OpenJDK / jdk / jdk
changeset 54592:4b4c8c11358f
Merge
author | psadhukhan |
---|---|
date | Mon, 22 Apr 2019 10:53:45 +0530 |
parents | dc6c5c53669b 3452d108d06d |
children | f0cec8e8d2ab 2ed7d59e725d |
files | src/jdk.accessibility/windows/native/common/AccessBridgeStatusWindow.RC src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Pool.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractPackageIndexWriter.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/external/jquery/jquery.js src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/images/ui-bg_glass_65_dadada_1x400.png src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/images/ui-bg_glass_75_dadada_1x400.png src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/images/ui-bg_glass_95_fef1ec_1x400.png src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/images/ui-icons_222222_256x240.png src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/images/ui-icons_2e83ff_256x240.png src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/images/ui-icons_454545_256x240.png src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/images/ui-icons_888888_256x240.png src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/images/ui-icons_cd0a0a_256x240.png src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-3.3.1.js src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-migrate-3.0.1.js src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.css src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.js src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.min.css src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.min.js src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.structure.css src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.structure.min.css src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jszip-utils/dist/jszip-utils-ie.js src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jszip-utils/dist/jszip-utils-ie.min.js src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jszip-utils/dist/jszip-utils.js src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jszip-utils/dist/jszip-utils.min.js src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jszip/dist/jszip.js src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jszip/dist/jszip.min.js test/hotspot/jtreg/runtime/ErrorHandling/ExplicitArithmeticCheck.java test/hotspot/jtreg/runtime/Thread/MonitorCacheMaybeExpand_DeadLock.java test/hotspot/jtreg/runtime/containers/cgroup/PlainRead.java test/hotspot/jtreg/runtime/containers/docker/AttemptOOM.java test/hotspot/jtreg/runtime/containers/docker/CheckContainerized.java test/hotspot/jtreg/runtime/containers/docker/DockerBasicTest.java test/hotspot/jtreg/runtime/containers/docker/HelloDocker.java test/hotspot/jtreg/runtime/containers/docker/JfrReporter.java test/hotspot/jtreg/runtime/containers/docker/PrintContainerInfo.java test/hotspot/jtreg/runtime/containers/docker/TEST.properties test/hotspot/jtreg/runtime/containers/docker/TestCPUAwareness.java test/hotspot/jtreg/runtime/containers/docker/TestCPUSets.java test/hotspot/jtreg/runtime/containers/docker/TestJFREvents.java test/hotspot/jtreg/runtime/containers/docker/TestMemoryAwareness.java test/hotspot/jtreg/runtime/containers/docker/TestMisc.java test/hotspot/jtreg/runtime/interpreter/WideStrictInline.java test/jdk/ProblemList.txt test/jdk/sun/security/tools/jarsigner/AlgOptions.sh test/jdk/sun/security/tools/jarsigner/PercentSign.sh test/jdk/sun/security/tools/jarsigner/certpolicy.sh test/jdk/sun/security/tools/jarsigner/checkusage.sh test/jdk/sun/security/tools/jarsigner/collator.sh test/jdk/sun/security/tools/jarsigner/concise_jarsigner.sh test/jdk/sun/security/tools/jarsigner/crl.sh test/jdk/sun/security/tools/jarsigner/default_options.sh test/jdk/sun/security/tools/jarsigner/diffend.sh test/jdk/sun/security/tools/jarsigner/ec.sh test/jdk/sun/security/tools/jarsigner/emptymanifest.sh test/jdk/sun/security/tools/jarsigner/jvindex.sh test/jdk/sun/security/tools/jarsigner/nameclash.sh test/jdk/sun/security/tools/jarsigner/newsize7.sh test/jdk/sun/security/tools/jarsigner/oldsig.sh test/jdk/sun/security/tools/jarsigner/onlymanifest.sh test/jdk/sun/security/tools/jarsigner/passtype.sh test/jdk/sun/security/tools/jarsigner/samename.sh test/jdk/sun/security/tools/jarsigner/weaksize.sh test/jdk/sun/security/tools/keytool/CloneKeyAskPassword.sh test/jdk/sun/security/tools/keytool/NoExtNPE.sh test/jdk/sun/security/tools/keytool/SecretKeyKS.sh test/jdk/sun/security/tools/keytool/StandardAlgName.sh test/jdk/sun/security/tools/keytool/StorePasswordsByShell.sh test/jdk/sun/security/tools/keytool/default_options.sh test/jdk/sun/security/tools/keytool/emptysubject.sh test/jdk/sun/security/tools/keytool/file-in-help.sh test/jdk/sun/security/tools/keytool/i18n.sh test/jdk/sun/security/tools/keytool/importreadall.sh test/jdk/sun/security/tools/keytool/keyalg.sh test/jdk/sun/security/tools/keytool/newhelp.sh test/jdk/sun/security/tools/keytool/resource.sh test/jdk/sun/security/tools/keytool/selfissued.sh test/jdk/sun/security/tools/keytool/trystore.sh |
diffstat | 380 files changed, 47401 insertions(+), 45253 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Apr 16 10:09:11 2019 +0530 +++ b/.hgtags Mon Apr 22 10:53:45 2019 +0530 @@ -554,3 +554,4 @@ 46cf212cdccaf4fb064d913b12004007d3322b67 jdk-13+14 f855ec13aa2501ae184c8b3e0626a8cec9966116 jdk-13+15 9d0ae9508d5337b0dc7cc4684be42888c4023755 jdk-13+16 +93b702d2a0cb9e32160208f6700aede1f8492773 jdk-13+17
--- a/doc/building.html Tue Apr 16 10:09:11 2019 +0530 +++ b/doc/building.html Mon Apr 22 10:53:45 2019 +0530 @@ -180,15 +180,15 @@ <tbody> <tr class="odd"> <td style="text-align: left;">Linux</td> -<td style="text-align: left;">Oracle Enterprise Linux 6.4 / 7.1 (using kernel 3.8.13)</td> +<td style="text-align: left;">Oracle Enterprise Linux 6.4 / 7.6</td> </tr> <tr class="even"> <td style="text-align: left;">Solaris</td> -<td style="text-align: left;">Solaris 11.1 SRU 21.4.1 / 11.2 SRU 5.5</td> +<td style="text-align: left;">Solaris 11.3</td> </tr> <tr class="odd"> <td style="text-align: left;">macOS</td> -<td style="text-align: left;">Mac OS X 10.9 (Mavericks) / 10.10 (Yosemite)</td> +<td style="text-align: left;">Mac OS X 10.13 (High Sierra)</td> </tr> <tr class="even"> <td style="text-align: left;">Windows</td> @@ -196,7 +196,7 @@ </tr> </tbody> </table> -<p>The double version numbers for Linux, Solaris and macOS is due to the hybrid model used at Oracle, where header files and external libraries from an older version are used when building on a more modern version of the OS.</p> +<p>The double version numbers for Linux and Solaris are due to the hybrid model used at Oracle, where header files and external libraries from an older version are used when building on a more modern version of the OS.</p> <p>The Build Group has a wiki page with <a href="https://wiki.openjdk.java.net/display/Build/Supported+Build+Platforms">Supported Build Platforms</a>. From time to time, this is updated by contributors to list successes or failures of building on different platforms.</p> <h3 id="windows">Windows</h3> <p>Windows XP is not a supported platform, but all newer Windows should be able to build the JDK.</p> @@ -281,19 +281,19 @@ <tbody> <tr class="odd"> <td style="text-align: left;">Linux</td> -<td style="text-align: left;">gcc 7.3.0</td> +<td style="text-align: left;">gcc 8.2.0</td> </tr> <tr class="even"> <td style="text-align: left;">macOS</td> -<td style="text-align: left;">Apple Xcode 9.4 (using clang 9.1.0)</td> +<td style="text-align: left;">Apple Xcode 10.1 (using clang 10.0.0)</td> </tr> <tr class="odd"> <td style="text-align: left;">Solaris</td> -<td style="text-align: left;">Oracle Solaris Studio 12.4 (with compiler version 5.13)</td> +<td style="text-align: left;">Oracle Solaris Studio 12.6 (with compiler version 5.15)</td> </tr> <tr class="even"> <td style="text-align: left;">Windows</td> -<td style="text-align: left;">Microsoft Visual Studio 2017 update 15.5.5</td> +<td style="text-align: left;">Microsoft Visual Studio 2017 update 15.9.6</td> </tr> </tbody> </table>
--- a/doc/building.md Tue Apr 16 10:09:11 2019 +0530 +++ b/doc/building.md Mon Apr 22 10:53:45 2019 +0530 @@ -150,14 +150,14 @@ Operating system Vendor/version used ----------------- ------------------------------------------------------- - Linux Oracle Enterprise Linux 6.4 / 7.1 (using kernel 3.8.13) - Solaris Solaris 11.1 SRU 21.4.1 / 11.2 SRU 5.5 - macOS Mac OS X 10.9 (Mavericks) / 10.10 (Yosemite) + Linux Oracle Enterprise Linux 6.4 / 7.6 + Solaris Solaris 11.3 SRU 20 + macOS Mac OS X 10.13 (High Sierra) Windows Windows Server 2012 R2 -The double version numbers for Linux, Solaris and macOS is due to the hybrid -model used at Oracle, where header files and external libraries from an older -version are used when building on a more modern version of the OS. +The double version numbers for Linux and Solaris are due to the hybrid model +used at Oracle, where header files and external libraries from an older version +are used when building on a more modern version of the OS. The Build Group has a wiki page with [Supported Build Platforms]( https://wiki.openjdk.java.net/display/Build/Supported+Build+Platforms). From @@ -323,10 +323,10 @@ Operating system Toolchain version ------------------ ------------------------------------------------------- - Linux gcc 7.3.0 - macOS Apple Xcode 9.4 (using clang 9.1.0) - Solaris Oracle Solaris Studio 12.4 (with compiler version 5.13) - Windows Microsoft Visual Studio 2017 update 15.5.5 + Linux gcc 8.2.0 + macOS Apple Xcode 10.1 (using clang 10.0.0) + Solaris Oracle Solaris Studio 12.6 (with compiler version 5.15) + Windows Microsoft Visual Studio 2017 update 15.9.6 ### gcc
--- a/doc/testing.html Tue Apr 16 10:09:11 2019 +0530 +++ b/doc/testing.html Mon Apr 22 10:53:45 2019 +0530 @@ -41,6 +41,7 @@ </ul></li> <li><a href="#notes-for-specific-tests">Notes for Specific Tests</a><ul> <li><a href="#docker-tests">Docker Tests</a></li> +<li><a href="#non-us-locale">Non-US locale</a></li> </ul></li> </ul> </nav> @@ -191,8 +192,12 @@ <h2 id="notes-for-specific-tests">Notes for Specific Tests</h2> <h3 id="docker-tests">Docker Tests</h3> <p>Docker tests with default parameters may fail on systems with glibc versions not compatible with the one used in the default docker image (e.g., Oracle Linux 7.6 for x86). For example, they pass on Ubuntu 16.04 but fail on Ubuntu 18.04 if run like this on x86:</p> -<pre><code>$ make test TEST="jtreg:test/hotspot/jtreg/runtime/containers/docker"</code></pre> +<pre><code>$ make test TEST="jtreg:test/hotspot/jtreg/containers/docker"</code></pre> <p>To run these tests correctly, additional parameters for the correct docker image are required on Ubuntu 18.04 by using <code>JAVA_OPTIONS</code>.</p> -<pre><code>$ make test TEST="jtreg:test/hotspot/jtreg/runtime/containers/docker" JTREG="JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu -Djdk.test.docker.image.version=latest"</code></pre> +<pre><code>$ make test TEST="jtreg:test/hotspot/jtreg/containers/docker" JTREG="JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu -Djdk.test.docker.image.version=latest"</code></pre> +<h3 id="non-us-locale">Non-US locale</h3> +<p>If your locale is non-US, some tests are likely to fail. To work around this you can set the locale to US. On Unix platforms simply setting <code>LANG="en_US"</code> in the environment before running tests should work. On Windows, setting <code>JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US"</code> helps for most, but not all test cases. For example:</p> +<pre><code>$ export LANG="en_US" && make test TEST=... +$ make test JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US" TEST=...</code></pre> </body> </html>
--- a/doc/testing.md Tue Apr 16 10:09:11 2019 +0530 +++ b/doc/testing.md Mon Apr 22 10:53:45 2019 +0530 @@ -381,12 +381,23 @@ compatible with the one used in the default docker image (e.g., Oracle Linux 7.6 for x86). For example, they pass on Ubuntu 16.04 but fail on Ubuntu 18.04 if run like this on x86: - $ make test TEST="jtreg:test/hotspot/jtreg/runtime/containers/docker" + $ make test TEST="jtreg:test/hotspot/jtreg/containers/docker" To run these tests correctly, additional parameters for the correct docker image are required on Ubuntu 18.04 by using `JAVA_OPTIONS`. - $ make test TEST="jtreg:test/hotspot/jtreg/runtime/containers/docker" JTREG="JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu -Djdk.test.docker.image.version=latest" + $ make test TEST="jtreg:test/hotspot/jtreg/containers/docker" JTREG="JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu -Djdk.test.docker.image.version=latest" + +### Non-US locale + +If your locale is non-US, some tests are likely to fail. To work around this you can +set the locale to US. On Unix platforms simply setting `LANG="en_US"` in the +environment before running tests should work. On Windows, setting +`JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US"` helps for most, but not all test cases. +For example: + + $ export LANG="en_US" && make test TEST=... + $ make test JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US" TEST=... --- # Override some definitions in the global css file that are not optimal for
--- a/make/Coverage.gmk Tue Apr 16 10:09:11 2019 +0530 +++ b/make/Coverage.gmk Mon Apr 22 10:53:45 2019 +0530 @@ -49,6 +49,7 @@ -exclude 'java.lang.Object' \ -exclude 'jdk.internal.org.objectweb.**' \ -exclude jdk.test.Main -exclude '**\$Proxy*' \ + $(JCOV_FILTERS) \ $(JCOV_TEMP)/$(JCOV_IMAGE_SUBDIR) $(MV) $(JCOV_TEMP)/$(JCOV_IMAGE_SUBDIR) $(JCOV_IMAGE_DIR) $(RMDIR) $(JCOV_TEMP)
--- a/make/RunTests.gmk Tue Apr 16 10:09:11 2019 +0530 +++ b/make/RunTests.gmk Mon Apr 22 10:53:45 2019 +0530 @@ -1194,10 +1194,18 @@ $(call LogWarn, Stopping JCov Grabber...) $(JAVA) -jar $(JCOV_HOME)/lib/jcov.jar GrabberManager -stop -stoptimeout 3600 + JCOV_REPORT_TITLE := JDK code coverage report<br/> + ifneq ($(JCOV_FILTERS), ) + JCOV_REPORT_TITLE += Code filters: $(JCOV_FILTERS)<br> + endif + JCOV_REPORT_TITLE += Tests: $(TEST) + jcov-gen-report: jcov-stop-grabber $(call LogWarn, Generating JCov report ...) $(JAVA) -Xmx4g -jar $(JCOV_HOME)/lib/jcov.jar RepGen -sourcepath \ `$(ECHO) $(TOPDIR)/src/*/share/classes/ | $(TR) ' ' ':'` -fmt html \ + $(JCOV_FILTERS) \ + -mainReportTitle "$(JCOV_REPORT_TITLE)" \ -o $(JCOV_REPORT) $(JCOV_RESULT_FILE) TARGETS += jcov-do-start-grabber jcov-start-grabber jcov-stop-grabber \
--- a/make/autoconf/flags-other.m4 Tue Apr 16 10:09:11 2019 +0530 +++ b/make/autoconf/flags-other.m4 Mon Apr 22 10:53:45 2019 +0530 @@ -81,21 +81,21 @@ RC_FLAGS="$RC_FLAGS \ -D\"JDK_VERSION_STRING=\$(VERSION_STRING)\" \ -D\"JDK_COMPANY=\$(COMPANY_NAME)\" \ - -D\"JDK_COMPONENT=\$(JDK_RC_NAME) binary\" \ + -D\"JDK_FILEDESC=\$(JDK_RC_NAME) binary\" \ -D\"JDK_VER=\$(VERSION_NUMBER)\" \ -D\"JDK_COPYRIGHT=Copyright \xA9 $COPYRIGHT_YEAR\" \ -D\"JDK_NAME=\$(JDK_RC_NAME) \$(VERSION_FEATURE)\" \ -D\"JDK_FVER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\"" JVM_RCFLAGS="$JVM_RCFLAGS \ - -D\"HS_BUILD_ID=\$(VERSION_STRING)\" \ + -D\"HS_VERSION_STRING=\$(VERSION_STRING)\" \ -D\"HS_COMPANY=\$(COMPANY_NAME)\" \ - -D\"JDK_DOTVER=\$(VERSION_NUMBER_FOUR_POSITIONS)\" \ + -D\"HS_VER=\$(VERSION_NUMBER_FOUR_POSITIONS)\" \ + -D\"HS_INTERNAL_NAME=jvm\" \ -D\"HS_COPYRIGHT=Copyright $COPYRIGHT_YEAR\" \ + -D\"HS_FNAME=jvm.dll\" \ -D\"HS_NAME=\$(PRODUCT_NAME) \$(VERSION_SHORT)\" \ - -D\"JDK_VER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\" \ - -D\"HS_FNAME=jvm.dll\" \ - -D\"HS_INTERNAL_NAME=jvm\"" + -D\"HS_FVER=\$(subst .,\$(COMMA),\$(VERSION_NUMBER_FOUR_POSITIONS))\"" fi AC_SUBST(RC_FLAGS) AC_SUBST(JVM_RCFLAGS)
--- a/make/autoconf/jdk-options.m4 Tue Apr 16 10:09:11 2019 +0530 +++ b/make/autoconf/jdk-options.m4 Mon Apr 22 10:53:45 2019 +0530 @@ -404,9 +404,12 @@ [jcov library location])]) AC_ARG_WITH(jcov-input-jdk, [AS_HELP_STRING([--with-jcov-input-jdk], [jdk image to instrument])]) + AC_ARG_WITH(jcov-filters, [AS_HELP_STRING([--with-jcov-filters], + [filters to limit code for jcov instrumentation and report generation])]) JCOV_HOME= JCOV_INPUT_JDK= JCOV_ENABLED= + JCOV_FILTERS= if test "x$with_jcov" = "x" ; then JCOV_ENABLED="false" else @@ -425,10 +428,14 @@ fi BASIC_FIXUP_PATH(JCOV_INPUT_JDK) fi + if test "x$with_jcov_filters" != "x" ; then + JCOV_FILTERS="$with_jcov_filters" + fi fi AC_SUBST(JCOV_ENABLED) AC_SUBST(JCOV_HOME) AC_SUBST(JCOV_INPUT_JDK) + AC_SUBST(JCOV_FILTERS) ]) ###############################################################################
--- a/make/autoconf/jdk-version.m4 Tue Apr 16 10:09:11 2019 +0530 +++ b/make/autoconf/jdk-version.m4 Mon Apr 22 10:53:45 2019 +0530 @@ -66,7 +66,33 @@ AC_SUBST(PRODUCT_SUFFIX) AC_SUBST(JDK_RC_PLATFORM_NAME) AC_SUBST(HOTSPOT_VM_DISTRO) + + # Set the MACOSX Bundle Name base + AC_ARG_WITH(macosx-bundle-name-base, [AS_HELP_STRING([--with-macosx-bundle-name-base], + [Set the MacOSX Bundle Name base. This is the base name for calculating MacOSX Bundle Names. + @<:@not specified@:>@])]) + if test "x$with_macosx_bundle_name_base" = xyes; then + AC_MSG_ERROR([--with-macosx-bundle-name-base must have a value]) + elif [ ! [[ $with_macosx_bundle_name_base =~ ^[[:print:]]*$ ]] ]; then + AC_MSG_ERROR([--with-macosx-bundle-name-base contains non-printing characters: $with_macosx_bundle_name_base]) + elif test "x$with_macosx_bundle_name_base" != x; then + # Set MACOSX_BUNDLE_NAME_BASE to the configured value. + MACOSX_BUNDLE_NAME_BASE="$with_macosx_bundle_name_base" + fi AC_SUBST(MACOSX_BUNDLE_NAME_BASE) + + # Set the MACOSX Bundle ID base + AC_ARG_WITH(macosx-bundle-id-base, [AS_HELP_STRING([--with-macosx-bundle-id-base], + [Set the MacOSX Bundle ID base. This is the base ID for calculating MacOSX Bundle IDs. + @<:@not specified@:>@])]) + if test "x$with_macosx_bundle_id_base" = xyes; then + AC_MSG_ERROR([--with-macosx-bundle-id-base must have a value]) + elif [ ! [[ $with_macosx_bundle_id_base =~ ^[[:print:]]*$ ]] ]; then + AC_MSG_ERROR([--with-macosx-bundle-id-base contains non-printing characters: $with_macosx_bundle_id_base]) + elif test "x$with_macosx_bundle_id_base" != x; then + # Set MACOSX_BUNDLE_ID_BASE to the configured value. + MACOSX_BUNDLE_ID_BASE="$with_macosx_bundle_id_base" + fi AC_SUBST(MACOSX_BUNDLE_ID_BASE) # Set the JDK RC name
--- a/make/autoconf/libraries.m4 Tue Apr 16 10:09:11 2019 +0530 +++ b/make/autoconf/libraries.m4 Mon Apr 22 10:53:45 2019 +0530 @@ -130,6 +130,11 @@ BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lthread" fi + # perfstat lib + if test "x$OPENJDK_TARGET_OS" = xaix; then + BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lperfstat" + fi + if test "x$OPENJDK_TARGET_OS" = xsolaris; then BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lsocket -lsched -ldoor -ldemangle -lnsl \ -lrt -lkstat"
--- a/make/autoconf/spec.gmk.in Tue Apr 16 10:09:11 2019 +0530 +++ b/make/autoconf/spec.gmk.in Mon Apr 22 10:53:45 2019 +0530 @@ -389,6 +389,7 @@ JCOV_ENABLED=@JCOV_ENABLED@ JCOV_HOME=@JCOV_HOME@ JCOV_INPUT_JDK=@JCOV_INPUT_JDK@ +JCOV_FILTERS=@JCOV_FILTERS@ # AddressSanitizer export ASAN_ENABLED:=@ASAN_ENABLED@
--- a/make/jdk/src/classes/build/tools/classlist/HelloClasslist.java Tue Apr 16 10:09:11 2019 +0530 +++ b/make/jdk/src/classes/build/tools/classlist/HelloClasslist.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -67,13 +67,24 @@ .forEach(System.out::println); // Common concatenation patterns - String const_I = "string" + args.length; - String const_S = "string" + String.valueOf(args.length); - String S_const = String.valueOf(args.length) + "string"; - String S_S = String.valueOf(args.length) + String.valueOf(args.length); - String const_J = "string" + System.currentTimeMillis(); - String I_const = args.length + "string"; - String J_const = System.currentTimeMillis() + "string"; + String SS = String.valueOf(args.length) + String.valueOf(args.length); + String CS = "string" + String.valueOf(args.length); + String SC = String.valueOf(args.length) + "string"; + String SCS = String.valueOf(args.length) + "string" + String.valueOf(args.length); + String CSS = "string" + String.valueOf(args.length) + String.valueOf(args.length); + String CSCS = "string" + String.valueOf(args.length) + "string" + String.valueOf(args.length); + String SCSC = String.valueOf(args.length) + "string" + String.valueOf(args.length) + "string"; + String CSCSC = "string" + String.valueOf(args.length) + "string" + String.valueOf(args.length) + "string"; + String SCSCS = String.valueOf(args.length) + "string" + String.valueOf(args.length) + "string" + String.valueOf(args.length); + String CI = "string" + args.length; + String IC = args.length + "string"; + String CIC = "string" + args.length + "string"; + String CICI = "string" + args.length + "string" + args.length; + String CJ = "string" + System.currentTimeMillis(); + String JC = System.currentTimeMillis() + "string"; + String CJC = "string" + System.currentTimeMillis() + "string"; + String CJCJ = "string" + System.currentTimeMillis() + "string" + System.currentTimeMillis(); + String CJCJC = "string" + System.currentTimeMillis() + "string" + System.currentTimeMillis() + "string"; String newDate = DateTimeFormatter.ISO_LOCAL_DATE_TIME.format( LocalDateTime.now(ZoneId.of("GMT")));
--- a/make/launcher/Launcher-java.base.gmk Tue Apr 16 10:09:11 2019 +0530 +++ b/make/launcher/Launcher-java.base.gmk Mon Apr 22 10:53:45 2019 +0530 @@ -39,7 +39,6 @@ # overwritten. $(eval $(call SetupBuildLauncher, java, \ CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS -DENABLE_ARG_FILES, \ - LDFLAGS_solaris := -R$(OPENWIN_HOME)/lib$(OPENJDK_TARGET_CPU_ISADIR), \ EXTRA_RC_FLAGS := $(JAVA_RC_FLAGS), \ VERSION_INFO_RESOURCE := $(JAVA_VERSION_INFO_RESOURCE), \ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/java_objs, \
--- a/make/launcher/Launcher-jdk.accessibility.gmk Tue Apr 16 10:09:11 2019 +0530 +++ b/make/launcher/Launcher-jdk.accessibility.gmk Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. +# 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 @@ -43,7 +43,7 @@ DISABLED_WARNINGS_microsoft := 4267 4996, \ LDFLAGS := $(LDFLAGS_JDKEXE), \ LIBS := advapi32.lib version.lib user32.lib, \ - VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRC)/AccessBridgeStatusWindow.RC, \ + VERSIONINFO_RESOURCE := $(ACCESSBRIDGE_SRC)/AccessBridgeStatusWindow.rc, \ MANIFEST := $(JABSWITCH_SRC)/jabswitch.manifest, \ MANIFEST_VERSION := $(VERSION_NUMBER_FOUR_POSITIONS), \ ))
--- a/make/launcher/LauncherCommon.gmk Tue Apr 16 10:09:11 2019 +0530 +++ b/make/launcher/LauncherCommon.gmk Mon Apr 22 10:53:45 2019 +0530 @@ -73,8 +73,7 @@ # compile time defines exceeding Visual Studio 2013 limitations. # CFLAGS Additional CFLAGS # CFLAGS_windows Additional CFLAGS_windows -# LDFLAGS_solaris Additional LDFLAGS_solaris -# RC_FLAGS Additional RC_FLAGS +# EXTRA_RC_FLAGS Additional EXTRA_RC_FLAGS # MACOSX_SIGNED On macosx, sign this binary # OPTIMIZATION Override default optimization level (LOW) # OUTPUT_DIR Override default output directory @@ -139,7 +138,7 @@ NAME := $1, \ EXTRA_FILES := $(LAUNCHER_SRC)/main.c, \ OPTIMIZATION := $$($1_OPTIMIZATION), \ - CFLAGS := $$(CFLAGS_JDKEXE) $$($1_CFLAGS) \ + CFLAGS := $$(CFLAGS_JDKEXE) \ $(LAUNCHER_CFLAGS) \ $(VERSION_CFLAGS) \ -DLAUNCHER_NAME='"$(LAUNCHER_NAME)"' \
--- a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -418,7 +418,7 @@ }; -IRT_ENTRY(address, +JRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread, Method* method, intptr_t* from, @@ -435,4 +435,4 @@ // return result handler return Interpreter::result_handler(m->result_type()); -IRT_END +JRT_END
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -67,7 +67,11 @@ return false; } + // The CPU implementer codes can be found in + // ARM Architecture Reference Manual ARMv8, for ARMv8-A architecture profile + // https://developer.arm.com/docs/ddi0487/latest enum Family { + CPU_AMPERE = 0xC0, CPU_ARM = 'A', CPU_BROADCOM = 'B', CPU_CAVIUM = 'C',
--- a/src/hotspot/cpu/arm/interpreterRT_arm.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/arm/interpreterRT_arm.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -369,9 +369,9 @@ } }; -IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread, Method* method, intptr_t* from, intptr_t* to)) +JRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread, Method* method, intptr_t* from, intptr_t* to)) methodHandle m(thread, (Method*)method); assert(m->is_native(), "sanity check"); SlowSignatureHandler(m, (address)from, to).iterate(UCONST64(-1)); return Interpreter::result_handler(m->result_type()); -IRT_END +JRT_END
--- a/src/hotspot/cpu/ppc/interpreterRT_ppc.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/ppc/interpreterRT_ppc.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2013 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -148,15 +148,15 @@ // Access function to get the signature. -IRT_ENTRY(address, InterpreterRuntime::get_signature(JavaThread* thread, Method* method)) +JRT_ENTRY(address, InterpreterRuntime::get_signature(JavaThread* thread, Method* method)) methodHandle m(thread, method); assert(m->is_native(), "sanity check"); Symbol *s = m->signature(); return (address) s->base(); -IRT_END +JRT_END -IRT_ENTRY(address, InterpreterRuntime::get_result_handler(JavaThread* thread, Method* method)) +JRT_ENTRY(address, InterpreterRuntime::get_result_handler(JavaThread* thread, Method* method)) methodHandle m(thread, method); assert(m->is_native(), "sanity check"); return AbstractInterpreter::result_handler(m->result_type()); -IRT_END +JRT_END
--- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -38,6 +38,9 @@ #include "vm_version_ppc.hpp" #include <sys/sysinfo.h> +#if defined(_AIX) +#include <libperfstat.h> +#endif #if defined(LINUX) && defined(VM_LITTLE_ENDIAN) #include <sys/auxv.h> @@ -382,6 +385,58 @@ } void VM_Version::print_platform_virtualization_info(outputStream* st) { +#if defined(_AIX) + // more info about perfstat API see + // https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.prftools/idprftools_perfstat_glob_partition.htm + int rc = 0; + perfstat_partition_total_t pinfo; + memset(&pinfo, 0, sizeof(perfstat_partition_total_t)); + rc = perfstat_partition_total(NULL, &pinfo, sizeof(perfstat_partition_total_t), 1); + if (rc != 1) { + return; + } else { + st->print_cr("Virtualization type : PowerVM"); + } + // CPU information + perfstat_cpu_total_t cpuinfo; + memset(&cpuinfo, 0, sizeof(perfstat_cpu_total_t)); + rc = perfstat_cpu_total(NULL, &cpuinfo, sizeof(perfstat_cpu_total_t), 1); + if (rc != 1) { + return; + } + + st->print_cr("Processor description : %s", cpuinfo.description); + st->print_cr("Processor speed : %llu Hz", cpuinfo.processorHZ); + + st->print_cr("LPAR partition name : %s", pinfo.name); + st->print_cr("LPAR partition number : %u", pinfo.lpar_id); + st->print_cr("LPAR partition type : %s", pinfo.type.b.shared_enabled ? "shared" : "dedicated"); + st->print_cr("LPAR mode : %s", pinfo.type.b.donate_enabled ? "donating" : pinfo.type.b.capped ? "capped" : "uncapped"); + st->print_cr("LPAR partition group ID : %u", pinfo.group_id); + st->print_cr("LPAR shared pool ID : %u", pinfo.pool_id); + + st->print_cr("AMS (active memory sharing) : %s", pinfo.type.b.ams_capable ? "capable" : "not capable"); + st->print_cr("AMS (active memory sharing) : %s", pinfo.type.b.ams_enabled ? "on" : "off"); + st->print_cr("AME (active memory expansion) : %s", pinfo.type.b.ame_enabled ? "on" : "off"); + + if (pinfo.type.b.ame_enabled) { + st->print_cr("AME true memory in bytes : %llu", pinfo.true_memory); + st->print_cr("AME expanded memory in bytes : %llu", pinfo.expanded_memory); + } + + st->print_cr("SMT : %s", pinfo.type.b.smt_capable ? "capable" : "not capable"); + st->print_cr("SMT : %s", pinfo.type.b.smt_enabled ? "on" : "off"); + int ocpus = pinfo.online_cpus > 0 ? pinfo.online_cpus : 1; + st->print_cr("LPAR threads : %d", cpuinfo.ncpus/ocpus); + st->print_cr("LPAR online virtual cpus : %d", pinfo.online_cpus); + st->print_cr("LPAR logical cpus : %d", cpuinfo.ncpus); + st->print_cr("LPAR maximum virtual cpus : %u", pinfo.max_cpus); + st->print_cr("LPAR minimum virtual cpus : %u", pinfo.min_cpus); + st->print_cr("LPAR entitled capacity : %4.2f", (double) (pinfo.entitled_proc_capacity/100.0)); + st->print_cr("LPAR online memory : %llu MB", pinfo.online_memory); + st->print_cr("LPAR maximum memory : %llu MB", pinfo.max_memory); + st->print_cr("LPAR minimum memory : %llu MB", pinfo.min_memory); +#else const char* info_file = "/proc/ppc64/lparcfg"; const char* kw[] = { "system_type=", // qemu indicates PowerKVM "partition_entitled_capacity=", // entitled processor capacity percentage @@ -400,6 +455,7 @@ if (!print_matching_lines_from_file(info_file, st, kw)) { st->print_cr(" <%s Not Available>", info_file); } +#endif } bool VM_Version::use_biased_locking() {
--- a/src/hotspot/cpu/s390/interpreterRT_s390.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/s390/interpreterRT_s390.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -151,15 +151,15 @@ void SignatureHandlerLibrary::pd_set_handler(address handler) {} -IRT_ENTRY(address, InterpreterRuntime::get_signature(JavaThread* thread, Method* method)) +JRT_ENTRY(address, InterpreterRuntime::get_signature(JavaThread* thread, Method* method)) methodHandle m(thread, method); assert(m->is_native(), "sanity check"); Symbol *s = m->signature(); return (address) s->base(); -IRT_END +JRT_END -IRT_ENTRY(address, InterpreterRuntime::get_result_handler(JavaThread* thread, Method* method)) +JRT_ENTRY(address, InterpreterRuntime::get_result_handler(JavaThread* thread, Method* method)) methodHandle m(thread, method); assert(m->is_native(), "sanity check"); return AbstractInterpreter::result_handler(m->result_type()); -IRT_END +JRT_END
--- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -4355,12 +4355,9 @@ // Emitter does not KILL cnt and base arguments, since they need to be copied to // work registers anyway. // Actually, only r0, r1, and r5 are killed. -unsigned int MacroAssembler::Clear_Array(Register cnt_arg, Register base_pointer_arg, Register src_addr, Register src_len) { - // Src_addr is evenReg. - // Src_len is odd_Reg. +unsigned int MacroAssembler::Clear_Array(Register cnt_arg, Register base_pointer_arg, Register odd_tmp_reg) { int block_start = offset(); - Register tmp_reg = src_len; // Holds target instr addr for EX. Register dst_len = Z_R1; // Holds dst len for MVCLE. Register dst_addr = Z_R0; // Holds dst addr for MVCLE. @@ -4369,7 +4366,7 @@ BLOCK_COMMENT("Clear_Array {"); // Check for zero len and convert to long. - z_ltgfr(src_len, cnt_arg); // Remember casted value for doSTG case. + z_ltgfr(odd_tmp_reg, cnt_arg); z_bre(done); // Nothing to do if len == 0. // Prefetch data to be cleared. @@ -4378,16 +4375,17 @@ z_pfd(0x02, 256, Z_R0, base_pointer_arg); } - z_sllg(dst_len, src_len, 3); // #bytes to clear. - z_cghi(src_len, 32); // Check for len <= 256 bytes (<=32 DW). - z_brnh(doXC); // If so, use executed XC to clear. + z_sllg(dst_len, odd_tmp_reg, 3); // #bytes to clear. + z_cghi(odd_tmp_reg, 32); // Check for len <= 256 bytes (<=32 DW). + z_brnh(doXC); // If so, use executed XC to clear. // MVCLE: initialize long arrays (general case). bind(doMVCLE); z_lgr(dst_addr, base_pointer_arg); - clear_reg(src_len, true, false); // Src len of MVCLE is zero. - - MacroAssembler::move_long_ext(dst_addr, src_addr, 0); + // Pass 0 as source length to MVCLE: destination will be filled with padding byte 0. + // The even register of the register pair is not killed. + clear_reg(odd_tmp_reg, true, false); + MacroAssembler::move_long_ext(dst_addr, as_Register(odd_tmp_reg->encoding()-1), 0); z_bru(done); // XC: initialize short arrays. @@ -4396,12 +4394,12 @@ z_xc(0,0,base_pointer_arg,0,base_pointer_arg); bind(doXC); - add2reg(dst_len, -1); // Get #bytes-1 for EXECUTE. + add2reg(dst_len, -1); // Get #bytes-1 for EXECUTE. if (VM_Version::has_ExecuteExtensions()) { - z_exrl(dst_len, XC_template); // Execute XC with var. len. + z_exrl(dst_len, XC_template); // Execute XC with var. len. } else { - z_larl(tmp_reg, XC_template); - z_ex(dst_len,0,Z_R0,tmp_reg); // Execute XC with var. len. + z_larl(odd_tmp_reg, XC_template); + z_ex(dst_len,0,Z_R0,odd_tmp_reg); // Execute XC with var. len. } // z_bru(done); // fallthru @@ -4463,7 +4461,7 @@ // Compiler ensures base is doubleword aligned and cnt is #doublewords. // Emitter does not KILL cnt and base arguments, since they need to be copied to // work registers anyway. -// Actually, only r0, r1, r4, and r5 (which are work registers) are killed. +// Actually, only r0, r1, (which are work registers) and odd_tmp_reg are killed. // // For very large arrays, exploit MVCLE H/W support. // MVCLE instruction automatically exploits H/W-optimized page mover. @@ -4471,9 +4469,7 @@ // - All full pages are cleared with the page mover H/W assist. // - Remaining bytes are again cleared by a series of XC to self. // -unsigned int MacroAssembler::Clear_Array_Const_Big(long cnt, Register base_pointer_arg, Register src_addr, Register src_len) { - // Src_addr is evenReg. - // Src_len is odd_Reg. +unsigned int MacroAssembler::Clear_Array_Const_Big(long cnt, Register base_pointer_arg, Register odd_tmp_reg) { int block_start = offset(); Register dst_len = Z_R1; // Holds dst len for MVCLE. @@ -4486,11 +4482,10 @@ // Prepare other args to MVCLE. z_lgr(dst_addr, base_pointer_arg); - // Indicate unused result. - (void) clear_reg(src_len, true, false); // Src len of MVCLE is zero. - - // Clear. - MacroAssembler::move_long_ext(dst_addr, src_addr, 0); + // Pass 0 as source length to MVCLE: destination will be filled with padding byte 0. + // The even register of the register pair is not killed. + (void) clear_reg(odd_tmp_reg, true, false); // Src len of MVCLE is zero. + MacroAssembler::move_long_ext(dst_addr, as_Register(odd_tmp_reg->encoding() - 1), 0); BLOCK_COMMENT("} Clear_Array_Const_Big"); int block_end = offset();
--- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -828,9 +828,9 @@ //-------------------------- //--- Operations on arrays. //-------------------------- - unsigned int Clear_Array(Register cnt_arg, Register base_pointer_arg, Register src_addr, Register src_len); + unsigned int Clear_Array(Register cnt_arg, Register base_pointer_arg, Register odd_tmp_reg); unsigned int Clear_Array_Const(long cnt, Register base); - unsigned int Clear_Array_Const_Big(long cnt, Register base_pointer_arg, Register src_addr, Register src_len); + unsigned int Clear_Array_Const_Big(long cnt, Register base_pointer_arg, Register odd_tmp_reg); unsigned int CopyRawMemory_AlignedDisjoint(Register src_reg, Register dst_reg, Register cnt_reg, Register tmp1_reg, Register tmp2_reg);
--- a/src/hotspot/cpu/s390/s390.ad Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/s390/s390.ad Mon Apr 22 10:53:45 2019 +0530 @@ -474,6 +474,19 @@ /*Z_R15_H,Z_R15*/ // SP ); +// z_long_reg without even registers +reg_class z_long_odd_reg( +/*Z_R0_H,Z_R0*/ // R0 +/*Z_R1_H,Z_R1*/ + Z_R3_H,Z_R3, + Z_R5_H,Z_R5, + Z_R7_H,Z_R7, + Z_R9_H,Z_R9, + Z_R11_H,Z_R11, + Z_R13_H,Z_R13 +/*Z_R14_H,Z_R14,*/ // return_pc +/*Z_R15_H,Z_R15*/ // SP +); // Special Class for Condition Code Flags Register @@ -3378,6 +3391,7 @@ match(RegL); match(revenRegL); match(roddRegL); + match(allRoddRegL); match(rarg1RegL); match(rarg5RegL); format %{ %} @@ -3400,6 +3414,14 @@ interface(REG_INTER); %} +// available odd registers for iRegL +operand allRoddRegL() %{ + constraint(ALLOC_IN_RC(z_long_odd_reg)); + match(iRegL); + format %{ %} + interface(REG_INTER); +%} + operand rarg1RegL() %{ constraint(ALLOC_IN_RC(z_rarg1_long_reg)); match(iRegL); @@ -9899,23 +9921,23 @@ ins_pipe(pipe_class_dummy); %} -instruct inlineCallClearArrayConstBig(immL cnt, iRegP_N2P base, Universe dummy, revenRegL srcA, roddRegL srcL, flagsReg cr) %{ +instruct inlineCallClearArrayConstBig(immL cnt, iRegP_N2P base, Universe dummy, allRoddRegL tmpL, flagsReg cr) %{ match(Set dummy (ClearArray cnt base)); - effect(TEMP srcA, TEMP srcL, KILL cr); // R0, R1 are killed, too. + effect(TEMP tmpL, KILL cr); // R0, R1 are killed, too. ins_cost(200); // TODO: s390 port size(VARIABLE_SIZE); // Variable in size due to optimized constant loader. format %{ "ClearArrayConstBig $cnt,$base" %} - ins_encode %{ __ Clear_Array_Const_Big($cnt$$constant, $base$$Register, $srcA$$Register, $srcL$$Register); %} - ins_pipe(pipe_class_dummy); -%} - -instruct inlineCallClearArray(iRegL cnt, iRegP_N2P base, Universe dummy, revenRegL srcA, roddRegL srcL, flagsReg cr) %{ + ins_encode %{ __ Clear_Array_Const_Big($cnt$$constant, $base$$Register, $tmpL$$Register); %} + ins_pipe(pipe_class_dummy); +%} + +instruct inlineCallClearArray(iRegL cnt, iRegP_N2P base, Universe dummy, allRoddRegL tmpL, flagsReg cr) %{ match(Set dummy (ClearArray cnt base)); - effect(TEMP srcA, TEMP srcL, KILL cr); // R0, R1 are killed, too. + effect(TEMP tmpL, KILL cr); // R0, R1 are killed, too. ins_cost(300); // TODO: s390 port size(FIXED_SIZE); // z/Architecture: emitted code depends on PreferLAoverADD being on/off. format %{ "ClearArrayVar $cnt,$base" %} - ins_encode %{ __ Clear_Array($cnt$$Register, $base$$Register, $srcA$$Register, $srcL$$Register); %} + ins_encode %{ __ Clear_Array($cnt$$Register, $base$$Register, $tmpL$$Register); %} ins_pipe(pipe_class_dummy); %}
--- a/src/hotspot/cpu/sparc/interpreterRT_sparc.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/sparc/interpreterRT_sparc.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -191,7 +191,7 @@ }; -IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler( +JRT_ENTRY(address, InterpreterRuntime::slow_signature_handler( JavaThread* thread, Method* method, intptr_t* from, @@ -204,4 +204,4 @@ SlowSignatureHandler(m, (address)from, m->is_static() ? to+2 : to+1, to).iterate((uint64_t)CONST64(-1)); // return result handler return Interpreter::result_handler(m->result_type()); -IRT_END +JRT_END
--- a/src/hotspot/cpu/x86/assembler_x86.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/x86/assembler_x86.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -3099,7 +3099,7 @@ } return; } - if (UseAddressNop && VM_Version::is_amd()) { + if (UseAddressNop && VM_Version::is_amd_family()) { // // Using multi-bytes nops "0x0F 0x1F [address]" for AMD. // 1: 0x90
--- a/src/hotspot/cpu/x86/interpreterRT_x86_32.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/x86/interpreterRT_x86_32.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -147,11 +147,11 @@ } }; -IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread, Method* method, intptr_t* from, intptr_t* to)) +JRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread, Method* method, intptr_t* from, intptr_t* to)) methodHandle m(thread, (Method*)method); assert(m->is_native(), "sanity check"); // handle arguments SlowSignatureHandler(m, (address)from, to + 1).iterate((uint64_t)CONST64(-1)); // return result handler return Interpreter::result_handler(m->result_type()); -IRT_END +JRT_END
--- a/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -496,7 +496,7 @@ #endif -IRT_ENTRY(address, +JRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread, Method* method, intptr_t* from, @@ -509,4 +509,4 @@ // return result handler return Interpreter::result_handler(m->result_type()); -IRT_END +JRT_END
--- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -2968,9 +2968,8 @@ __ enter(); __ subptr(rsp, 8 * wordSize); - if (multi_block) { - __ push(limit); - } + handleSOERegisters(true /*saving*/); + __ movptr(buf, buf_param); __ movptr(state, state_param); if (multi_block) { @@ -2981,9 +2980,7 @@ __ fast_sha1(abcd, e0, e1, msg0, msg1, msg2, msg3, shuf_mask, buf, state, ofs, limit, rsp, multi_block); - if (multi_block) { - __ pop(limit); - } + handleSOERegisters(false /*restoring*/); __ addptr(rsp, 8 * wordSize); __ leave(); __ ret(0);
--- a/src/hotspot/cpu/x86/vm_version_ext_x86.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/x86/vm_version_ext_x86.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -43,10 +43,10 @@ CPU_FAMILY_PENTIUM_4 = 0xF } FamilyFlag; - typedef enum { - RDTSCP_FLAG = 0x08000000, // bit 27 - INTEL64_FLAG = 0x20000000 // bit 29 - } _featureExtendedEdxFlag; +typedef enum { + RDTSCP_FLAG = 0x08000000, // bit 27 + INTEL64_FLAG = 0x20000000 // bit 29 +} _featureExtendedEdxFlag; #define CPUID_STANDARD_FN 0x0 #define CPUID_STANDARD_FN_1 0x1 @@ -340,6 +340,10 @@ return !is_amd_Barcelona(); } + if (is_hygon()) { + return true; + } + return false; } @@ -399,13 +403,20 @@ const char* VM_Version_Ext::cpu_family_description(void) { int cpu_family_id = extended_cpu_family(); if (is_amd()) { - return _family_id_amd[cpu_family_id]; + if (cpu_family_id < ExtendedFamilyIdLength_AMD) { + return _family_id_amd[cpu_family_id]; + } } if (is_intel()) { if (cpu_family_id == CPU_FAMILY_PENTIUMPRO) { return cpu_model_description(); } - return _family_id_intel[cpu_family_id]; + if (cpu_family_id < ExtendedFamilyIdLength_INTEL) { + return _family_id_intel[cpu_family_id]; + } + } + if (is_hygon()) { + return "Dhyana"; } return "Unknown x86"; } @@ -423,6 +434,9 @@ } else if (is_amd()) { cpu_type = "AMD"; x64 = cpu_is_em64t() ? " AMD64" : ""; + } else if (is_hygon()) { + cpu_type = "Hygon"; + x64 = cpu_is_em64t() ? " AMD64" : ""; } else { cpu_type = "Unknown x86"; x64 = cpu_is_em64t() ? " x86_64" : ""; @@ -694,7 +708,7 @@ return _max_qualified_cpu_frequency; } -const char* const VM_Version_Ext::_family_id_intel[] = { +const char* const VM_Version_Ext::_family_id_intel[ExtendedFamilyIdLength_INTEL] = { "8086/8088", "", "286", @@ -713,7 +727,7 @@ "Pentium 4" }; -const char* const VM_Version_Ext::_family_id_amd[] = { +const char* const VM_Version_Ext::_family_id_amd[ExtendedFamilyIdLength_AMD] = { "", "", "", @@ -731,6 +745,13 @@ "", "Opteron/Athlon64", "Opteron QC/Phenom" // Barcelona et.al. + "", + "", + "", + "", + "", + "", + "Zen" }; // Partially from Intel 64 and IA-32 Architecture Software Developer's Manual, // September 2013, Vol 3C Table 35-1
--- a/src/hotspot/cpu/x86/vm_version_ext_x86.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/x86/vm_version_ext_x86.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -29,14 +29,20 @@ #include "vm_version_x86.hpp" class VM_Version_Ext : public VM_Version { + + enum { + ExtendedFamilyIdLength_INTEL = 16, + ExtendedFamilyIdLength_AMD = 24 + }; + private: static const size_t VENDOR_LENGTH; static const size_t CPU_EBS_MAX_LENGTH; static const size_t CPU_TYPE_DESC_BUF_SIZE; static const size_t CPU_DETAILED_DESC_BUF_SIZE; - static const char* const _family_id_intel[]; - static const char* const _family_id_amd[]; + static const char* const _family_id_intel[ExtendedFamilyIdLength_INTEL]; + static const char* const _family_id_amd[ExtendedFamilyIdLength_AMD]; static const char* const _brand_id[]; static const char* const _model_id_pentium_pro[];
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -680,7 +680,7 @@ _features &= ~CPU_HT; } - if( is_intel() ) { // Intel cpus specific settings + if (is_intel()) { // Intel cpus specific settings if (is_knights_family()) { _features &= ~CPU_VZEROUPPER; } @@ -781,7 +781,7 @@ FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); } } else { - if(supports_sse4_1()) { + if (supports_sse4_1()) { if (FLAG_IS_DEFAULT(UseAESCTRIntrinsics)) { FLAG_SET_DEFAULT(UseAESCTRIntrinsics, true); } @@ -1001,7 +1001,7 @@ } else if (UseAVX == 1 || UseAVX == 2) { // 32 bytes vectors (in YMM) are only supported with AVX+ max_vector_size = 32; - } else if (UseAVX > 2 ) { + } else if (UseAVX > 2) { // 64 bytes vectors (in ZMM) are only supported with AVX 3 max_vector_size = 64; } @@ -1165,38 +1165,38 @@ } } - if( is_amd() ) { // AMD cpus specific settings - if( supports_sse2() && FLAG_IS_DEFAULT(UseAddressNop) ) { + if (is_amd_family()) { // AMD cpus specific settings + if (supports_sse2() && FLAG_IS_DEFAULT(UseAddressNop)) { // Use it on new AMD cpus starting from Opteron. UseAddressNop = true; } - if( supports_sse2() && FLAG_IS_DEFAULT(UseNewLongLShift) ) { + if (supports_sse2() && FLAG_IS_DEFAULT(UseNewLongLShift)) { // Use it on new AMD cpus starting from Opteron. UseNewLongLShift = true; } - if( FLAG_IS_DEFAULT(UseXmmLoadAndClearUpper) ) { + if (FLAG_IS_DEFAULT(UseXmmLoadAndClearUpper)) { if (supports_sse4a()) { UseXmmLoadAndClearUpper = true; // use movsd only on '10h' Opteron } else { UseXmmLoadAndClearUpper = false; } } - if( FLAG_IS_DEFAULT(UseXmmRegToRegMoveAll) ) { - if( supports_sse4a() ) { + if (FLAG_IS_DEFAULT(UseXmmRegToRegMoveAll)) { + if (supports_sse4a()) { UseXmmRegToRegMoveAll = true; // use movaps, movapd only on '10h' } else { UseXmmRegToRegMoveAll = false; } } - if( FLAG_IS_DEFAULT(UseXmmI2F) ) { - if( supports_sse4a() ) { + if (FLAG_IS_DEFAULT(UseXmmI2F)) { + if (supports_sse4a()) { UseXmmI2F = true; } else { UseXmmI2F = false; } } - if( FLAG_IS_DEFAULT(UseXmmI2D) ) { - if( supports_sse4a() ) { + if (FLAG_IS_DEFAULT(UseXmmI2D)) { + if (supports_sse4a()) { UseXmmI2D = true; } else { UseXmmI2D = false; @@ -1214,7 +1214,7 @@ } // some defaults for AMD family 15h - if ( cpu_family() == 0x15 ) { + if (cpu_family() == 0x15) { // On family 15h processors default is no sw prefetch if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) { FLAG_SET_DEFAULT(AllocatePrefetchStyle, 0); @@ -1239,8 +1239,8 @@ } #endif // COMPILER2 - // Some defaults for AMD family 17h - if ( cpu_family() == 0x17 ) { + // Some defaults for AMD family 17h || Hygon family 18h + if (cpu_family() == 0x17 || cpu_family() == 0x18) { // On family 17h processors use XMM and UnalignedLoadStores for Array Copy if (supports_sse2() && FLAG_IS_DEFAULT(UseXMMForArrayCopy)) { FLAG_SET_DEFAULT(UseXMMForArrayCopy, true); @@ -1256,29 +1256,29 @@ } } - if( is_intel() ) { // Intel cpus specific settings - if( FLAG_IS_DEFAULT(UseStoreImmI16) ) { + if (is_intel()) { // Intel cpus specific settings + if (FLAG_IS_DEFAULT(UseStoreImmI16)) { UseStoreImmI16 = false; // don't use it on Intel cpus } - if( cpu_family() == 6 || cpu_family() == 15 ) { - if( FLAG_IS_DEFAULT(UseAddressNop) ) { + if (cpu_family() == 6 || cpu_family() == 15) { + if (FLAG_IS_DEFAULT(UseAddressNop)) { // Use it on all Intel cpus starting from PentiumPro UseAddressNop = true; } } - if( FLAG_IS_DEFAULT(UseXmmLoadAndClearUpper) ) { + if (FLAG_IS_DEFAULT(UseXmmLoadAndClearUpper)) { UseXmmLoadAndClearUpper = true; // use movsd on all Intel cpus } - if( FLAG_IS_DEFAULT(UseXmmRegToRegMoveAll) ) { - if( supports_sse3() ) { + if (FLAG_IS_DEFAULT(UseXmmRegToRegMoveAll)) { + if (supports_sse3()) { UseXmmRegToRegMoveAll = true; // use movaps, movapd on new Intel cpus } else { UseXmmRegToRegMoveAll = false; } } - if( cpu_family() == 6 && supports_sse3() ) { // New Intel cpus + if (cpu_family() == 6 && supports_sse3()) { // New Intel cpus #ifdef COMPILER2 - if( FLAG_IS_DEFAULT(MaxLoopPad) ) { + if (FLAG_IS_DEFAULT(MaxLoopPad)) { // For new Intel cpus do the next optimization: // don't align the beginning of a loop if there are enough instructions // left (NumberOfLoopInstrToAlign defined in c2_globals.hpp) @@ -1324,7 +1324,7 @@ FLAG_SET_DEFAULT(UseIncDec, false); } } - if(FLAG_IS_DEFAULT(AllocatePrefetchInstr) && supports_3dnow_prefetch()) { + if (FLAG_IS_DEFAULT(AllocatePrefetchInstr) && supports_3dnow_prefetch()) { FLAG_SET_DEFAULT(AllocatePrefetchInstr, 3); } }
--- a/src/hotspot/cpu/x86/vm_version_x86.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/x86/vm_version_x86.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -495,13 +495,13 @@ result |= CPU_CX8; if (_cpuid_info.std_cpuid1_edx.bits.cmov != 0) result |= CPU_CMOV; - if (_cpuid_info.std_cpuid1_edx.bits.fxsr != 0 || (is_amd() && + if (_cpuid_info.std_cpuid1_edx.bits.fxsr != 0 || (is_amd_family() && _cpuid_info.ext_cpuid1_edx.bits.fxsr != 0)) result |= CPU_FXSR; // HT flag is set for multi-core processors also. if (threads_per_core() > 1) result |= CPU_HT; - if (_cpuid_info.std_cpuid1_edx.bits.mmx != 0 || (is_amd() && + if (_cpuid_info.std_cpuid1_edx.bits.mmx != 0 || (is_amd_family() && _cpuid_info.ext_cpuid1_edx.bits.mmx != 0)) result |= CPU_MMX; if (_cpuid_info.std_cpuid1_edx.bits.sse != 0) @@ -553,7 +553,7 @@ result |= CPU_VNNI; } } - if(_cpuid_info.sef_cpuid7_ebx.bits.bmi1 != 0) + if (_cpuid_info.sef_cpuid7_ebx.bits.bmi1 != 0) result |= CPU_BMI1; if (_cpuid_info.std_cpuid1_edx.bits.tsc != 0) result |= CPU_TSC; @@ -567,17 +567,17 @@ result |= CPU_CLMUL; if (_cpuid_info.sef_cpuid7_ebx.bits.rtm != 0) result |= CPU_RTM; - if(_cpuid_info.sef_cpuid7_ebx.bits.adx != 0) + if (_cpuid_info.sef_cpuid7_ebx.bits.adx != 0) result |= CPU_ADX; - if(_cpuid_info.sef_cpuid7_ebx.bits.bmi2 != 0) + if (_cpuid_info.sef_cpuid7_ebx.bits.bmi2 != 0) result |= CPU_BMI2; if (_cpuid_info.sef_cpuid7_ebx.bits.sha != 0) result |= CPU_SHA; if (_cpuid_info.std_cpuid1_ecx.bits.fma != 0) result |= CPU_FMA; - // AMD features. - if (is_amd()) { + // AMD|Hygon features. + if (is_amd_family()) { if ((_cpuid_info.ext_cpuid1_edx.bits.tdnow != 0) || (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0)) result |= CPU_3DNOW_PREFETCH; @@ -587,8 +587,8 @@ result |= CPU_SSE4A; } // Intel features. - if(is_intel()) { - if(_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0) + if (is_intel()) { + if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0) result |= CPU_LZCNT; // for Intel, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) { @@ -714,6 +714,8 @@ static int cpu_family() { return _cpu;} static bool is_P6() { return cpu_family() >= 6; } static bool is_amd() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x68747541; } // 'htuA' + static bool is_hygon() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x6F677948; } // 'ogyH' + static bool is_amd_family() { return is_amd() || is_hygon(); } static bool is_intel() { assert_is_initialized(); return _cpuid_info.std_vendor_name_0 == 0x756e6547; } // 'uneG' static bool is_zx() { assert_is_initialized(); return (_cpuid_info.std_vendor_name_0 == 0x746e6543) || (_cpuid_info.std_vendor_name_0 == 0x68532020); } // 'tneC'||'hS ' static bool is_atom_family() { return ((cpu_family() == 0x06) && ((extended_cpu_model() == 0x36) || (extended_cpu_model() == 0x37) || (extended_cpu_model() == 0x4D))); } //Silvermont and Centerton @@ -737,7 +739,7 @@ if (!supports_topology || result == 0) { result = (_cpuid_info.dcp_cpuid4_eax.bits.cores_per_cpu + 1); } - } else if (is_amd()) { + } else if (is_amd_family()) { result = (_cpuid_info.ext_cpuid8_ecx.bits.cores_per_cpu + 1); } else if (is_zx()) { bool supports_topology = supports_processor_topology(); @@ -773,7 +775,7 @@ intx result = 0; if (is_intel()) { result = (_cpuid_info.dcp_cpuid4_ebx.bits.L1_line_size + 1); - } else if (is_amd()) { + } else if (is_amd_family()) { result = _cpuid_info.ext_cpuid5_ecx.bits.L1_line_size; } else if (is_zx()) { result = (_cpuid_info.dcp_cpuid4_ebx.bits.L1_line_size + 1); @@ -860,7 +862,7 @@ // AMD features static bool supports_3dnow_prefetch() { return (_features & CPU_3DNOW_PREFETCH) != 0; } - static bool supports_mmx_ext() { return is_amd() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; } + static bool supports_mmx_ext() { return is_amd_family() && _cpuid_info.ext_cpuid1_edx.bits.mmx_amd != 0; } static bool supports_lzcnt() { return (_features & CPU_LZCNT) != 0; } static bool supports_sse4a() { return (_features & CPU_SSE4A) != 0; } @@ -873,8 +875,8 @@ } static bool supports_tscinv() { return supports_tscinv_bit() && - ( (is_amd() && !is_amd_Barcelona()) || - is_intel_tsc_synched_at_init() ); + ((is_amd_family() && !is_amd_Barcelona()) || + is_intel_tsc_synched_at_init()); } // Intel Core and newer cpus have fast IDIV instruction (excluding Atom). @@ -899,7 +901,7 @@ // Core - 256 / prefetchnta // It will be used only when AllocatePrefetchStyle > 0 - if (is_amd()) { // AMD + if (is_amd_family()) { // AMD | Hygon if (supports_sse2()) { return 256; // Opteron } else {
--- a/src/hotspot/cpu/zero/cppInterpreter_zero.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/zero/cppInterpreter_zero.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -699,11 +699,11 @@ return stack->sp() + argument_slots; } -IRT_ENTRY(void, CppInterpreter::throw_exception(JavaThread* thread, +JRT_ENTRY(void, CppInterpreter::throw_exception(JavaThread* thread, Symbol* name, char* message)) THROW_MSG(name, message); -IRT_END +JRT_END InterpreterFrame *InterpreterFrame::build(Method* const method, TRAPS) { JavaThread *thread = (JavaThread *) THREAD;
--- a/src/hotspot/cpu/zero/interpreterRT_zero.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/cpu/zero/interpreterRT_zero.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -141,7 +141,7 @@ assert(status == FFI_OK, "should be"); } -IRT_ENTRY(address, +JRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread, Method* method, intptr_t* unused1, @@ -162,7 +162,7 @@ handler->finalize(); return (address) handler; -IRT_END +JRT_END void SignatureHandlerLibrary::pd_set_handler(address handlerAddr) { InterpreterRuntime::SignatureHandler *handler =
--- a/src/hotspot/os/aix/os_aix.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/os/aix/os_aix.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1405,13 +1405,7 @@ st->print_cr("type: %s", (wi.app_wpar ? "application" : "system")); } - // print partition info - libperfstat::partitioninfo_t pi; - if (libperfstat::get_partitioninfo(&pi)) { - st->print_cr("partition info"); - st->print_cr(" name: %s", pi.name); - } - + VM_Version::print_platform_virtualization_info(st); } void os::print_memory_info(outputStream* st) {
--- a/src/hotspot/os/linux/osContainer_linux.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/os/linux/osContainer_linux.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -122,7 +122,25 @@ char *subsystem_path() { return _path; } }; -CgroupSubsystem* memory = NULL; +class CgroupMemorySubsystem: CgroupSubsystem { + friend class OSContainer; + + private: + /* Some container runtimes set limits via cgroup + * hierarchy. If set to true consider also memory.stat + * file if everything else seems unlimited */ + bool _uses_mem_hierarchy; + + public: + CgroupMemorySubsystem(char *root, char *mountpoint) : CgroupSubsystem::CgroupSubsystem(root, mountpoint) { + _uses_mem_hierarchy = false; + } + + bool is_hierarchical() { return _uses_mem_hierarchy; } + void set_hierarchical(bool value) { _uses_mem_hierarchy = value; } +}; + +CgroupMemorySubsystem* memory = NULL; CgroupSubsystem* cpuset = NULL; CgroupSubsystem* cpu = NULL; CgroupSubsystem* cpuacct = NULL; @@ -131,21 +149,24 @@ PRAGMA_DIAG_PUSH PRAGMA_FORMAT_NONLITERAL_IGNORED -template <typename T> int subsystem_file_contents(CgroupSubsystem* c, +template <typename T> int subsystem_file_line_contents(CgroupSubsystem* c, const char *filename, + const char *matchline, const char *scan_fmt, T returnval) { FILE *fp = NULL; char *p; char file[MAXPATHLEN+1]; char buf[MAXPATHLEN+1]; + char discard[MAXPATHLEN+1]; + bool found_match = false; if (c == NULL) { - log_debug(os, container)("subsystem_file_contents: CgroupSubsytem* is NULL"); + log_debug(os, container)("subsystem_file_line_contents: CgroupSubsytem* is NULL"); return OSCONTAINER_ERROR; } if (c->subsystem_path() == NULL) { - log_debug(os, container)("subsystem_file_contents: subsystem path is NULL"); + log_debug(os, container)("subsystem_file_line_contents: subsystem path is NULL"); return OSCONTAINER_ERROR; } @@ -160,16 +181,32 @@ log_trace(os, container)("Path to %s is %s", filename, file); fp = fopen(file, "r"); if (fp != NULL) { - p = fgets(buf, MAXPATHLEN, fp); - if (p != NULL) { - int matched = sscanf(p, scan_fmt, returnval); - if (matched == 1) { + int err = 0; + while ((p = fgets(buf, MAXPATHLEN, fp)) != NULL) { + found_match = false; + if (matchline == NULL) { + // single-line file case + int matched = sscanf(p, scan_fmt, returnval); + found_match = (matched == 1); + } else { + // multi-line file case + if (strstr(p, matchline) != NULL) { + // discard matchline string prefix + int matched = sscanf(p, scan_fmt, discard, returnval); + found_match = (matched == 2); + } else { + continue; // substring not found + } + } + if (found_match) { fclose(fp); return 0; } else { + err = 1; log_debug(os, container)("Type %s not found in file %s", scan_fmt, file); } - } else { + } + if (err == 0) { log_debug(os, container)("Empty file %s", file); } } else { @@ -186,10 +223,11 @@ return_type variable; \ { \ int err; \ - err = subsystem_file_contents(subsystem, \ - filename, \ - scan_fmt, \ - &variable); \ + err = subsystem_file_line_contents(subsystem, \ + filename, \ + NULL, \ + scan_fmt, \ + &variable); \ if (err != 0) \ return (return_type) OSCONTAINER_ERROR; \ \ @@ -201,16 +239,33 @@ char variable[bufsize]; \ { \ int err; \ - err = subsystem_file_contents(subsystem, \ - filename, \ - scan_fmt, \ - variable); \ + err = subsystem_file_line_contents(subsystem, \ + filename, \ + NULL, \ + scan_fmt, \ + variable); \ if (err != 0) \ return (return_type) NULL; \ \ log_trace(os, container)(logstring, variable); \ } +#define GET_CONTAINER_INFO_LINE(return_type, subsystem, filename, \ + matchline, logstring, scan_fmt, variable) \ + return_type variable; \ +{ \ + int err; \ + err = subsystem_file_line_contents(subsystem, \ + filename, \ + matchline, \ + scan_fmt, \ + &variable); \ + if (err != 0) \ + return (return_type) OSCONTAINER_ERROR; \ + \ + log_trace(os, container)(logstring, variable); \ +} + /* init * * Initialize the container support and determine if @@ -266,7 +321,7 @@ } while ((token = strsep(&cptr, ",")) != NULL) { if (strcmp(token, "memory") == 0) { - memory = new CgroupSubsystem(tmproot, tmpmount); + memory = new CgroupMemorySubsystem(tmproot, tmpmount); } else if (strcmp(token, "cpuset") == 0) { cpuset = new CgroupSubsystem(tmproot, tmpmount); } else if (strcmp(token, "cpu") == 0) { @@ -344,6 +399,10 @@ while ((token = strsep(&controllers, ",")) != NULL) { if (strcmp(token, "memory") == 0) { memory->set_subsystem_path(base); + jlong hierarchy = uses_mem_hierarchy(); + if (hierarchy > 0) { + memory->set_hierarchical(true); + } } else if (strcmp(token, "cpuset") == 0) { cpuset->set_subsystem_path(base); } else if (strcmp(token, "cpu") == 0) { @@ -360,6 +419,7 @@ // command line arguments have been processed. if ((mem_limit = memory_limit_in_bytes()) > 0) { os::Linux::set_physical_memory(mem_limit); + log_info(os, container)("Memory Limit is: " JLONG_FORMAT, mem_limit); } _is_containerized = true; @@ -374,6 +434,21 @@ } } +/* uses_mem_hierarchy + * + * Return whether or not hierarchical cgroup accounting is being + * done. + * + * return: + * A number > 0 if true, or + * OSCONTAINER_ERROR for not supported + */ +jlong OSContainer::uses_mem_hierarchy() { + GET_CONTAINER_INFO(jlong, memory, "/memory.use_hierarchy", + "Use Hierarchy is: " JLONG_FORMAT, JLONG_FORMAT, use_hierarchy); + return use_hierarchy; +} + /* memory_limit_in_bytes * @@ -389,7 +464,18 @@ "Memory Limit is: " JULONG_FORMAT, JULONG_FORMAT, memlimit); if (memlimit >= _unlimited_memory) { - log_trace(os, container)("Memory Limit is: Unlimited"); + log_trace(os, container)("Non-Hierarchical Memory Limit is: Unlimited"); + if (memory->is_hierarchical()) { + const char* matchline = "hierarchical_memory_limit"; + char* format = "%s " JULONG_FORMAT; + GET_CONTAINER_INFO_LINE(julong, memory, "/memory.stat", matchline, + "Hierarchical Memory Limit is: " JULONG_FORMAT, format, hier_memlimit) + if (hier_memlimit >= _unlimited_memory) { + log_trace(os, container)("Hierarchical Memory Limit is: Unlimited"); + } else { + return (jlong)hier_memlimit; + } + } return (jlong)-1; } else { @@ -401,7 +487,18 @@ GET_CONTAINER_INFO(julong, memory, "/memory.memsw.limit_in_bytes", "Memory and Swap Limit is: " JULONG_FORMAT, JULONG_FORMAT, memswlimit); if (memswlimit >= _unlimited_memory) { - log_trace(os, container)("Memory and Swap Limit is: Unlimited"); + log_trace(os, container)("Non-Hierarchical Memory and Swap Limit is: Unlimited"); + if (memory->is_hierarchical()) { + const char* matchline = "hierarchical_memsw_limit"; + char* format = "%s " JULONG_FORMAT; + GET_CONTAINER_INFO_LINE(julong, memory, "/memory.stat", matchline, + "Hierarchical Memory and Swap Limit is : " JULONG_FORMAT, format, hier_memlimit) + if (hier_memlimit >= _unlimited_memory) { + log_trace(os, container)("Hierarchical Memory and Swap Limit is: Unlimited"); + } else { + return (jlong)hier_memlimit; + } + } return (jlong)-1; } else { return (jlong)memswlimit;
--- a/src/hotspot/os/linux/osContainer_linux.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/os/linux/osContainer_linux.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -42,6 +42,7 @@ static inline bool is_containerized(); static const char * container_type(); + static jlong uses_mem_hierarchy(); static jlong memory_limit_in_bytes(); static jlong memory_and_swap_limit_in_bytes(); static jlong memory_soft_limit_in_bytes();
--- a/src/hotspot/os/windows/os_windows.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/os/windows/os_windows.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -5000,17 +5000,13 @@ char *addr, size_t bytes, bool read_only, bool allow_exec) { // This OS does not allow existing memory maps to be remapped so we - // have to unmap the memory before we remap it. - if (!os::unmap_memory(addr, bytes)) { - return NULL; - } - - // There is a very small theoretical window between the unmap_memory() - // call above and the map_memory() call below where a thread in native - // code may be able to access an address that is no longer mapped. - - return os::map_memory(fd, file_name, file_offset, addr, bytes, - read_only, allow_exec); + // would have to unmap the memory before we remap it. + + // Because there is a small window between unmapping memory and mapping + // it in again with different protections, CDS archives are mapped RW + // on windows, so this function isn't called. + ShouldNotReachHere(); + return NULL; }
--- a/src/hotspot/os/windows/version.rc Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/os/windows/version.rc Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ // -// Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2004, 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 @@ -36,8 +36,8 @@ // VS_VERSION_INFO VERSIONINFO - FILEVERSION JDK_VER - PRODUCTVERSION JDK_VER + FILEVERSION HS_FVER + PRODUCTVERSION HS_FVER FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -54,15 +54,15 @@ BEGIN BLOCK "000004b0" BEGIN - VALUE "CompanyName", XSTR(HS_COMPANY) "\0" - VALUE "FileDescription", XSTR(HS_FILEDESC) "\0" - VALUE "FileVersion", XSTR(JDK_DOTVER) "\0" - VALUE "Full Version", XSTR(HS_BUILD_ID) "\0" - VALUE "InternalName", XSTR(HS_INTERNAL_NAME) "\0" - VALUE "LegalCopyright", XSTR(HS_COPYRIGHT) "\0" - VALUE "OriginalFilename", XSTR(HS_FNAME) "\0" - VALUE "ProductName", XSTR(HS_NAME) "\0" - VALUE "ProductVersion", XSTR(JDK_DOTVER) "\0" + VALUE "CompanyName", XSTR(HS_COMPANY) "\0" + VALUE "FileDescription", XSTR(HS_FILEDESC) "\0" + VALUE "FileVersion", XSTR(HS_VER) "\0" + VALUE "Full Version", XSTR(HS_VERSION_STRING) "\0" + VALUE "InternalName", XSTR(HS_INTERNAL_NAME) "\0" + VALUE "LegalCopyright", XSTR(HS_COPYRIGHT) "\0" + VALUE "OriginalFilename", XSTR(HS_FNAME) "\0" + VALUE "ProductName", XSTR(HS_NAME) "\0" + VALUE "ProductVersion", XSTR(HS_VER) "\0" END END BLOCK "VarFileInfo"
--- a/src/hotspot/share/adlc/formssel.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/adlc/formssel.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -774,10 +774,16 @@ !strcmp(_matrule->_rChild->_opType,"CheckCastPP") || !strcmp(_matrule->_rChild->_opType,"GetAndSetP") || !strcmp(_matrule->_rChild->_opType,"GetAndSetN") || +#if INCLUDE_ZGC + !strcmp(_matrule->_rChild->_opType,"LoadBarrierSlowReg") || + !strcmp(_matrule->_rChild->_opType,"LoadBarrierWeakSlowReg") || +#endif +#if INCLUDE_SHENANDOAHGC + !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeP") || + !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeN") || +#endif !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeP") || - !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeN") || - !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeP") || - !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeN"))) return true; + !strcmp(_matrule->_rChild->_opType,"CompareAndExchangeN"))) return true; else if ( is_ideal_load() == Form::idealP ) return true; else if ( is_ideal_store() != Form::none ) return true;
--- a/src/hotspot/share/classfile/classFileParser.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/classfile/classFileParser.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -5975,9 +5975,9 @@ _minor_version = stream->get_u2_fast(); _major_version = stream->get_u2_fast(); - if (DumpSharedSpaces && _major_version < JAVA_1_5_VERSION) { + if (DumpSharedSpaces && _major_version < JAVA_6_VERSION) { ResourceMark rm; - warning("Pre JDK 1.5 class not supported by CDS: %u.%u %s", + warning("Pre JDK 6 class not supported by CDS: %u.%u %s", _major_version, _minor_version, _class_name->as_C_string()); Exceptions::fthrow( THREAD_AND_LOCATION,
--- a/src/hotspot/share/classfile/javaClasses.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/classfile/javaClasses.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1714,20 +1714,13 @@ jlong java_lang_Thread::stackSize(oop java_thread) { - if (_stackSize_offset > 0) { - return java_thread->long_field(_stackSize_offset); - } else { - return 0; - } + return java_thread->long_field(_stackSize_offset); } // Write the thread status value to threadStatus field in java.lang.Thread java class. void java_lang_Thread::set_thread_status(oop java_thread, java_lang_Thread::ThreadStatus status) { - // The threadStatus is only present starting in 1.5 - if (_thread_status_offset > 0) { - java_thread->int_field_put(_thread_status_offset, status); - } + java_thread->int_field_put(_thread_status_offset, status); } // Read thread status value from threadStatus field in java.lang.Thread java class. @@ -1737,62 +1730,31 @@ assert(Threads_lock->owned_by_self() || Thread::current()->is_VM_thread() || JavaThread::current()->thread_state() == _thread_in_vm, "Java Thread is not running in vm"); - // The threadStatus is only present starting in 1.5 - if (_thread_status_offset > 0) { - return (java_lang_Thread::ThreadStatus)java_thread->int_field(_thread_status_offset); - } else { - // All we can easily figure out is if it is alive, but that is - // enough info for a valid unknown status. - // These aren't restricted to valid set ThreadStatus values, so - // use JVMTI values and cast. - JavaThread* thr = java_lang_Thread::thread(java_thread); - if (thr == NULL) { - // the thread hasn't run yet or is in the process of exiting - return NEW; - } - return (java_lang_Thread::ThreadStatus)JVMTI_THREAD_STATE_ALIVE; - } + return (java_lang_Thread::ThreadStatus)java_thread->int_field(_thread_status_offset); } jlong java_lang_Thread::thread_id(oop java_thread) { - // The thread ID field is only present starting in 1.5 - if (_tid_offset > 0) { - return java_thread->long_field(_tid_offset); - } else { - return 0; - } + return java_thread->long_field(_tid_offset); } oop java_lang_Thread::park_blocker(oop java_thread) { - assert(JDK_Version::current().supports_thread_park_blocker() && - _park_blocker_offset != 0, "Must support parkBlocker field"); - - if (_park_blocker_offset > 0) { - return java_thread->obj_field(_park_blocker_offset); - } - - return NULL; + assert(JDK_Version::current().supports_thread_park_blocker(), + "Must support parkBlocker field"); + + return java_thread->obj_field(_park_blocker_offset); } jlong java_lang_Thread::park_event(oop java_thread) { - if (_park_event_offset > 0) { - return java_thread->long_field(_park_event_offset); - } - return 0; + return java_thread->long_field(_park_event_offset); } bool java_lang_Thread::set_park_event(oop java_thread, jlong ptr) { - if (_park_event_offset > 0) { - java_thread->long_field_put(_park_event_offset, ptr); - return true; - } - return false; -} - + java_thread->long_field_put(_park_event_offset, ptr); + return true; +} const char* java_lang_Thread::thread_status_name(oop java_thread) { - assert(_thread_status_offset != 0, "Must have thread status"); ThreadStatus status = (java_lang_Thread::ThreadStatus)java_thread->int_field(_thread_status_offset); switch (status) { case NEW : return "NEW"; @@ -3635,23 +3597,48 @@ resolved_method->address_field_put(_vmtarget_offset, (address)m); } +void java_lang_invoke_ResolvedMethodName::set_vmholder(oop resolved_method, oop holder) { + assert(is_instance(resolved_method), "wrong type"); + resolved_method->obj_field_put(_vmholder_offset, holder); +} + oop java_lang_invoke_ResolvedMethodName::find_resolved_method(const methodHandle& m, TRAPS) { + const Method* method = m(); + // lookup ResolvedMethod oop in the table, or create a new one and intern it - oop resolved_method = ResolvedMethodTable::find_method(m()); - if (resolved_method == NULL) { - InstanceKlass* k = SystemDictionary::ResolvedMethodName_klass(); - if (!k->is_initialized()) { - k->initialize(CHECK_NULL); - } - oop new_resolved_method = k->allocate_instance(CHECK_NULL); - new_resolved_method->address_field_put(_vmtarget_offset, (address)m()); - // Add a reference to the loader (actually mirror because unsafe anonymous classes will not have - // distinct loaders) to ensure the metadata is kept alive. - // This mirror may be different than the one in clazz field. - new_resolved_method->obj_field_put(_vmholder_offset, m->method_holder()->java_mirror()); - resolved_method = ResolvedMethodTable::add_method(m, Handle(THREAD, new_resolved_method)); + oop resolved_method = ResolvedMethodTable::find_method(method); + if (resolved_method != NULL) { + return resolved_method; + } + + InstanceKlass* k = SystemDictionary::ResolvedMethodName_klass(); + if (!k->is_initialized()) { + k->initialize(CHECK_NULL); } - return resolved_method; + + oop new_resolved_method = k->allocate_instance(CHECK_NULL); + + NoSafepointVerifier nsv; + + if (method->is_old()) { + method = (method->is_deleted()) ? Universe::throw_no_such_method_error() : + method->get_new_method(); + } + + InstanceKlass* holder = method->method_holder(); + + set_vmtarget(new_resolved_method, const_cast<Method*>(method)); + // Add a reference to the loader (actually mirror because unsafe anonymous classes will not have + // distinct loaders) to ensure the metadata is kept alive. + // This mirror may be different than the one in clazz field. + set_vmholder(new_resolved_method, holder->java_mirror()); + + // Set flag in class to indicate this InstanceKlass has entries in the table + // to avoid walking table during redefinition if none of the redefined classes + // have any membernames in the table. + holder->set_has_resolved_methods(); + + return ResolvedMethodTable::add_method(method, Handle(THREAD, new_resolved_method)); } oop java_lang_invoke_LambdaForm::vmentry(oop lform) {
--- a/src/hotspot/share/classfile/javaClasses.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/classfile/javaClasses.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -1063,6 +1063,8 @@ static Method* vmtarget(oop resolved_method); static void set_vmtarget(oop resolved_method, Method* method); + static void set_vmholder(oop resolved_method, oop holder); + // find or create resolved member name static oop find_resolved_method(const methodHandle& m, TRAPS);
--- a/src/hotspot/share/classfile/systemDictionary.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/classfile/systemDictionary.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -68,7 +68,6 @@ #include "oops/symbol.hpp" #include "oops/typeArrayKlass.hpp" #include "prims/jvmtiExport.hpp" -#include "prims/resolvedMethodTable.hpp" #include "prims/methodHandles.hpp" #include "runtime/arguments.hpp" #include "runtime/biasedLocking.hpp" @@ -1836,8 +1835,6 @@ } GCTraceTime(Debug, gc, phases) t("Trigger cleanups", gc_timer); - // Trigger cleaning the ResolvedMethodTable even if no unloading occurred. - ResolvedMethodTable::trigger_cleanup(); if (unloading_occurred) { SymbolTable::trigger_cleanup();
--- a/src/hotspot/share/gc/shared/weakProcessor.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shared/weakProcessor.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -31,22 +31,33 @@ #include "gc/shared/weakProcessorPhaseTimes.hpp" #include "memory/allocation.inline.hpp" #include "memory/iterator.hpp" +#include "prims/resolvedMethodTable.hpp" #include "runtime/globals.hpp" #include "utilities/macros.hpp" +template <typename Container> +class OopsDoAndReportCounts { +public: + void operator()(BoolObjectClosure* is_alive, OopClosure* keep_alive, WeakProcessorPhase phase) { + Container::reset_dead_counter(); + + CountingSkippedIsAliveClosure<BoolObjectClosure, OopClosure> cl(is_alive, keep_alive); + WeakProcessorPhases::oop_storage(phase)->oops_do(&cl); + + Container::inc_dead_counter(cl.num_dead() + cl.num_skipped()); + Container::finish_dead_counter(); + } +}; + void WeakProcessor::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive) { FOR_EACH_WEAK_PROCESSOR_PHASE(phase) { if (WeakProcessorPhases::is_serial(phase)) { WeakProcessorPhases::processor(phase)(is_alive, keep_alive); } else { if (WeakProcessorPhases::is_stringtable(phase)) { - StringTable::reset_dead_counter(); - - CountingSkippedIsAliveClosure<BoolObjectClosure, OopClosure> cl(is_alive, keep_alive); - WeakProcessorPhases::oop_storage(phase)->oops_do(&cl); - - StringTable::inc_dead_counter(cl.num_dead() + cl.num_skipped()); - StringTable::finish_dead_counter(); + OopsDoAndReportCounts<StringTable>()(is_alive, keep_alive, phase); + } else if (WeakProcessorPhases::is_resolved_method_table(phase)){ + OopsDoAndReportCounts<ResolvedMethodTable>()(is_alive, keep_alive, phase); } else { WeakProcessorPhases::oop_storage(phase)->weak_oops_do(is_alive, keep_alive); } @@ -104,6 +115,7 @@ new (states++) StorageState(storage, _nworkers); } StringTable::reset_dead_counter(); + ResolvedMethodTable::reset_dead_counter(); } WeakProcessor::Task::Task(uint nworkers) : @@ -134,6 +146,7 @@ FREE_C_HEAP_ARRAY(StorageState, _storage_states); } StringTable::finish_dead_counter(); + ResolvedMethodTable::finish_dead_counter(); } void WeakProcessor::GangTask::work(uint worker_id) {
--- a/src/hotspot/share/gc/shared/weakProcessor.inline.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shared/weakProcessor.inline.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -32,6 +32,7 @@ #include "gc/shared/weakProcessorPhases.hpp" #include "gc/shared/weakProcessorPhaseTimes.hpp" #include "gc/shared/workgroup.hpp" +#include "prims/resolvedMethodTable.hpp" #include "utilities/debug.hpp" class BoolObjectClosure; @@ -115,6 +116,9 @@ if (WeakProcessorPhases::is_stringtable(phase)) { StringTable::inc_dead_counter(cl.num_dead() + cl.num_skipped()); } + if (WeakProcessorPhases::is_resolved_method_table(phase)) { + ResolvedMethodTable::inc_dead_counter(cl.num_dead() + cl.num_skipped()); + } } }
--- a/src/hotspot/share/gc/shared/weakProcessorPhases.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shared/weakProcessorPhases.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -26,6 +26,7 @@ #include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "gc/shared/weakProcessorPhases.hpp" +#include "prims/resolvedMethodTable.hpp" #include "runtime/jniHandles.hpp" #include "utilities/debug.hpp" #include "utilities/macros.hpp" @@ -80,6 +81,7 @@ JFR_ONLY(case jfr: return "JFR weak processing";) case jni: return "JNI weak processing"; case stringtable: return "StringTable weak processing"; + case resolved_method_table: return "ResolvedMethodTable weak processing"; case vm: return "VM weak processing"; default: ShouldNotReachHere(); @@ -101,6 +103,7 @@ switch (phase) { case jni: return JNIHandles::weak_global_handles(); case stringtable: return StringTable::weak_storage(); + case resolved_method_table: return ResolvedMethodTable::weak_storage(); case vm: return SystemDictionary::vm_weak_oop_storage(); default: ShouldNotReachHere(); @@ -111,3 +114,7 @@ bool WeakProcessorPhases::is_stringtable(Phase phase) { return phase == stringtable; } + +bool WeakProcessorPhases::is_resolved_method_table(Phase phase) { + return phase == resolved_method_table; +}
--- a/src/hotspot/share/gc/shared/weakProcessorPhases.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shared/weakProcessorPhases.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -45,6 +45,7 @@ // OopStorage phases. jni, stringtable, + resolved_method_table, vm }; @@ -68,6 +69,7 @@ static OopStorage* oop_storage(Phase phase); // Precondition: is_oop_storage(phase) static bool is_stringtable(Phase phase); + static bool is_resolved_method_table(Phase phase); }; typedef WeakProcessorPhases::Phase WeakProcessorPhase;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP + +#include "memory/iterator.hpp" + +class ShenandoahHeap; +class ShenandoahMarkingContext; +class Thread; + +class ShenandoahForwardedIsAliveClosure: public BoolObjectClosure { +private: + ShenandoahMarkingContext* const _mark_context; +public: + inline ShenandoahForwardedIsAliveClosure(); + inline bool do_object_b(oop obj); +}; + +class ShenandoahIsAliveClosure: public BoolObjectClosure { +private: + ShenandoahMarkingContext* const _mark_context; +public: + inline ShenandoahIsAliveClosure(); + inline bool do_object_b(oop obj); +}; + +class ShenandoahIsAliveSelector : public StackObj { +private: + ShenandoahIsAliveClosure _alive_cl; + ShenandoahForwardedIsAliveClosure _fwd_alive_cl; +public: + inline BoolObjectClosure* is_alive_closure(); +}; + +class ShenandoahUpdateRefsClosure: public OopClosure { +private: + ShenandoahHeap* _heap; +public: + inline ShenandoahUpdateRefsClosure(); + inline void do_oop(oop* p); + inline void do_oop(narrowOop* p); +private: + template <class T> + inline void do_oop_work(T* p); +}; + +class ShenandoahEvacuateUpdateRootsClosure: public BasicOopIterateClosure { +private: + ShenandoahHeap* _heap; + Thread* _thread; +public: + inline ShenandoahEvacuateUpdateRootsClosure(); + inline void do_oop(oop* p); + inline void do_oop(narrowOop* p); + +private: + template <class T> + inline void do_oop_work(T* p); +}; + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. All rights reserved. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_INLINE_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_INLINE_HPP + +#include "gc/shenandoah/shenandoahAsserts.hpp" +#include "gc/shenandoah/shenandoahClosures.hpp" +#include "gc/shenandoah/shenandoahHeap.inline.hpp" +#include "oops/compressedOops.inline.hpp" +#include "runtime/thread.hpp" + +ShenandoahForwardedIsAliveClosure::ShenandoahForwardedIsAliveClosure() : + _mark_context(ShenandoahHeap::heap()->marking_context()) { +} + +bool ShenandoahForwardedIsAliveClosure::do_object_b(oop obj) { + if (CompressedOops::is_null(obj)) { + return false; + } + obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); + shenandoah_assert_not_forwarded_if(NULL, obj, + (ShenandoahHeap::heap()->is_concurrent_mark_in_progress() || + ShenandoahHeap::heap()->is_concurrent_traversal_in_progress())); + return _mark_context->is_marked(obj); +} + +ShenandoahIsAliveClosure::ShenandoahIsAliveClosure() : + _mark_context(ShenandoahHeap::heap()->marking_context()) { +} + +bool ShenandoahIsAliveClosure::do_object_b(oop obj) { + if (CompressedOops::is_null(obj)) { + return false; + } + shenandoah_assert_not_forwarded(NULL, obj); + return _mark_context->is_marked(obj); +} + +BoolObjectClosure* ShenandoahIsAliveSelector::is_alive_closure() { + return ShenandoahHeap::heap()->has_forwarded_objects() ? + reinterpret_cast<BoolObjectClosure*>(&_fwd_alive_cl) : + reinterpret_cast<BoolObjectClosure*>(&_alive_cl); +} + +ShenandoahUpdateRefsClosure::ShenandoahUpdateRefsClosure() : + _heap(ShenandoahHeap::heap()) { +} + +template <class T> +void ShenandoahUpdateRefsClosure::do_oop_work(T* p) { + T o = RawAccess<>::oop_load(p); + if (!CompressedOops::is_null(o)) { + oop obj = CompressedOops::decode_not_null(o); + _heap->update_with_forwarded_not_null(p, obj); + } +} + +void ShenandoahUpdateRefsClosure::do_oop(oop* p) { do_oop_work(p); } +void ShenandoahUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); } + +ShenandoahEvacuateUpdateRootsClosure::ShenandoahEvacuateUpdateRootsClosure() : + _heap(ShenandoahHeap::heap()), _thread(Thread::current()) { +} + +template <class T> +void ShenandoahEvacuateUpdateRootsClosure::do_oop_work(T* p) { + assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); + + T o = RawAccess<>::oop_load(p); + if (! CompressedOops::is_null(o)) { + oop obj = CompressedOops::decode_not_null(o); + if (_heap->in_collection_set(obj)) { + shenandoah_assert_marked(p, obj); + oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); + if (oopDesc::equals_raw(resolved, obj)) { + resolved = _heap->evacuate_object(obj, _thread); + } + RawAccess<IS_NOT_NULL>::oop_store(p, resolved); + } + } +} +void ShenandoahEvacuateUpdateRootsClosure::do_oop(oop* p) { + do_oop_work(p); +} + +void ShenandoahEvacuateUpdateRootsClosure::do_oop(narrowOop* p) { + do_oop_work(p); +} + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -33,6 +33,7 @@ #include "gc/shared/referenceProcessorPhaseTimes.hpp" #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp" +#include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" #include "gc/shenandoah/shenandoahMarkCompact.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp"
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -33,6 +33,7 @@ #include "gc/shenandoah/shenandoahAllocTracker.hpp" #include "gc/shenandoah/shenandoahBarrierSet.hpp" #include "gc/shenandoah/shenandoahBrooksPointer.hpp" +#include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" @@ -70,8 +71,6 @@ #include "runtime/vmThread.hpp" #include "services/mallocTracker.hpp" -ShenandoahUpdateRefsClosure::ShenandoahUpdateRefsClosure() : _heap(ShenandoahHeap::heap()) {} - #ifdef ASSERT template <class T> void ShenandoahAssertToSpaceClosure::do_oop_work(T* p) { @@ -459,8 +458,8 @@ _max_workers = MAX2(_max_workers, 1U); _workers = new ShenandoahWorkGang("Shenandoah GC Threads", _max_workers, - /* are_GC_task_threads */true, - /* are_ConcurrentGC_threads */false); + /* are_GC_task_threads */ true, + /* are_ConcurrentGC_threads */ true); if (_workers == NULL) { vm_exit_during_initialization("Failed necessary allocation."); } else { @@ -470,7 +469,8 @@ if (ShenandoahParallelSafepointThreads > 1) { _safepoint_workers = new ShenandoahWorkGang("Safepoint Cleanup Thread", ShenandoahParallelSafepointThreads, - false, false); + /* are_GC_task_threads */ false, + /* are_ConcurrentGC_threads */ false); _safepoint_workers->initialize_workers(); } } @@ -939,43 +939,6 @@ return CollectedHeap::min_dummy_object_size() + ShenandoahBrooksPointer::word_size(); } -class ShenandoahEvacuateUpdateRootsClosure: public BasicOopIterateClosure { -private: - ShenandoahHeap* _heap; - Thread* _thread; -public: - ShenandoahEvacuateUpdateRootsClosure() : - _heap(ShenandoahHeap::heap()), _thread(Thread::current()) { - } - -private: - template <class T> - void do_oop_work(T* p) { - assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); - - T o = RawAccess<>::oop_load(p); - if (! CompressedOops::is_null(o)) { - oop obj = CompressedOops::decode_not_null(o); - if (_heap->in_collection_set(obj)) { - shenandoah_assert_marked(p, obj); - oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); - if (oopDesc::equals_raw(resolved, obj)) { - resolved = _heap->evacuate_object(obj, _thread); - } - RawAccess<IS_NOT_NULL>::oop_store(p, resolved); - } - } - } - -public: - void do_oop(oop* p) { - do_oop_work(p); - } - void do_oop(narrowOop* p) { - do_oop_work(p); - } -}; - class ShenandoahConcurrentEvacuateRegionObjectClosure : public ObjectClosure { private: ShenandoahHeap* const _heap; @@ -1883,31 +1846,6 @@ return result; } -ShenandoahForwardedIsAliveClosure::ShenandoahForwardedIsAliveClosure() : - _mark_context(ShenandoahHeap::heap()->marking_context()) { -} - -ShenandoahIsAliveClosure::ShenandoahIsAliveClosure() : - _mark_context(ShenandoahHeap::heap()->marking_context()) { -} - -bool ShenandoahForwardedIsAliveClosure::do_object_b(oop obj) { - if (CompressedOops::is_null(obj)) { - return false; - } - obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); - shenandoah_assert_not_forwarded_if(NULL, obj, ShenandoahHeap::heap()->is_concurrent_mark_in_progress() || ShenandoahHeap::heap()->is_concurrent_traversal_in_progress()); - return _mark_context->is_marked(obj); -} - -bool ShenandoahIsAliveClosure::do_object_b(oop obj) { - if (CompressedOops::is_null(obj)) { - return false; - } - shenandoah_assert_not_forwarded(NULL, obj); - return _mark_context->is_marked(obj); -} - void ShenandoahHeap::ref_processing_init() { assert(_max_workers > 0, "Sanity"); @@ -2878,8 +2816,3 @@ ptrdiff_t ShenandoahHeap::cell_header_size() const { return ShenandoahBrooksPointer::byte_size(); } - -BoolObjectClosure* ShenandoahIsAliveSelector::is_alive_closure() { - return ShenandoahHeap::heap()->has_forwarded_objects() ? reinterpret_cast<BoolObjectClosure*>(&_fwd_alive_cl) - : reinterpret_cast<BoolObjectClosure*>(&_alive_cl); -}
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -91,19 +91,6 @@ virtual bool is_thread_safe() { return false; } }; -class ShenandoahUpdateRefsClosure: public OopClosure { -private: - ShenandoahHeap* _heap; - - template <class T> - inline void do_oop_work(T* p); - -public: - ShenandoahUpdateRefsClosure(); - inline void do_oop(oop* p); - inline void do_oop(narrowOop* p); -}; - #ifdef ASSERT class ShenandoahAssertToSpaceClosure : public OopClosure { private: @@ -115,34 +102,6 @@ }; #endif -class ShenandoahAlwaysTrueClosure : public BoolObjectClosure { -public: - bool do_object_b(oop p) { return true; } -}; - -class ShenandoahForwardedIsAliveClosure: public BoolObjectClosure { -private: - ShenandoahMarkingContext* const _mark_context; -public: - ShenandoahForwardedIsAliveClosure(); - bool do_object_b(oop obj); -}; - -class ShenandoahIsAliveClosure: public BoolObjectClosure { -private: - ShenandoahMarkingContext* const _mark_context; -public: - ShenandoahIsAliveClosure(); - bool do_object_b(oop obj); -}; - -class ShenandoahIsAliveSelector : public StackObj { -private: - ShenandoahIsAliveClosure _alive_cl; - ShenandoahForwardedIsAliveClosure _fwd_alive_cl; -public: - BoolObjectClosure* is_alive_closure(); -}; // Shenandoah GC is low-pause concurrent GC that uses Brooks forwarding pointers // to encode forwarding data. See BrooksPointer for details on forwarding data encoding.
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -46,17 +46,6 @@ #include "utilities/copy.hpp" #include "utilities/globalDefinitions.hpp" -template <class T> -void ShenandoahUpdateRefsClosure::do_oop_work(T* p) { - T o = RawAccess<>::oop_load(p); - if (!CompressedOops::is_null(o)) { - oop obj = CompressedOops::decode_not_null(o); - _heap->update_with_forwarded_not_null(p, obj); - } -} - -void ShenandoahUpdateRefsClosure::do_oop(oop* p) { do_oop_work(p); } -void ShenandoahUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); } inline ShenandoahHeapRegion* ShenandoahRegionIterator::next() { size_t new_index = Atomic::add((size_t) 1, &_index);
--- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -51,6 +51,7 @@ f(scan_jfr_weak_roots, " S: JFR Weak Roots") \ f(scan_jni_weak_roots, " S: JNI Weak Roots") \ f(scan_stringtable_roots, " S: String Table Roots") \ + f(scan_resolved_method_table_roots, " S: Resolved Table Roots") \ f(scan_vm_weak_roots, " S: VM Weak Roots") \ f(scan_synchronizer_roots, " S: Synchronizer Roots") \ f(scan_management_roots, " S: Management Roots") \ @@ -76,6 +77,7 @@ f(update_jfr_weak_roots, " U: JFR Weak Roots") \ f(update_jni_weak_roots, " U: JNI Weak Roots") \ f(update_stringtable_roots, " U: String Table Roots") \ + f(update_resolved_method_table_roots, " U: Resolved Table Roots") \ f(update_vm_weak_roots, " U: VM Weak Roots") \ f(update_synchronizer_roots, " U: Synchronizer Roots") \ f(update_management_roots, " U: Management Roots") \ @@ -109,6 +111,7 @@ f(evac_jfr_weak_roots, " E: JFR Weak Roots") \ f(evac_jni_weak_roots, " E: JNI Weak Roots") \ f(evac_stringtable_roots, " E: String Table Roots") \ + f(evac_resolved_method_table_roots, " E: Resolved Table Roots") \ f(evac_vm_weak_roots, " E: VM Weak Roots") \ f(evac_synchronizer_roots, " E: Synchronizer Roots") \ f(evac_management_roots, " E: Management Roots") \ @@ -139,6 +142,7 @@ f(final_update_jfr_weak_roots, " UR: JFR Weak Roots") \ f(final_update_jni_weak_roots, " UR: JNI Weak Roots") \ f(final_update_stringtable_roots, " UR: String Table Roots") \ + f(final_update_resolved_method_table_roots, " UR: Resolved Table Roots") \ f(final_update_vm_weak_roots, " UR: VM Weak Roots") \ f(final_update_refs_synchronizer_roots, " UR: Synchronizer Roots") \ f(final_update_refs_management_roots, " UR: Management Roots") \ @@ -164,6 +168,7 @@ f(degen_gc_update_jfr_weak_roots, " DU: JFR Weak Roots") \ f(degen_gc_update_jni_weak_roots, " DU: JNI Weak Roots") \ f(degen_gc_update_stringtable_roots, " DU: String Table Roots") \ + f(degen_gc_update_resolved_method_table_roots, " DU: Resolved Table Roots") \ f(degen_gc_update_vm_weak_roots, " DU: VM Weak Roots") \ f(degen_gc_update_synchronizer_roots, " DU: Synchronizer Roots") \ f(degen_gc_update_management_roots, " DU: Management Roots") \ @@ -190,6 +195,7 @@ f(init_traversal_gc_jfr_weak_roots, " TI: JFR Weak Roots") \ f(init_traversal_gc_jni_weak_roots, " TI: JNI Weak Roots") \ f(init_traversal_gc_stringtable_roots, " TI: String Table Roots") \ + f(init_traversal_gc_resolved_method_table_roots, " TI: Resolved Table Roots") \ f(init_traversal_gc_vm_weak_roots, " TI: VM Weak Roots") \ f(init_traversal_gc_synchronizer_roots, " TI: Synchronizer Roots") \ f(init_traversal_gc_management_roots, " TI: Management Roots") \ @@ -213,6 +219,7 @@ f(final_traversal_gc_jfr_weak_roots, " TF: JFR Weak Roots") \ f(final_traversal_gc_jni_weak_roots, " TF: JNI Weak Roots") \ f(final_traversal_gc_stringtable_roots, " TF: String Table Roots") \ + f(final_traversal_gc_resolved_method_table_roots, " TF: Resolved Table Roots") \ f(final_traversal_gc_vm_weak_roots, " TF: VM Weak Roots") \ f(final_traversal_gc_synchronizer_roots, " TF: Synchronizer Roots") \ f(final_traversal_gc_management_roots, " TF: Management Roots") \ @@ -225,24 +232,25 @@ f(final_traversal_gc_termination, " TF: Termination") \ \ /* Per-thread timer block, should have "roots" counters in consistent order */ \ - f(final_traversal_update_roots, " Update Roots") \ - f(final_traversal_update_thread_roots, " TU: Thread Roots") \ - f(final_traversal_update_code_roots, " TU: Code Cache Roots") \ - f(final_traversal_update_universe_roots, " TU: Universe Roots") \ - f(final_traversal_update_jni_roots, " TU: JNI Roots") \ - f(final_traversal_update_jvmti_weak_roots, " TU: JVMTI Weak Roots") \ - f(final_traversal_update_jfr_weak_roots, " TU: JFR Weak Roots") \ - f(final_traversal_update_jni_weak_roots, " TU: JNI Weak Roots") \ - f(final_traversal_update_stringtable_roots, " TU: String Table Roots") \ - f(final_traversal_update_vm_weak_roots, " TU: VM Weak Roots") \ - f(final_traversal_update_synchronizer_roots, " TU: Synchronizer Roots") \ - f(final_traversal_update_management_roots, " TU: Management Roots") \ - f(final_traversal_update_system_dict_roots, " TU: System Dict Roots") \ - f(final_traversal_update_cldg_roots, " TU: CLDG Roots") \ - f(final_traversal_update_jvmti_roots, " TU: JVMTI Roots") \ - f(final_traversal_update_string_dedup_table_roots, " TU: Dedup Table Roots") \ - f(final_traversal_update_string_dedup_queue_roots, " TU: Dedup Queue Roots") \ - f(final_traversal_update_finish_queues, " TU: Finish Queues") \ + f(final_traversal_update_roots, " Update Roots") \ + f(final_traversal_update_thread_roots, " TU: Thread Roots") \ + f(final_traversal_update_code_roots, " TU: Code Cache Roots") \ + f(final_traversal_update_universe_roots, " TU: Universe Roots") \ + f(final_traversal_update_jni_roots, " TU: JNI Roots") \ + f(final_traversal_update_jvmti_weak_roots, " TU: JVMTI Weak Roots") \ + f(final_traversal_update_jfr_weak_roots, " TU: JFR Weak Roots") \ + f(final_traversal_update_jni_weak_roots, " TU: JNI Weak Roots") \ + f(final_traversal_update_stringtable_roots, " TU: String Table Roots") \ + f(final_traversal_update_resolved_method_table_roots, " TU: Resolved Table Roots") \ + f(final_traversal_update_vm_weak_roots, " TU: VM Weak Roots") \ + f(final_traversal_update_synchronizer_roots, " TU: Synchronizer Roots") \ + f(final_traversal_update_management_roots, " TU: Management Roots") \ + f(final_traversal_update_system_dict_roots, " TU: System Dict Roots") \ + f(final_traversal_update_cldg_roots, " TU: CLDG Roots") \ + f(final_traversal_update_jvmti_roots, " TU: JVMTI Roots") \ + f(final_traversal_update_string_dedup_table_roots, " TU: Dedup Table Roots") \ + f(final_traversal_update_string_dedup_queue_roots, " TU: Dedup Queue Roots") \ + f(final_traversal_update_finish_queues, " TU: Finish Queues") \ \ f(traversal_gc_cleanup, " Cleanup") \ \ @@ -261,6 +269,7 @@ f(full_gc_jfr_weak_roots, " F: JFR Weak Roots") \ f(full_gc_jni_weak_roots, " F: JNI Weak Roots") \ f(full_gc_stringtable_roots, " F: String Table Roots") \ + f(full_gc_resolved_method_table_roots, " F: Resolved Table Roots") \ f(full_gc_vm_weak_roots, " F: VM Weak Roots") \ f(full_gc_synchronizer_roots, " F: Synchronizer Roots") \ f(full_gc_management_roots, " F: Management Roots") \ @@ -311,23 +320,24 @@ // end #define SHENANDOAH_GC_PAR_PHASE_DO(f) \ - f(ThreadRoots, "Thread Roots (ms):") \ - f(CodeCacheRoots, "CodeCache Roots (ms):") \ - f(UniverseRoots, "Universe Roots (ms):") \ - f(JNIRoots, "JNI Handles Roots (ms):") \ - f(JVMTIWeakRoots, "JVMTI Weak Roots (ms):") \ - f(JFRWeakRoots, "JFR Weak Roots (ms):") \ - f(JNIWeakRoots, "JNI Weak Roots (ms):") \ - f(StringTableRoots, "StringTable Roots(ms):") \ - f(VMWeakRoots, "VM Weak Roots(ms)") \ - f(ObjectSynchronizerRoots, "ObjectSynchronizer Roots (ms):") \ - f(ManagementRoots, "Management Roots (ms):") \ - f(SystemDictionaryRoots, "SystemDictionary Roots (ms):") \ - f(CLDGRoots, "CLDG Roots (ms):") \ - f(JVMTIRoots, "JVMTI Roots (ms):") \ - f(StringDedupTableRoots, "String Dedup Table Roots (ms):") \ - f(StringDedupQueueRoots, "String Dedup Queue Roots (ms):") \ - f(FinishQueues, "Finish Queues (ms):") \ + f(ThreadRoots, "Thread Roots (ms):") \ + f(CodeCacheRoots, "CodeCache Roots (ms):") \ + f(UniverseRoots, "Universe Roots (ms):") \ + f(JNIRoots, "JNI Handles Roots (ms):") \ + f(JVMTIWeakRoots, "JVMTI Weak Roots (ms):") \ + f(JFRWeakRoots, "JFR Weak Roots (ms):") \ + f(JNIWeakRoots, "JNI Weak Roots (ms):") \ + f(StringTableRoots, "StringTable Roots(ms):") \ + f(ResolvedMethodTableRoots, "Resolved Table Roots(ms):") \ + f(VMWeakRoots, "VM Weak Roots(ms)") \ + f(ObjectSynchronizerRoots, "ObjectSynchronizer Roots (ms):") \ + f(ManagementRoots, "Management Roots (ms):") \ + f(SystemDictionaryRoots, "SystemDictionary Roots (ms):") \ + f(CLDGRoots, "CLDG Roots (ms):") \ + f(JVMTIRoots, "JVMTI Roots (ms):") \ + f(StringDedupTableRoots, "String Dedup Table Roots (ms):") \ + f(StringDedupQueueRoots, "String Dedup Queue Roots (ms):") \ + f(FinishQueues, "Finish Queues (ms):") \ // end class ShenandoahPhaseTimings : public CHeapObj<mtGC> {
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -27,6 +27,7 @@ #include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" +#include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahRootProcessor.hpp" #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" @@ -48,14 +49,15 @@ static const struct PhaseMap phase_mapping[] = { #if INCLUDE_JVMTI - {WeakProcessorPhases::jvmti, ShenandoahPhaseTimings::JVMTIWeakRoots}, + {WeakProcessorPhases::jvmti, ShenandoahPhaseTimings::JVMTIWeakRoots}, #endif #if INCLUDE_JFR - {WeakProcessorPhases::jfr, ShenandoahPhaseTimings::JFRWeakRoots}, + {WeakProcessorPhases::jfr, ShenandoahPhaseTimings::JFRWeakRoots}, #endif - {WeakProcessorPhases::jni, ShenandoahPhaseTimings::JNIWeakRoots}, - {WeakProcessorPhases::stringtable, ShenandoahPhaseTimings::StringTableRoots}, - {WeakProcessorPhases::vm, ShenandoahPhaseTimings::VMWeakRoots} + {WeakProcessorPhases::jni, ShenandoahPhaseTimings::JNIWeakRoots}, + {WeakProcessorPhases::stringtable, ShenandoahPhaseTimings::StringTableRoots}, + {WeakProcessorPhases::resolved_method_table, ShenandoahPhaseTimings::ResolvedMethodTableRoots}, + {WeakProcessorPhases::vm, ShenandoahPhaseTimings::VMWeakRoots} }; STATIC_ASSERT(sizeof(phase_mapping) / sizeof(PhaseMap) == WeakProcessorPhases::phase_count); @@ -64,7 +66,6 @@ ShenandoahPhaseTimings::Phase phase) : _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)), _srs(n_workers), - _par_state_string(StringTable::weak_storage()), _phase(phase), _coderoots_all_iterator(ShenandoahCodeRoots::iterator()), _weak_processor_timings(n_workers), @@ -242,10 +243,7 @@ _evacuation_tasks(new SubTasksDone(SHENANDOAH_EVAC_NumElements)), _srs(n_workers), _phase(phase), - _coderoots_cset_iterator(ShenandoahCodeRoots::cset_iterator()), - _par_state_string(StringTable::weak_storage()) - -{ + _coderoots_cset_iterator(ShenandoahCodeRoots::cset_iterator()) { heap->phase_timings()->record_workers_start(_phase); if (ShenandoahStringDedup::is_enabled()) { StringDedup::gc_prologue(false);
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -56,7 +56,6 @@ class ShenandoahRootProcessor : public StackObj { SubTasksDone* _process_strong_tasks; StrongRootsScope _srs; - OopStorage::ParState<false, false> _par_state_string; ShenandoahPhaseTimings::Phase _phase; ParallelCLDRootIterator _cld_iterator; ShenandoahAllCodeRootsIterator _coderoots_all_iterator; @@ -120,7 +119,6 @@ StrongRootsScope _srs; ShenandoahPhaseTimings::Phase _phase; ShenandoahCsetCodeRootsIterator _coderoots_cset_iterator; - OopStorage::ParState<false, false> _par_state_string; enum Shenandoah_evacuate_roots_tasks { SHENANDOAH_EVAC_Universe_oops_do,
--- a/src/hotspot/share/gc/shenandoah/shenandoahStringDedup.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahStringDedup.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -92,7 +92,7 @@ void ShenandoahStringDedup::oops_do_slow(OopClosure* cl) { assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); assert(is_enabled(), "String deduplication not enabled"); - ShenandoahAlwaysTrueClosure always_true; + AlwaysTrueClosure always_true; StringDedupUnlinkOrOopsDoClosure sd_cl(&always_true, cl); StringDedupQueue::unlink_or_oops_do(&sd_cl); StringDedupTable::unlink_or_oops_do(&sd_cl, 0);
--- a/src/hotspot/share/gc/shenandoah/shenandoahTimingTracker.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahTimingTracker.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -76,8 +76,11 @@ phase == ShenandoahPhaseTimings::full_gc_weakrefs_termination, "Only these phases"); - assert(Thread::current()->is_VM_thread() || Thread::current()->is_ConcurrentGC_thread(), - "Called from wrong thread"); + assert(!Thread::current()->is_Worker_thread() && + (Thread::current()->is_VM_thread() || + Thread::current()->is_ConcurrentGC_thread()), + "Called from wrong thread"); + _current_termination_phase = phase; ShenandoahHeap::heap()->phase_timings()->termination_times()->reset(); }
--- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -30,6 +30,7 @@ #include "gc/shared/workgroup.hpp" #include "gc/shared/weakProcessor.inline.hpp" #include "gc/shenandoah/shenandoahBarrierSet.hpp" +#include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahCodeRoots.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
--- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -100,9 +100,10 @@ ShenandoahGCPhase::ShenandoahGCPhase(const ShenandoahPhaseTimings::Phase phase) : _heap(ShenandoahHeap::heap()), _phase(phase) { - assert(Thread::current()->is_VM_thread() || - Thread::current()->is_ConcurrentGC_thread(), - "Must be set by these threads"); + assert(!Thread::current()->is_Worker_thread() && + (Thread::current()->is_VM_thread() || + Thread::current()->is_ConcurrentGC_thread()), + "Must be set by these threads"); _parent_phase = _current_phase; _current_phase = phase;
--- a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -55,11 +55,7 @@ // Heal oops and disarm ZNMethodOopClosure cl; - nm->oops_do(&cl); - nm->fix_oop_relocations(); - - OrderAccess::release(); - + ZNMethod::nmethod_oops_do(nm, &cl); disarm(nm); return true;
--- a/src/hotspot/share/gc/z/zRootsIterator.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/z/zRootsIterator.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -41,6 +41,7 @@ #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "prims/jvmtiExport.hpp" +#include "prims/resolvedMethodTable.hpp" #include "runtime/atomic.hpp" #include "runtime/jniHandles.hpp" #include "runtime/thread.hpp" @@ -80,6 +81,7 @@ static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsVMWeakHandles("Concurrent Weak Roots VMWeakHandles"); static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsJNIWeakHandles("Concurrent Weak Roots JNIWeakHandles"); static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsStringTable("Concurrent Weak Roots StringTable"); +static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsResolvedMethodTable("Concurrent Weak Roots ResolvedMethodTable"); template <typename T, void (T::*F)(ZRootsIteratorClosure*)> ZSerialOopsDo<T, F>::ZSerialOopsDo(T* iter) : @@ -341,14 +343,18 @@ _vm_weak_handles_iter(SystemDictionary::vm_weak_oop_storage()), _jni_weak_handles_iter(JNIHandles::weak_global_handles()), _string_table_iter(StringTable::weak_storage()), + _resolved_method_table_iter(ResolvedMethodTable::weak_storage()), _vm_weak_handles(this), _jni_weak_handles(this), - _string_table(this) { + _string_table(this), + _resolved_method_table(this) { StringTable::reset_dead_counter(); + ResolvedMethodTable::reset_dead_counter(); } ZConcurrentWeakRootsIterator::~ZConcurrentWeakRootsIterator() { StringTable::finish_dead_counter(); + ResolvedMethodTable::finish_dead_counter(); } void ZConcurrentWeakRootsIterator::do_vm_weak_handles(ZRootsIteratorClosure* cl) { @@ -361,18 +367,19 @@ _jni_weak_handles_iter.oops_do(cl); } -class ZStringTableDeadCounterClosure : public ZRootsIteratorClosure { +template <class Container> +class ZDeadCounterClosure : public ZRootsIteratorClosure { private: ZRootsIteratorClosure* const _cl; size_t _ndead; public: - ZStringTableDeadCounterClosure(ZRootsIteratorClosure* cl) : + ZDeadCounterClosure(ZRootsIteratorClosure* cl) : _cl(cl), _ndead(0) {} - ~ZStringTableDeadCounterClosure() { - StringTable::inc_dead_counter(_ndead); + ~ZDeadCounterClosure() { + Container::inc_dead_counter(_ndead); } virtual void do_oop(oop* p) { @@ -389,15 +396,22 @@ void ZConcurrentWeakRootsIterator::do_string_table(ZRootsIteratorClosure* cl) { ZStatTimer timer(ZSubPhaseConcurrentWeakRootsStringTable); - ZStringTableDeadCounterClosure counter_cl(cl); + ZDeadCounterClosure<StringTable> counter_cl(cl); _string_table_iter.oops_do(&counter_cl); } +void ZConcurrentWeakRootsIterator::do_resolved_method_table(ZRootsIteratorClosure* cl) { + ZStatTimer timer(ZSubPhaseConcurrentWeakRootsResolvedMethodTable); + ZDeadCounterClosure<ResolvedMethodTable> counter_cl(cl); + _resolved_method_table_iter.oops_do(&counter_cl); +} + void ZConcurrentWeakRootsIterator::oops_do(ZRootsIteratorClosure* cl) { ZStatTimer timer(ZSubPhaseConcurrentWeakRoots); _vm_weak_handles.oops_do(cl); _jni_weak_handles.oops_do(cl); _string_table.oops_do(cl); + _resolved_method_table.oops_do(cl); } ZThreadRootsIterator::ZThreadRootsIterator() :
--- a/src/hotspot/share/gc/z/zRootsIterator.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/z/zRootsIterator.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -149,14 +149,17 @@ ZOopStorageIterator _vm_weak_handles_iter; ZOopStorageIterator _jni_weak_handles_iter; ZOopStorageIterator _string_table_iter; + ZOopStorageIterator _resolved_method_table_iter; void do_vm_weak_handles(ZRootsIteratorClosure* cl); void do_jni_weak_handles(ZRootsIteratorClosure* cl); void do_string_table(ZRootsIteratorClosure* cl); + void do_resolved_method_table(ZRootsIteratorClosure* cl); - ZParallelOopsDo<ZConcurrentWeakRootsIterator, &ZConcurrentWeakRootsIterator::do_vm_weak_handles> _vm_weak_handles; - ZParallelOopsDo<ZConcurrentWeakRootsIterator, &ZConcurrentWeakRootsIterator::do_jni_weak_handles> _jni_weak_handles; - ZParallelOopsDo<ZConcurrentWeakRootsIterator, &ZConcurrentWeakRootsIterator::do_string_table> _string_table; + ZParallelOopsDo<ZConcurrentWeakRootsIterator, &ZConcurrentWeakRootsIterator::do_vm_weak_handles> _vm_weak_handles; + ZParallelOopsDo<ZConcurrentWeakRootsIterator, &ZConcurrentWeakRootsIterator::do_jni_weak_handles> _jni_weak_handles; + ZParallelOopsDo<ZConcurrentWeakRootsIterator, &ZConcurrentWeakRootsIterator::do_string_table> _string_table; + ZParallelOopsDo<ZConcurrentWeakRootsIterator, &ZConcurrentWeakRootsIterator::do_resolved_method_table> _resolved_method_table; public: ZConcurrentWeakRootsIterator();
--- a/src/hotspot/share/gc/z/zUnload.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/gc/z/zUnload.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -71,7 +71,7 @@ ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm); ZLocker<ZReentrantLock> locker(lock); ZIsUnloadingOopClosure cl; - nm->oops_do(&cl, true /* allow_zombie */); + ZNMethod::nmethod_oops_do(nm, &cl); return cl.is_unloading(); } };
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -156,7 +156,7 @@ // Constants -IRT_ENTRY(void, InterpreterRuntime::ldc(JavaThread* thread, bool wide)) +JRT_ENTRY(void, InterpreterRuntime::ldc(JavaThread* thread, bool wide)) // access constant pool LastFrameAccessor last_frame(thread); ConstantPool* pool = last_frame.method()->constants(); @@ -167,9 +167,9 @@ Klass* klass = pool->klass_at(index, CHECK); oop java_class = klass->java_mirror(); thread->set_vm_result(java_class); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* thread, Bytecodes::Code bytecode)) { +JRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* thread, Bytecodes::Code bytecode)) { assert(bytecode == Bytecodes::_ldc || bytecode == Bytecodes::_ldc_w || bytecode == Bytecodes::_ldc2_w || @@ -219,13 +219,13 @@ thread->set_vm_result_2((Metadata*)flags); } } -IRT_END +JRT_END //------------------------------------------------------------------------------------------------------------------------ // Allocation -IRT_ENTRY(void, InterpreterRuntime::_new(JavaThread* thread, ConstantPool* pool, int index)) +JRT_ENTRY(void, InterpreterRuntime::_new(JavaThread* thread, ConstantPool* pool, int index)) Klass* k = pool->klass_at(index, CHECK); InstanceKlass* klass = InstanceKlass::cast(k); @@ -251,23 +251,23 @@ // because the _breakpoint bytecode would be lost. oop obj = klass->allocate_instance(CHECK); thread->set_vm_result(obj); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size)) +JRT_ENTRY(void, InterpreterRuntime::newarray(JavaThread* thread, BasicType type, jint size)) oop obj = oopFactory::new_typeArray(type, size, CHECK); thread->set_vm_result(obj); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size)) +JRT_ENTRY(void, InterpreterRuntime::anewarray(JavaThread* thread, ConstantPool* pool, int index, jint size)) Klass* klass = pool->klass_at(index, CHECK); objArrayOop obj = oopFactory::new_objArray(klass, size, CHECK); thread->set_vm_result(obj); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address)) +JRT_ENTRY(void, InterpreterRuntime::multianewarray(JavaThread* thread, jint* first_size_address)) // We may want to pass in more arguments - could make this slightly faster LastFrameAccessor last_frame(thread); ConstantPool* constants = last_frame.method()->constants(); @@ -292,18 +292,18 @@ } oop obj = ArrayKlass::cast(klass)->multi_allocate(nof_dims, dims, CHECK); thread->set_vm_result(obj); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::register_finalizer(JavaThread* thread, oopDesc* obj)) +JRT_ENTRY(void, InterpreterRuntime::register_finalizer(JavaThread* thread, oopDesc* obj)) assert(oopDesc::is_oop(obj), "must be a valid oop"); assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise"); InstanceKlass::register_finalizer(instanceOop(obj), CHECK); -IRT_END +JRT_END // Quicken instance-of and check-cast bytecodes -IRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* thread)) +JRT_ENTRY(void, InterpreterRuntime::quicken_io_cc(JavaThread* thread)) // Force resolving; quicken the bytecode LastFrameAccessor last_frame(thread); int which = last_frame.get_index_u2(Bytecodes::_checkcast); @@ -314,7 +314,7 @@ // assert( cpool->tag_at(which).is_unresolved_klass(), "should only come here to quicken bytecodes" ); Klass* klass = cpool->klass_at(which, CHECK); thread->set_vm_result_2(klass); -IRT_END +JRT_END //------------------------------------------------------------------------------------------------------------------------ @@ -354,10 +354,10 @@ #ifdef CC_INTERP // As legacy note_trap, but we have more arguments. -IRT_ENTRY(void, InterpreterRuntime::note_trap(JavaThread* thread, int reason, Method *method, int trap_bci)) +JRT_ENTRY(void, InterpreterRuntime::note_trap(JavaThread* thread, int reason, Method *method, int trap_bci)) methodHandle trap_method(method); note_trap_inner(thread, reason, trap_method, trap_bci, THREAD); -IRT_END +JRT_END // Class Deoptimization is not visible in BytecodeInterpreter, so we need a wrapper // for each exception. @@ -394,16 +394,16 @@ // space left we use the pre-allocated & pre-initialized StackOverflowError // klass to create an stack overflow error instance. We do not call its // constructor for the same reason (it is empty, anyway). -IRT_ENTRY(void, InterpreterRuntime::throw_StackOverflowError(JavaThread* thread)) +JRT_ENTRY(void, InterpreterRuntime::throw_StackOverflowError(JavaThread* thread)) Handle exception = get_preinitialized_exception( SystemDictionary::StackOverflowError_klass(), CHECK); // Increment counter for hs_err file reporting Atomic::inc(&Exceptions::_stack_overflow_errors); THROW_HANDLE(exception); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::throw_delayed_StackOverflowError(JavaThread* thread)) +JRT_ENTRY(void, InterpreterRuntime::throw_delayed_StackOverflowError(JavaThread* thread)) Handle exception = get_preinitialized_exception( SystemDictionary::StackOverflowError_klass(), CHECK); @@ -412,9 +412,9 @@ // Increment counter for hs_err file reporting Atomic::inc(&Exceptions::_stack_overflow_errors); THROW_HANDLE(exception); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::create_exception(JavaThread* thread, char* name, char* message)) +JRT_ENTRY(void, InterpreterRuntime::create_exception(JavaThread* thread, char* name, char* message)) // lookup exception klass TempNewSymbol s = SymbolTable::new_symbol(name, CHECK); if (ProfileTraps) { @@ -427,10 +427,10 @@ // create exception Handle exception = Exceptions::new_exception(thread, s, message); thread->set_vm_result(exception()); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::create_klass_exception(JavaThread* thread, char* name, oopDesc* obj)) +JRT_ENTRY(void, InterpreterRuntime::create_klass_exception(JavaThread* thread, char* name, oopDesc* obj)) // Produce the error message first because note_trap can safepoint ResourceMark rm(thread); const char* klass_name = obj->klass()->external_name(); @@ -442,9 +442,9 @@ // create exception, with klass name as detail message Handle exception = Exceptions::new_exception(thread, s, klass_name); thread->set_vm_result(exception()); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException(JavaThread* thread, arrayOopDesc* a, jint index)) +JRT_ENTRY(void, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException(JavaThread* thread, arrayOopDesc* a, jint index)) // Produce the error message first because note_trap can safepoint ResourceMark rm(thread); stringStream ss; @@ -455,9 +455,9 @@ } THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), ss.as_string()); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::throw_ClassCastException( +JRT_ENTRY(void, InterpreterRuntime::throw_ClassCastException( JavaThread* thread, oopDesc* obj)) // Produce the error message first because note_trap can safepoint @@ -471,7 +471,7 @@ // create exception THROW_MSG(vmSymbols::java_lang_ClassCastException(), message); -IRT_END +JRT_END // exception_handler_for_exception(...) returns the continuation address, // the exception oop (via TLS) and sets the bci/bcp for the continuation. @@ -481,7 +481,7 @@ // bci where the exception happened. If the exception was propagated back // from a call, the expression stack contains the values for the bci at the // invoke w/o arguments (i.e., as if one were inside the call). -IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception)) +JRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThread* thread, oopDesc* exception)) LastFrameAccessor last_frame(thread); Handle h_exception(thread, exception); @@ -622,18 +622,18 @@ thread->set_vm_result(h_exception()); return continuation; -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::throw_pending_exception(JavaThread* thread)) +JRT_ENTRY(void, InterpreterRuntime::throw_pending_exception(JavaThread* thread)) assert(thread->has_pending_exception(), "must only ne called if there's an exception pending"); // nothing to do - eventually we should remove this code entirely (see comments @ call sites) -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::throw_AbstractMethodError(JavaThread* thread)) +JRT_ENTRY(void, InterpreterRuntime::throw_AbstractMethodError(JavaThread* thread)) THROW(vmSymbols::java_lang_AbstractMethodError()); -IRT_END +JRT_END // This method is called from the "abstract_entry" of the interpreter. // At that point, the arguments have already been removed from the stack @@ -641,28 +641,28 @@ // on some platforms the receiver still resides in a register...). Thus, // we have no choice but print an error message not containing the receiver // type. -IRT_ENTRY(void, InterpreterRuntime::throw_AbstractMethodErrorWithMethod(JavaThread* thread, +JRT_ENTRY(void, InterpreterRuntime::throw_AbstractMethodErrorWithMethod(JavaThread* thread, Method* missingMethod)) ResourceMark rm(thread); assert(missingMethod != NULL, "sanity"); methodHandle m(thread, missingMethod); LinkResolver::throw_abstract_method_error(m, THREAD); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::throw_AbstractMethodErrorVerbose(JavaThread* thread, +JRT_ENTRY(void, InterpreterRuntime::throw_AbstractMethodErrorVerbose(JavaThread* thread, Klass* recvKlass, Method* missingMethod)) ResourceMark rm(thread); methodHandle mh = methodHandle(thread, missingMethod); LinkResolver::throw_abstract_method_error(mh, recvKlass, THREAD); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::throw_IncompatibleClassChangeError(JavaThread* thread)) +JRT_ENTRY(void, InterpreterRuntime::throw_IncompatibleClassChangeError(JavaThread* thread)) THROW(vmSymbols::java_lang_IncompatibleClassChangeError()); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose(JavaThread* thread, +JRT_ENTRY(void, InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose(JavaThread* thread, Klass* recvKlass, Klass* interfaceKlass)) ResourceMark rm(thread); @@ -673,7 +673,7 @@ recvKlass ? recvKlass->external_name() : "NULL", interfaceKlass ? interfaceKlass->external_name() : "NULL"); THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); -IRT_END +JRT_END //------------------------------------------------------------------------------------------------------------------------ // Fields @@ -760,7 +760,7 @@ //%note synchronization_3 //%note monitor_1 -IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem)) +JRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem)) #ifdef ASSERT thread->last_frame().interpreter_frame_verify_monitor(elem); #endif @@ -781,11 +781,11 @@ #ifdef ASSERT thread->last_frame().interpreter_frame_verify_monitor(elem); #endif -IRT_END +JRT_END //%note monitor_1 -IRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorexit(JavaThread* thread, BasicObjectLock* elem)) +JRT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorexit(JavaThread* thread, BasicObjectLock* elem)) #ifdef ASSERT thread->last_frame().interpreter_frame_verify_monitor(elem); #endif @@ -802,15 +802,15 @@ #ifdef ASSERT thread->last_frame().interpreter_frame_verify_monitor(elem); #endif -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::throw_illegal_monitor_state_exception(JavaThread* thread)) +JRT_ENTRY(void, InterpreterRuntime::throw_illegal_monitor_state_exception(JavaThread* thread)) THROW(vmSymbols::java_lang_IllegalMonitorStateException()); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::new_illegal_monitor_state_exception(JavaThread* thread)) +JRT_ENTRY(void, InterpreterRuntime::new_illegal_monitor_state_exception(JavaThread* thread)) // Returns an illegal exception to install into the current thread. The // pending_exception flag is cleared so normal exception handling does not // trigger. Any current installed exception will be overwritten. This @@ -826,23 +826,23 @@ CATCH); } thread->set_vm_result(exception()); -IRT_END +JRT_END //------------------------------------------------------------------------------------------------------------------------ // Invokes -IRT_ENTRY(Bytecodes::Code, InterpreterRuntime::get_original_bytecode_at(JavaThread* thread, Method* method, address bcp)) +JRT_ENTRY(Bytecodes::Code, InterpreterRuntime::get_original_bytecode_at(JavaThread* thread, Method* method, address bcp)) return method->orig_bytecode_at(method->bci_from(bcp)); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::set_original_bytecode_at(JavaThread* thread, Method* method, address bcp, Bytecodes::Code new_code)) +JRT_ENTRY(void, InterpreterRuntime::set_original_bytecode_at(JavaThread* thread, Method* method, address bcp, Bytecodes::Code new_code)) method->set_orig_bytecode_at(method->bci_from(bcp), new_code); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::_breakpoint(JavaThread* thread, Method* method, address bcp)) +JRT_ENTRY(void, InterpreterRuntime::_breakpoint(JavaThread* thread, Method* method, address bcp)) JvmtiExport::post_raw_breakpoint(thread, method, bcp); -IRT_END +JRT_END void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode) { Thread* THREAD = thread; @@ -998,7 +998,7 @@ // This function is the interface to the assembly code. It returns the resolved // cpCache entry. This doesn't safepoint, but the helper routines safepoint. // This function will check for redefinition! -IRT_ENTRY(void, InterpreterRuntime::resolve_from_cache(JavaThread* thread, Bytecodes::Code bytecode)) { +JRT_ENTRY(void, InterpreterRuntime::resolve_from_cache(JavaThread* thread, Bytecodes::Code bytecode)) { switch (bytecode) { case Bytecodes::_getstatic: case Bytecodes::_putstatic: @@ -1023,7 +1023,7 @@ break; } } -IRT_END +JRT_END //------------------------------------------------------------------------------------------------------------------------ // Miscellaneous @@ -1069,7 +1069,7 @@ return nm; } -IRT_ENTRY(nmethod*, +JRT_ENTRY(nmethod*, InterpreterRuntime::frequency_counter_overflow_inner(JavaThread* thread, address branch_bcp)) // use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized // flag, in case this method triggers classloading which will call into Java. @@ -1113,17 +1113,17 @@ } } return osr_nm; -IRT_END +JRT_END -IRT_LEAF(jint, InterpreterRuntime::bcp_to_di(Method* method, address cur_bcp)) +JRT_LEAF(jint, InterpreterRuntime::bcp_to_di(Method* method, address cur_bcp)) assert(ProfileInterpreter, "must be profiling interpreter"); int bci = method->bci_from(cur_bcp); MethodData* mdo = method->method_data(); if (mdo == NULL) return 0; return mdo->bci_to_di(bci); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::profile_method(JavaThread* thread)) +JRT_ENTRY(void, InterpreterRuntime::profile_method(JavaThread* thread)) // use UnlockFlagSaver to clear and restore the _do_not_unlock_if_synchronized // flag, in case this method triggers classloading which will call into Java. UnlockFlagSaver fs(thread); @@ -1138,11 +1138,11 @@ CLEAR_PENDING_EXCEPTION; // and fall through... } -IRT_END +JRT_END #ifdef ASSERT -IRT_LEAF(void, InterpreterRuntime::verify_mdp(Method* method, address bcp, address mdp)) +JRT_LEAF(void, InterpreterRuntime::verify_mdp(Method* method, address bcp, address mdp)) assert(ProfileInterpreter, "must be profiling interpreter"); MethodData* mdo = method->method_data(); @@ -1169,10 +1169,10 @@ method->print_codes(); } assert(mdp == mdp2, "wrong mdp"); -IRT_END +JRT_END #endif // ASSERT -IRT_ENTRY(void, InterpreterRuntime::update_mdp_for_ret(JavaThread* thread, int return_bci)) +JRT_ENTRY(void, InterpreterRuntime::update_mdp_for_ret(JavaThread* thread, int return_bci)) assert(ProfileInterpreter, "must be profiling interpreter"); ResourceMark rm(thread); HandleMark hm(thread); @@ -1191,24 +1191,24 @@ RetData* rdata = data->as_RetData(); address new_mdp = rdata->fixup_ret(return_bci, h_mdo); last_frame.set_mdp(new_mdp); -IRT_END +JRT_END -IRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m)) +JRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m)) MethodCounters* mcs = Method::build_method_counters(m, thread); if (HAS_PENDING_EXCEPTION) { assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); CLEAR_PENDING_EXCEPTION; } return mcs; -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::at_safepoint(JavaThread* thread)) +JRT_ENTRY(void, InterpreterRuntime::at_safepoint(JavaThread* thread)) // We used to need an explict preserve_arguments here for invoke bytecodes. However, // stack traversal automatically takes care of preserving arguments for invoke, so // this is no longer needed. - // IRT_END does an implicit safepoint check, hence we are guaranteed to block + // JRT_END does an implicit safepoint check, hence we are guaranteed to block // if this is called during a safepoint if (JvmtiExport::should_post_single_step()) { @@ -1218,9 +1218,9 @@ LastFrameAccessor last_frame(thread); JvmtiExport::at_single_stepping_point(thread, last_frame.method(), last_frame.bcp()); } -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread *thread, oopDesc* obj, +JRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread *thread, oopDesc* obj, ConstantPoolCacheEntry *cp_entry)) // check the access_flags for the field in the klass @@ -1241,9 +1241,9 @@ jfieldID fid = jfieldIDWorkaround::to_jfieldID(cp_entry_f1, cp_entry->f2_as_index(), is_static); LastFrameAccessor last_frame(thread); JvmtiExport::post_field_access(thread, last_frame.method(), last_frame.bcp(), cp_entry_f1, h_obj, fid); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread, +JRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread, oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value)) Klass* k = cp_entry->f1_as_klass(); @@ -1298,24 +1298,24 @@ LastFrameAccessor last_frame(thread); JvmtiExport::post_raw_field_modification(thread, last_frame.method(), last_frame.bcp(), ik, h_obj, fid, sig_type, &fvalue); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::post_method_entry(JavaThread *thread)) +JRT_ENTRY(void, InterpreterRuntime::post_method_entry(JavaThread *thread)) LastFrameAccessor last_frame(thread); JvmtiExport::post_method_entry(thread, last_frame.method(), last_frame.get_frame()); -IRT_END +JRT_END -IRT_ENTRY(void, InterpreterRuntime::post_method_exit(JavaThread *thread)) +JRT_ENTRY(void, InterpreterRuntime::post_method_exit(JavaThread *thread)) LastFrameAccessor last_frame(thread); JvmtiExport::post_method_exit(thread, last_frame.method(), last_frame.get_frame()); -IRT_END +JRT_END -IRT_LEAF(int, InterpreterRuntime::interpreter_contains(address pc)) +JRT_LEAF(int, InterpreterRuntime::interpreter_contains(address pc)) { return (Interpreter::contains(pc) ? 1 : 0); } -IRT_END +JRT_END // Implementation of SignatureHandlerLibrary @@ -1508,7 +1508,7 @@ address SignatureHandlerLibrary::_buffer = NULL; -IRT_ENTRY(void, InterpreterRuntime::prepare_native_call(JavaThread* thread, Method* method)) +JRT_ENTRY(void, InterpreterRuntime::prepare_native_call(JavaThread* thread, Method* method)) methodHandle m(thread, method); assert(m->is_native(), "sanity check"); // lookup native function entry point if it doesn't exist @@ -1522,10 +1522,10 @@ // before trying to fetch the native entry point and klass mirror. // We must set the signature handler last, so that multiple processors // preparing the same method will be sure to see non-null entry & mirror. -IRT_END +JRT_END #if defined(IA32) || defined(AMD64) || defined(ARM) -IRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* thread, void* src_address, void* dest_address)) +JRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* thread, void* src_address, void* dest_address)) if (src_address == dest_address) { return; } @@ -1541,7 +1541,7 @@ int size_of_arguments = (asc.size() + (invoke.has_receiver() ? 1 : 0)); // receiver Copy::conjoint_jbytes(src_address, dest_address, size_of_arguments * Interpreter::stackElementSize); -IRT_END +JRT_END #endif #if INCLUDE_JVMTI @@ -1551,7 +1551,7 @@ // The member_name argument is a saved reference (in local#0) to the member_name. // For backward compatibility with some JDK versions (7, 8) it can also be a direct method handle. // FIXME: remove DMH case after j.l.i.InvokerBytecodeGenerator code shape is updated. -IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address member_name, +JRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address member_name, Method* method, address bcp)) Bytecodes::Code code = Bytecodes::code_at(method, bcp); if (code != Bytecodes::_invokestatic) { @@ -1572,19 +1572,19 @@ } else { thread->set_vm_result(NULL); } -IRT_END +JRT_END #endif // INCLUDE_JVMTI #ifndef PRODUCT -// This must be a IRT_LEAF function because the interpreter must save registers on x86 to +// This must be a JRT_LEAF function because the interpreter must save registers on x86 to // call this, which changes rsp and makes the interpreter's expression stack not walkable. // The generated code still uses call_VM because that will set up the frame pointer for // bcp and method. -IRT_LEAF(intptr_t, InterpreterRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2)) +JRT_LEAF(intptr_t, InterpreterRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2)) LastFrameAccessor last_frame(thread); assert(last_frame.is_interpreted_frame(), "must be an interpreted frame"); methodHandle mh(thread, last_frame.method()); BytecodeTracer::trace(mh, last_frame.bcp(), tos, tos2); return preserve_this_value; -IRT_END +JRT_END #endif // !PRODUCT
--- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -359,7 +359,7 @@ } bool ret = false; - thread->set_trace_flag(); + thread->set_trace_flag(); // Provides StoreLoad, needed to keep read of thread state from floating up. if (JAVA_SAMPLE == type) { if (thread_state_in_java(thread)) { ret = sample_thread_in_java(thread, frames, max_frames);
--- a/src/hotspot/share/memory/filemap.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/memory/filemap.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -806,13 +806,14 @@ addr, size, false /* !read_only */, si->_allow_exec); close(); + // These have to be errors because the shared region is now unmapped. if (base == NULL) { - fail_continue("Unable to remap shared readonly space (errno=%d).", errno); - return false; + log_error(cds)("Unable to remap shared readonly space (errno=%d).", errno); + vm_exit(1); } if (base != addr) { - fail_continue("Unable to remap shared readonly space at required address."); - return false; + log_error(cds)("Unable to remap shared readonly space (errno=%d).", errno); + vm_exit(1); } si->_read_only = false; return true; @@ -849,10 +850,17 @@ size_t size = align_up(used, alignment); char *requested_addr = region_addr(i); - // If a tool agent is in use (debugging enabled), we must map the address space RW - if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) { +#ifdef _WINDOWS + // Windows cannot remap read-only shared memory to read-write when required for + // RedefineClasses, which is also used by JFR. Always map windows regions as RW. + si->_read_only = false; +#else + // If a tool agent is in use (debugging enabled), or JFR, we must map the address space RW + if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space() || + Arguments::has_jfr_option()) { si->_read_only = false; } +#endif // _WINDOWS // map the contents of the CDS archive in this memory char *base = os::map_memory(_fd, _full_path, si->_file_offset, @@ -868,7 +876,6 @@ MemTracker::record_virtual_memory_type((address)base, mtClassShared); #endif - if (!verify_region_checksum(i)) { return NULL; }
--- a/src/hotspot/share/memory/universe.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/memory/universe.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1151,6 +1151,8 @@ verify_flags |= Verify_JNIHandles; } else if (strcmp(token, "codecache_oops") == 0) { verify_flags |= Verify_CodeCacheOops; + } else if (strcmp(token, "resolved_method_table") == 0) { + verify_flags |= Verify_ResolvedMethodTable; } else { vm_exit_during_initialization(err_msg("VerifySubSet: \'%s\' memory sub-system is unknown, please correct it", token)); } @@ -1230,6 +1232,10 @@ log_debug(gc, verify)("CodeCache Oops"); CodeCache::verify_oops(); } + if (should_verify_subset(Verify_ResolvedMethodTable)) { + log_debug(gc, verify)("ResolvedMethodTable Oops"); + ResolvedMethodTable::verify(); + } _verify_in_progress = false; }
--- a/src/hotspot/share/memory/universe.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/memory/universe.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -478,6 +478,7 @@ Verify_MetaspaceUtils = 128, Verify_JNIHandles = 256, Verify_CodeCacheOops = 512, + Verify_ResolvedMethodTable = 1024, Verify_All = -1 }; static void initialize_verify_flags();
--- a/src/hotspot/share/oops/weakHandle.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/oops/weakHandle.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -29,6 +29,7 @@ #include "oops/access.inline.hpp" #include "oops/oop.hpp" #include "oops/weakHandle.inline.hpp" +#include "prims/resolvedMethodTable.hpp" #include "utilities/debug.hpp" #include "utilities/ostream.hpp" @@ -40,6 +41,10 @@ return StringTable::weak_storage(); } +template <> OopStorage* WeakHandle<vm_resolved_method_table_data>::get_storage() { + return ResolvedMethodTable::weak_storage(); +} + template <WeakHandleType T> WeakHandle<T> WeakHandle<T>::create(Handle obj) { assert(obj() != NULL, "no need to create weak null oop"); @@ -74,4 +79,4 @@ // Provide instantiation. template class WeakHandle<vm_class_loader_data>; template class WeakHandle<vm_string_table_data>; - +template class WeakHandle<vm_resolved_method_table_data>;
--- a/src/hotspot/share/oops/weakHandle.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/oops/weakHandle.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -39,7 +39,7 @@ // This is the vm version of jweak but has different GC lifetimes and policies, // depending on the type. -enum WeakHandleType { vm_class_loader_data, vm_string_table_data }; +enum WeakHandleType { vm_class_loader_data, vm_string_table_data, vm_resolved_method_table_data }; template <WeakHandleType T> class WeakHandle { @@ -64,6 +64,4 @@ void print_on(outputStream* st) const; }; -typedef WeakHandle<vm_class_loader_data> ClassLoaderWeakHandle; - #endif // SHARE_OOPS_WEAKHANDLE_HPP
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -787,6 +787,12 @@ return JVMTI_ERROR_NONE; } +static bool can_add_or_delete(Method* m) { + // Compatibility mode + return (AllowRedefinitionToAddDeleteMethods && + (m->is_private() && (m->is_static() || m->is_final()))); +} + jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions( InstanceKlass* the_class, InstanceKlass* scratch_class) { @@ -992,12 +998,7 @@ break; case added: // method added, see if it is OK - new_flags = (jushort) k_new_method->access_flags().get_flags(); - if ((new_flags & JVM_ACC_PRIVATE) == 0 - // hack: private should be treated as final, but alas - || (new_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0 - ) { - // new methods must be private + if (!can_add_or_delete(k_new_method)) { return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED; } { @@ -1026,12 +1027,7 @@ break; case deleted: // method deleted, see if it is OK - old_flags = (jushort) k_old_method->access_flags().get_flags(); - if ((old_flags & JVM_ACC_PRIVATE) == 0 - // hack: private should be treated as final, but alas - || (old_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0 - ) { - // deleted methods must be private + if (!can_add_or_delete(k_old_method)) { return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED; } log_trace(redefine, class, normalize)
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/prims/resolvedMethodTable.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -24,223 +24,395 @@ #include "precompiled.hpp" #include "classfile/javaClasses.hpp" +#include "gc/shared/oopStorage.inline.hpp" #include "logging/log.hpp" #include "memory/allocation.hpp" #include "memory/resourceArea.hpp" #include "oops/access.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/method.hpp" -#include "oops/symbol.hpp" #include "oops/weakHandle.inline.hpp" #include "prims/resolvedMethodTable.hpp" #include "runtime/handles.inline.hpp" +#include "runtime/interfaceSupport.inline.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/safepointVerifiers.hpp" -#include "utilities/hashtable.inline.hpp" +#include "runtime/timerTrace.hpp" +#include "utilities/concurrentHashTable.inline.hpp" +#include "utilities/concurrentHashTableTasks.inline.hpp" #include "utilities/macros.hpp" - -oop ResolvedMethodEntry::object() { - return literal().resolve(); -} - -oop ResolvedMethodEntry::object_no_keepalive() { - // The AS_NO_KEEPALIVE peeks at the oop without keeping it alive. - // This is dangerous in general but is okay if the loaded oop does - // not leak out past a thread transition where a safepoint can happen. - // A subsequent oop_load without AS_NO_KEEPALIVE (the object() accessor) - // keeps the oop alive before doing so. - return literal().peek(); -} - -ResolvedMethodTable::ResolvedMethodTable() - : Hashtable<ClassLoaderWeakHandle, mtClass>(_table_size, sizeof(ResolvedMethodEntry)) { } +// 2^24 is max size +static const size_t END_SIZE = 24; +// If a chain gets to 32 something might be wrong +static const size_t GROW_HINT = 32; -oop ResolvedMethodTable::lookup(int index, unsigned int hash, Method* method) { - assert_locked_or_safepoint(ResolvedMethodTable_lock); - for (ResolvedMethodEntry* p = bucket(index); p != NULL; p = p->next()) { - if (p->hash() == hash) { - - // Peek the object to check if it is the right target. - oop target = p->object_no_keepalive(); +static const size_t ResolvedMethodTableSizeLog = 10; - // The method is in the table as a target already - if (target != NULL && java_lang_invoke_ResolvedMethodName::vmtarget(target) == method) { - ResourceMark rm; - log_debug(membername, table) ("ResolvedMethod entry found for %s index %d", - method->name_and_sig_as_C_string(), index); - // The object() accessor makes sure the target object is kept alive before - // leaking out. - return p->object(); - } - } - } - return NULL; -} - -unsigned int ResolvedMethodTable::compute_hash(Method* method) { +unsigned int method_hash(const Method* method) { unsigned int name_hash = method->name()->identity_hash(); unsigned int signature_hash = method->signature()->identity_hash(); return name_hash ^ signature_hash; } +class ResolvedMethodTableConfig : public ResolvedMethodTableHash::BaseConfig { + private: + public: + static uintx get_hash(WeakHandle<vm_resolved_method_table_data> const& value, + bool* is_dead) { + EXCEPTION_MARK; + oop val_oop = value.peek(); + if (val_oop == NULL) { + *is_dead = true; + return 0; + } + *is_dead = false; + Method* method = java_lang_invoke_ResolvedMethodName::vmtarget(val_oop); + return method_hash(method); + } -oop ResolvedMethodTable::lookup(Method* method) { - unsigned int hash = compute_hash(method); - int index = hash_to_index(hash); - return lookup(index, hash, method); + // We use default allocation/deallocation but counted + static void* allocate_node(size_t size, WeakHandle<vm_resolved_method_table_data> const& value) { + ResolvedMethodTable::item_added(); + return ResolvedMethodTableHash::BaseConfig::allocate_node(size, value); + } + static void free_node(void* memory, WeakHandle<vm_resolved_method_table_data> const& value) { + value.release(); + ResolvedMethodTableHash::BaseConfig::free_node(memory, value); + ResolvedMethodTable::item_removed(); + } +}; + +ResolvedMethodTableHash* ResolvedMethodTable::_local_table = NULL; +size_t ResolvedMethodTable::_current_size = (size_t)1 << ResolvedMethodTableSizeLog; + +OopStorage* ResolvedMethodTable::_weak_handles = NULL; + +volatile bool ResolvedMethodTable::_has_work = false; +volatile size_t ResolvedMethodTable::_items_count = 0; +volatile size_t ResolvedMethodTable::_uncleaned_items_count = 0; + +void ResolvedMethodTable::create_table() { + _local_table = new ResolvedMethodTableHash(ResolvedMethodTableSizeLog, END_SIZE, GROW_HINT); + _weak_handles = new OopStorage("ResolvedMethodTable weak", + ResolvedMethodTableWeakAlloc_lock, + ResolvedMethodTableWeakActive_lock); + log_trace(membername, table)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", + _current_size, ResolvedMethodTableSizeLog); +} + +size_t ResolvedMethodTable::table_size() { + return (size_t)1 << _local_table->get_size_log2(Thread::current()); } -oop ResolvedMethodTable::basic_add(Method* method, Handle rmethod_name) { - assert_locked_or_safepoint(ResolvedMethodTable_lock); +class ResolvedMethodTableLookup : StackObj { + private: + Thread* _thread; + uintx _hash; + const Method* _method; + Handle _found; + + public: + ResolvedMethodTableLookup(Thread* thread, uintx hash, const Method* key) + : _thread(thread), _hash(hash), _method(key) { + } + uintx get_hash() const { + return _hash; + } + bool equals(WeakHandle<vm_resolved_method_table_data>* value, bool* is_dead) { + oop val_oop = value->peek(); + if (val_oop == NULL) { + // dead oop, mark this hash dead for cleaning + *is_dead = true; + return false; + } + bool equals = _method == java_lang_invoke_ResolvedMethodName::vmtarget(val_oop); + if (!equals) { + return false; + } + // Need to resolve weak handle and Handleize through possible safepoint. + _found = Handle(_thread, value->resolve()); + return true; + } +}; + - unsigned int hash = compute_hash(method); - int index = hash_to_index(hash); +class ResolvedMethodGet : public StackObj { + Thread* _thread; + const Method* _method; + Handle _return; +public: + ResolvedMethodGet(Thread* thread, const Method* method) : _thread(thread), _method(method) {} + void operator()(WeakHandle<vm_resolved_method_table_data>* val) { + oop result = val->resolve(); + assert(result != NULL, "Result should be reachable"); + _return = Handle(_thread, result); + log_get(); + } + oop get_res_oop() { + return _return(); + } + void log_get() { + LogTarget(Trace, membername, table) log; + if (log.is_enabled()) { + ResourceMark rm; + log.print("ResolvedMethod entry found for %s", + _method->name_and_sig_as_C_string()); + } + } +}; + +oop ResolvedMethodTable::find_method(const Method* method) { + Thread* thread = Thread::current(); - // One was added while aquiring the lock - oop entry = lookup(index, hash, method); - if (entry != NULL) { - return entry; + ResolvedMethodTableLookup lookup(thread, method_hash(method), method); + ResolvedMethodGet rmg(thread, method); + _local_table->get(thread, lookup, rmg); + + return rmg.get_res_oop(); +} + +static void log_insert(const Method* method) { + LogTarget(Debug, membername, table) log; + if (log.is_enabled()) { + ResourceMark rm; + log_debug(membername, table) ("ResolvedMethod entry added for %s", + method->name_and_sig_as_C_string()); + } +} + +oop ResolvedMethodTable::add_method(const Method* method, Handle rmethod_name) { + Thread* thread = Thread::current(); + + ResolvedMethodTableLookup lookup(thread, method_hash(method), method); + ResolvedMethodGet rmg(thread, method); + + while (true) { + if (_local_table->get(thread, lookup, rmg)) { + return rmg.get_res_oop(); + } + WeakHandle<vm_resolved_method_table_data> wh = WeakHandle<vm_resolved_method_table_data>::create(rmethod_name); + // The hash table takes ownership of the WeakHandle, even if it's not inserted. + if (_local_table->insert(thread, lookup, wh)) { + log_insert(method); + return wh.resolve(); + } } - ClassLoaderWeakHandle w = ClassLoaderWeakHandle::create(rmethod_name); - ResolvedMethodEntry* p = (ResolvedMethodEntry*) Hashtable<ClassLoaderWeakHandle, mtClass>::new_entry(hash, w); - Hashtable<ClassLoaderWeakHandle, mtClass>::add_entry(index, p); - ResourceMark rm; - log_debug(membername, table) ("ResolvedMethod entry added for %s index %d", - method->name_and_sig_as_C_string(), index); return rmethod_name(); } -ResolvedMethodTable* ResolvedMethodTable::_the_table = NULL; +void ResolvedMethodTable::item_added() { + Atomic::inc(&_items_count); +} + +void ResolvedMethodTable::item_removed() { + Atomic::dec(&_items_count); + log_trace(membername, table) ("ResolvedMethod entry removed"); +} -oop ResolvedMethodTable::find_method(Method* method) { - MutexLocker ml(ResolvedMethodTable_lock); - oop entry = _the_table->lookup(method); - return entry; +bool ResolvedMethodTable::has_work() { + return _has_work; +} + +OopStorage* ResolvedMethodTable::weak_storage() { + return _weak_handles; +} + +double ResolvedMethodTable::get_load_factor() { + return (double)_items_count/_current_size; +} + +double ResolvedMethodTable::get_dead_factor() { + return (double)_uncleaned_items_count/_current_size; } -oop ResolvedMethodTable::add_method(const methodHandle& m, Handle resolved_method_name) { - MutexLocker ml(ResolvedMethodTable_lock); - DEBUG_ONLY(NoSafepointVerifier nsv); +static const double PREF_AVG_LIST_LEN = 2.0; +// If we have as many dead items as 50% of the number of bucket +static const double CLEAN_DEAD_HIGH_WATER_MARK = 0.5; - Method* method = m(); - // Check if method has been redefined while taking out ResolvedMethodTable_lock, if so - // use new method in the ResolvedMethodName. The old method won't be deallocated - // yet because it's passed in as a Handle. - if (method->is_old()) { - method = (method->is_deleted()) ? Universe::throw_no_such_method_error() : - method->get_new_method(); - java_lang_invoke_ResolvedMethodName::set_vmtarget(resolved_method_name(), method); +void ResolvedMethodTable::check_concurrent_work() { + if (_has_work) { + return; } - // Set flag in class to indicate this InstanceKlass has entries in the table - // to avoid walking table during redefinition if none of the redefined classes - // have any membernames in the table. - method->method_holder()->set_has_resolved_methods(); - - return _the_table->basic_add(method, resolved_method_name); + double load_factor = get_load_factor(); + double dead_factor = get_dead_factor(); + // We should clean/resize if we have more dead than alive, + // more items than preferred load factor or + // more dead items than water mark. + if ((dead_factor > load_factor) || + (load_factor > PREF_AVG_LIST_LEN) || + (dead_factor > CLEAN_DEAD_HIGH_WATER_MARK)) { + log_debug(membername, table)("Concurrent work triggered, live factor: %g dead factor: %g", + load_factor, dead_factor); + trigger_concurrent_work(); + } } -// Removing entries -int ResolvedMethodTable::_total_oops_removed = 0; - -// There are no dead entries at start -bool ResolvedMethodTable::_dead_entries = false; - -void ResolvedMethodTable::trigger_cleanup() { +void ResolvedMethodTable::trigger_concurrent_work() { MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); - _dead_entries = true; + _has_work = true; Service_lock->notify_all(); } -// Serially invoke removed unused oops from the table. -// This is done by the ServiceThread after being notified on class unloading -void ResolvedMethodTable::unlink() { - MutexLocker ml(ResolvedMethodTable_lock); - int _oops_removed = 0; - int _oops_counted = 0; - for (int i = 0; i < _the_table->table_size(); ++i) { - ResolvedMethodEntry** p = _the_table->bucket_addr(i); - ResolvedMethodEntry* entry = _the_table->bucket(i); - while (entry != NULL) { - _oops_counted++; - oop l = entry->object_no_keepalive(); - if (l != NULL) { - p = entry->next_addr(); - } else { - // Entry has been removed. - _oops_removed++; - if (log_is_enabled(Debug, membername, table)) { - log_debug(membername, table) ("ResolvedMethod entry removed for index %d", i); - } - entry->literal().release(); - *p = entry->next(); - _the_table->free_entry(entry); +void ResolvedMethodTable::do_concurrent_work(JavaThread* jt) { + _has_work = false; + double load_factor = get_load_factor(); + log_debug(membername, table)("Concurrent work, live factor: %g", load_factor); + // We prefer growing, since that also removes dead items + if (load_factor > PREF_AVG_LIST_LEN && !_local_table->is_max_size_reached()) { + grow(jt); + } else { + clean_dead_entries(jt); + } +} + +void ResolvedMethodTable::grow(JavaThread* jt) { + ResolvedMethodTableHash::GrowTask gt(_local_table); + if (!gt.prepare(jt)) { + return; + } + log_trace(membername, table)("Started to grow"); + { + TraceTime timer("Grow", TRACETIME_LOG(Debug, membername, table, perf)); + while (gt.do_task(jt)) { + gt.pause(jt); + { + ThreadBlockInVM tbivm(jt); } - // get next entry - entry = (ResolvedMethodEntry*)HashtableEntry<ClassLoaderWeakHandle, mtClass>::make_ptr(*p); + gt.cont(jt); + } + } + gt.done(jt); + _current_size = table_size(); + log_info(membername, table)("Grown to size:" SIZE_FORMAT, _current_size); +} + +struct ResolvedMethodTableDoDelete : StackObj { + void operator()(WeakHandle<vm_resolved_method_table_data>* val) { + /* do nothing */ + } +}; + +struct ResolvedMethodTableDeleteCheck : StackObj { + long _count; + long _item; + ResolvedMethodTableDeleteCheck() : _count(0), _item(0) {} + bool operator()(WeakHandle<vm_resolved_method_table_data>* val) { + ++_item; + oop tmp = val->peek(); + if (tmp == NULL) { + ++_count; + return true; + } else { + return false; } } - log_debug(membername, table) ("ResolvedMethod entries counted %d removed %d", - _oops_counted, _oops_removed); - _total_oops_removed += _oops_removed; - _dead_entries = false; +}; + +void ResolvedMethodTable::clean_dead_entries(JavaThread* jt) { + ResolvedMethodTableHash::BulkDeleteTask bdt(_local_table); + if (!bdt.prepare(jt)) { + return; + } + ResolvedMethodTableDeleteCheck stdc; + ResolvedMethodTableDoDelete stdd; + { + TraceTime timer("Clean", TRACETIME_LOG(Debug, membername, table, perf)); + while(bdt.do_task(jt, stdc, stdd)) { + bdt.pause(jt); + { + ThreadBlockInVM tbivm(jt); + } + bdt.cont(jt); + } + bdt.done(jt); + } + log_info(membername, table)("Cleaned %ld of %ld", stdc._count, stdc._item); +} +void ResolvedMethodTable::reset_dead_counter() { + _uncleaned_items_count = 0; +} + +void ResolvedMethodTable::inc_dead_counter(size_t ndead) { + size_t total = Atomic::add(ndead, &_uncleaned_items_count); + log_trace(membername, table)( + "Uncleaned items:" SIZE_FORMAT " added: " SIZE_FORMAT " total:" SIZE_FORMAT, + _uncleaned_items_count, ndead, total); } -#ifndef PRODUCT -void ResolvedMethodTable::print() { - MutexLocker ml(ResolvedMethodTable_lock); - for (int i = 0; i < table_size(); ++i) { - ResolvedMethodEntry* entry = bucket(i); - while (entry != NULL) { - tty->print("%d : ", i); - oop rmethod_name = entry->object_no_keepalive(); - if (rmethod_name != NULL) { - rmethod_name->print(); - Method* m = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(rmethod_name); - m->print(); - } - entry = entry->next(); - } - } +// After the parallel walk this method must be called to trigger +// cleaning. Note it might trigger a resize instead. +void ResolvedMethodTable::finish_dead_counter() { + check_concurrent_work(); } -#endif // PRODUCT #if INCLUDE_JVMTI +class AdjustMethodEntries : public StackObj { + bool* _trace_name_printed; +public: + AdjustMethodEntries(bool* trace_name_printed) : _trace_name_printed(trace_name_printed) {}; + bool operator()(WeakHandle<vm_resolved_method_table_data>* entry) { + oop mem_name = entry->peek(); + if (mem_name == NULL) { + // Removed + return true; + } + + Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name); + + if (old_method->is_old()) { + + Method* new_method = (old_method->is_deleted()) ? + Universe::throw_no_such_method_error() : + old_method->get_new_method(); + java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, new_method); + + ResourceMark rm; + if (!(*_trace_name_printed)) { + log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name()); + *_trace_name_printed = true; + } + log_debug(redefine, class, update, constantpool) + ("ResolvedMethod method update: %s(%s)", + new_method->name()->as_C_string(), new_method->signature()->as_C_string()); + } + + return true; + } +}; + // It is called at safepoint only for RedefineClasses void ResolvedMethodTable::adjust_method_entries(bool * trace_name_printed) { assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); // For each entry in RMT, change to new method - for (int i = 0; i < _the_table->table_size(); ++i) { - for (ResolvedMethodEntry* entry = _the_table->bucket(i); - entry != NULL; - entry = entry->next()) { - - oop mem_name = entry->object_no_keepalive(); - // except ones removed - if (mem_name == NULL) { - continue; - } - Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name); - - if (old_method->is_old()) { + AdjustMethodEntries adjust(trace_name_printed); + _local_table->do_safepoint_scan(adjust); +} +#endif // INCLUDE_JVMTI - Method* new_method = (old_method->is_deleted()) ? - Universe::throw_no_such_method_error() : - old_method->get_new_method(); - java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, new_method); +// Verification +class VerifyResolvedMethod : StackObj { + public: + bool operator()(WeakHandle<vm_resolved_method_table_data>* val) { + oop obj = val->peek(); + if (obj != NULL) { + Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(obj); + guarantee(method->is_method(), "Must be"); + guarantee(!method->is_old(), "Must be"); + } + return true; + }; +}; - ResourceMark rm; - if (!(*trace_name_printed)) { - log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name()); - *trace_name_printed = true; - } - log_debug(redefine, class, update, constantpool) - ("ResolvedMethod method update: %s(%s)", - new_method->name()->as_C_string(), new_method->signature()->as_C_string()); - } - } +size_t ResolvedMethodTable::items_count() { + return _items_count; +} + +void ResolvedMethodTable::verify() { + VerifyResolvedMethod vcs; + if (!_local_table->try_scan(Thread::current(), vcs)) { + log_info(membername, table)("verify unavailable at this moment"); } } -#endif // INCLUDE_JVMTI
--- a/src/hotspot/share/prims/resolvedMethodTable.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/prims/resolvedMethodTable.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -25,89 +25,78 @@ #ifndef SHARE_PRIMS_RESOLVEDMETHODTABLE_HPP #define SHARE_PRIMS_RESOLVEDMETHODTABLE_HPP +#include "gc/shared/oopStorage.hpp" +#include "gc/shared/oopStorageParState.hpp" +#include "memory/allocation.hpp" #include "oops/symbol.hpp" #include "oops/weakHandle.hpp" +#include "utilities/concurrentHashTable.hpp" #include "utilities/hashtable.hpp" -// Hashtable to record Method* used in ResolvedMethods, via. ResolvedMethod oops. -// This is needed for redefinition to replace Method* with redefined versions. - -// Entry in a ResolvedMethodTable, mapping a ClassLoaderWeakHandle for a single oop of -// java_lang_invoke_ResolvedMethodName which holds JVM Method* in vmtarget. - -class ResolvedMethodEntry : public HashtableEntry<ClassLoaderWeakHandle, mtClass> { - public: - ResolvedMethodEntry* next() const { - return (ResolvedMethodEntry*)HashtableEntry<ClassLoaderWeakHandle, mtClass>::next(); - } - - ResolvedMethodEntry** next_addr() { - return (ResolvedMethodEntry**)HashtableEntry<ClassLoaderWeakHandle, mtClass>::next_addr(); - } - - oop object(); - oop object_no_keepalive(); - - void print_on(outputStream* st) const; -}; +class ResolvedMethodTable; +class ResolvedMethodTableConfig; +typedef ConcurrentHashTable<WeakHandle<vm_resolved_method_table_data>, ResolvedMethodTableConfig, mtClass> ResolvedMethodTableHash; -class ResolvedMethodTable : public Hashtable<ClassLoaderWeakHandle, mtClass> { - enum Constants { - _table_size = 1007 - }; - - static int _total_oops_removed; - - static bool _dead_entries; +class ResolvedMethodTable : public AllStatic { + static ResolvedMethodTableHash* _local_table; + static size_t _current_size; - static ResolvedMethodTable* _the_table; -private: - ResolvedMethodEntry* bucket(int i) { - return (ResolvedMethodEntry*) Hashtable<ClassLoaderWeakHandle, mtClass>::bucket(i); - } + static OopStorage* _weak_handles; - ResolvedMethodEntry** bucket_addr(int i) { - return (ResolvedMethodEntry**) Hashtable<ClassLoaderWeakHandle, mtClass>::bucket_addr(i); - } - - unsigned int compute_hash(Method* method); + static volatile bool _has_work; - // need not be locked; no state change - oop lookup(int index, unsigned int hash, Method* method); - oop lookup(Method* method); - - // must be done under ResolvedMethodTable_lock - oop basic_add(Method* method, Handle rmethod_name); + static volatile size_t _items_count; + static volatile size_t _uncleaned_items_count; public: - ResolvedMethodTable(); + // Initialization + static void create_table(); - static void create_table() { - assert(_the_table == NULL, "One symbol table allowed."); - _the_table = new ResolvedMethodTable(); - } + static size_t table_size(); + + // Lookup and inserts + static oop find_method(const Method* method); + static oop add_method(const Method* method, Handle rmethod_name); - // Called from java_lang_invoke_ResolvedMethodName - static oop find_method(Method* method); - static oop add_method(const methodHandle& method, Handle rmethod_name); + // Callbacks + static void item_added(); + static void item_removed(); + + // Cleaning + static bool has_work(); - static bool has_work() { return _dead_entries; } - static void trigger_cleanup(); + // GC Support - Backing storage for the oop*s + static OopStorage* weak_storage(); + + // Cleaning and table management + + static double get_load_factor(); + static double get_dead_factor(); - static int removed_entries_count() { return _total_oops_removed; }; + static void check_concurrent_work(); + static void trigger_concurrent_work(); + static void do_concurrent_work(JavaThread* jt); -#if INCLUDE_JVMTI - // It is called at safepoint only for RedefineClasses - static void adjust_method_entries(bool * trace_name_printed); -#endif // INCLUDE_JVMTI + static void grow(JavaThread* jt); + static void clean_dead_entries(JavaThread* jt); + + // GC Notification - // Cleanup cleared entries - static void unlink(); + // Must be called before a parallel walk where objects might die. + static void reset_dead_counter(); + // After the parallel walk this method must be called to trigger + // cleaning. Note it might trigger a resize instead. + static void finish_dead_counter(); + // If GC uses ParState directly it should add the number of cleared + // entries to this method. + static void inc_dead_counter(size_t ndead); -#ifndef PRODUCT - void print(); -#endif - void verify(); + // JVMTI Support - It is called at safepoint only for RedefineClasses + JVMTI_ONLY(static void adjust_method_entries(bool * trace_name_printed);) + + // Debugging + static size_t items_count(); + static void verify(); }; #endif // SHARE_PRIMS_RESOLVEDMETHODTABLE_HPP
--- a/src/hotspot/share/prims/whitebox.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/prims/whitebox.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -2092,8 +2092,8 @@ #endif WB_END -WB_ENTRY(jint, WB_ResolvedMethodRemovedCount(JNIEnv* env, jobject o)) - return (jint) ResolvedMethodTable::removed_entries_count(); +WB_ENTRY(jlong, WB_ResolvedMethodItemsCount(JNIEnv* env, jobject o)) + return (jlong) ResolvedMethodTable::items_count(); WB_END WB_ENTRY(jint, WB_ProtectionDomainRemovedCount(JNIEnv* env, jobject o)) @@ -2337,7 +2337,7 @@ {CC"isContainerized", CC"()Z", (void*)&WB_IsContainerized }, {CC"printOsInfo", CC"()V", (void*)&WB_PrintOsInfo }, {CC"disableElfSectionCache", CC"()V", (void*)&WB_DisableElfSectionCache }, - {CC"resolvedMethodRemovedCount", CC"()I", (void*)&WB_ResolvedMethodRemovedCount }, + {CC"resolvedMethodItemsCount", CC"()J", (void*)&WB_ResolvedMethodItemsCount }, {CC"protectionDomainRemovedCount", CC"()I", (void*)&WB_ProtectionDomainRemovedCount }, {CC"aotLibrariesCount", CC"()I", (void*)&WB_AotLibrariesCount }, };
--- a/src/hotspot/share/runtime/arguments.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/runtime/arguments.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -271,17 +271,25 @@ } #if INCLUDE_JFR +static bool _has_jfr_option = false; // is using JFR + // return true on failure static bool match_jfr_option(const JavaVMOption** option) { assert((*option)->optionString != NULL, "invariant"); char* tail = NULL; if (match_option(*option, "-XX:StartFlightRecording", (const char**)&tail)) { + _has_jfr_option = true; return Jfr::on_start_flight_recording_option(option, tail); } else if (match_option(*option, "-XX:FlightRecorderOptions", (const char**)&tail)) { + _has_jfr_option = true; return Jfr::on_flight_recorder_option(option, tail); } return false; } + +bool Arguments::has_jfr_option() { + return _has_jfr_option; +} #endif static void logOption(const char* opt) { @@ -532,6 +540,7 @@ { "FailOverToOldVerifier", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::undefined() }, { "AllowJNIEnvProxy", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::jdk(15) }, { "ThreadLocalHandshakes", JDK_Version::jdk(13), JDK_Version::jdk(14), JDK_Version::jdk(15) }, + { "AllowRedefinitionToAddDeleteMethods", JDK_Version::jdk(13), JDK_Version::undefined(), JDK_Version::undefined() }, // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in: { "DefaultMaxRAMFraction", JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() },
--- a/src/hotspot/share/runtime/arguments.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/runtime/arguments.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -649,6 +649,8 @@ static bool check_unsupported_cds_runtime_properties() NOT_CDS_RETURN0; static bool atojulong(const char *s, julong* result); + + static bool has_jfr_option() NOT_JFR_RETURN_(false); }; // Disable options not supported in this release, with a warning if they
--- a/src/hotspot/share/runtime/globals.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/runtime/globals.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -978,6 +978,10 @@ product(bool, VerifyMergedCPBytecodes, true, \ "Verify bytecodes after RedefineClasses constant pool merging") \ \ + product(bool, AllowRedefinitionToAddDeleteMethods, false, \ + "Allow redefinition to add and delete private static or " \ + "final methods for compatibility with old releases") \ + \ develop(bool, TraceBytecodes, false, \ "Trace bytecode execution") \ \
--- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -422,30 +422,6 @@ /* begin of body */ -// Definitions for IRT (Interpreter Runtime) -// (thread is an argument passed in to all these routines) - -#define IRT_ENTRY(result_type, header) \ - result_type header { \ - ThreadInVMfromJava __tiv(thread); \ - VM_ENTRY_BASE(result_type, header, thread) \ - debug_only(VMEntryWrapper __vew;) - - -#define IRT_LEAF(result_type, header) \ - result_type header { \ - VM_LEAF_BASE(result_type, header) \ - debug_only(NoSafepointVerifier __nspv(true);) - - -#define IRT_ENTRY_NO_ASYNC(result_type, header) \ - result_type header { \ - ThreadInVMfromJavaNoAsyncException __tiv(thread); \ - VM_ENTRY_BASE(result_type, header, thread) \ - debug_only(VMEntryWrapper __vew;) - -#define IRT_END } - #define JRT_ENTRY(result_type, header) \ result_type header { \ ThreadInVMfromJava __tiv(thread); \
--- a/src/hotspot/share/runtime/mutexLocker.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/runtime/mutexLocker.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -54,7 +54,8 @@ Mutex* JNIHandleBlockFreeList_lock = NULL; Mutex* VMWeakAlloc_lock = NULL; Mutex* VMWeakActive_lock = NULL; -Mutex* ResolvedMethodTable_lock = NULL; +Mutex* ResolvedMethodTableWeakAlloc_lock = NULL; +Mutex* ResolvedMethodTableWeakActive_lock = NULL; Mutex* JmethodIdCreation_lock = NULL; Mutex* JfieldIdCreation_lock = NULL; Monitor* JNICritical_lock = NULL; @@ -212,6 +213,9 @@ def(StringTableWeakAlloc_lock , PaddedMutex , vmweak, true, Monitor::_safepoint_check_never); def(StringTableWeakActive_lock , PaddedMutex , vmweak-1, true, Monitor::_safepoint_check_never); + def(ResolvedMethodTableWeakAlloc_lock , PaddedMutex , vmweak, true, Monitor::_safepoint_check_never); + def(ResolvedMethodTableWeakActive_lock , PaddedMutex , vmweak-1, true, Monitor::_safepoint_check_never); + if (UseConcMarkSweepGC || UseG1GC) { def(FullGCCount_lock , PaddedMonitor, leaf, true, Monitor::_safepoint_check_never); // in support of ExplicitGCInvokesConcurrent } @@ -298,7 +302,6 @@ def(Heap_lock , PaddedMonitor, nonleaf+1, false, Monitor::_safepoint_check_sometimes); def(JfieldIdCreation_lock , PaddedMutex , nonleaf+1, true, Monitor::_safepoint_check_always); // jfieldID, Used in VM_Operation - def(ResolvedMethodTable_lock , PaddedMutex , nonleaf+1, false, Monitor::_safepoint_check_always); // Used to protect ResolvedMethodTable def(CompiledIC_lock , PaddedMutex , nonleaf+2, false, Monitor::_safepoint_check_never); // locks VtableStubs_lock, InlineCacheBuffer_lock def(CompileTaskAlloc_lock , PaddedMutex , nonleaf+2, true, Monitor::_safepoint_check_always);
--- a/src/hotspot/share/runtime/mutexLocker.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/runtime/mutexLocker.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -48,7 +48,8 @@ extern Mutex* JNIHandleBlockFreeList_lock; // a lock on the JNI handle block free list extern Mutex* VMWeakAlloc_lock; // VM Weak Handles storage allocate list lock extern Mutex* VMWeakActive_lock; // VM Weak Handles storage active list lock -extern Mutex* ResolvedMethodTable_lock; // a lock on the ResolvedMethodTable updates +extern Mutex* ResolvedMethodTableWeakAlloc_lock; // ResolvedMethodTable weak storage allocate list +extern Mutex* ResolvedMethodTableWeakActive_lock; // ResolvedMethodTable weak storage active list extern Mutex* JmethodIdCreation_lock; // a lock on creating JNI method identifiers extern Mutex* JfieldIdCreation_lock; // a lock on creating JNI static field identifiers extern Monitor* JNICritical_lock; // a lock used while entering and exiting JNI critical regions, allows GC to sometimes get in
--- a/src/hotspot/share/runtime/serviceThread.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/runtime/serviceThread.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -190,7 +190,7 @@ } if (resolved_method_table_work) { - ResolvedMethodTable::unlink(); + ResolvedMethodTable::do_concurrent_work(jt); } if (protection_domain_table_work) {
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/runtime/sharedRuntime.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1918,7 +1918,7 @@ // where we went int -> i2c -> c2i and so the caller could in fact be // interpreted. If the caller is compiled we attempt to patch the caller // so he no longer calls into the interpreter. -IRT_LEAF(void, SharedRuntime::fixup_callers_callsite(Method* method, address caller_pc)) +JRT_LEAF(void, SharedRuntime::fixup_callers_callsite(Method* method, address caller_pc)) Method* moop(method); address entry_point = moop->from_compiled_entry_no_trampoline(); @@ -1987,7 +1987,7 @@ } } } -IRT_END +JRT_END // same as JVM_Arraycopy, but called directly from compiled code
--- a/src/hotspot/share/runtime/thread.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/runtime/thread.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -1415,7 +1415,7 @@ // Whenever a thread transitions from native to vm/java it must suspend // if external|deopt suspend is present. bool is_suspend_after_native() const { - return (_suspend_flags & (_external_suspend | _deopt_suspend)) != 0; + return (_suspend_flags & (_external_suspend | _deopt_suspend JFR_ONLY(| _trace_flag))) != 0; } // external suspend request is completed
--- a/src/hotspot/share/runtime/threadSMR.cpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/runtime/threadSMR.cpp Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -590,12 +590,9 @@ } void ThreadsList::dec_nested_handle_cnt() { - // The decrement needs to be MO_ACQ_REL. At the moment, the Atomic::dec - // backend on PPC does not yet conform to these requirements. Therefore - // the decrement is simulated with an Atomic::sub(1, &addr). - // Without this MO_ACQ_REL Atomic::dec simulation, the nested SMR mechanism - // is not generally safe to use. - Atomic::sub(1, &_nested_handle_cnt); + // The decrement only needs to be MO_ACQ_REL since the reference + // counter is volatile (and the hazard ptr is already NULL). + Atomic::dec(&_nested_handle_cnt); } int ThreadsList::find_index_of_JavaThread(JavaThread *target) { @@ -626,19 +623,9 @@ } void ThreadsList::inc_nested_handle_cnt() { - // The increment needs to be MO_SEQ_CST. At the moment, the Atomic::inc - // backend on PPC does not yet conform to these requirements. Therefore - // the increment is simulated with a load phi; cas phi + 1; loop. - // Without this MO_SEQ_CST Atomic::inc simulation, the nested SMR mechanism - // is not generally safe to use. - intx sample = OrderAccess::load_acquire(&_nested_handle_cnt); - for (;;) { - if (Atomic::cmpxchg(sample + 1, &_nested_handle_cnt, sample) == sample) { - return; - } else { - sample = OrderAccess::load_acquire(&_nested_handle_cnt); - } - } + // The increment needs to be MO_SEQ_CST so that the reference counter + // update is seen before the subsequent hazard ptr update. + Atomic::inc(&_nested_handle_cnt); } bool ThreadsList::includes(const JavaThread * const p) const {
--- a/src/hotspot/share/utilities/macros.hpp Tue Apr 16 10:09:11 2019 +0530 +++ b/src/hotspot/share/utilities/macros.hpp Mon Apr 22 10:53:45 2019 +0530 @@ -279,8 +279,10 @@ #if INCLUDE_JFR #define JFR_ONLY(code) code +#define NOT_JFR_RETURN_(code) /* next token must be ; */ #else #define JFR_ONLY(code) +#define NOT_JFR_RETURN_(code) { return code; } #endif #ifndef INCLUDE_JVMCI
--- a/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/Metrics.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/Metrics.java Mon Apr 22 10:53:45 2019 +0530 @@ -25,15 +25,16 @@ package jdk.internal.platform.cgroupv1; -import java.io.BufferedReader; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; +import jdk.internal.platform.cgroupv1.SubSystem.MemorySubSystem; + public class Metrics implements jdk.internal.platform.Metrics { - private SubSystem memory; + private MemorySubSystem memory; private SubSystem cpu; private SubSystem cpuacct; private SubSystem cpuset; @@ -133,7 +134,7 @@ for (String subsystemName: subsystemNames) { switch (subsystemName) { case "memory": - metric.setMemorySubSystem(new SubSystem(mountentry[3], mountentry[4])); + metric.setMemorySubSystem(new MemorySubSystem(mountentry[3], mountentry[4])); break; case "cpuset": metric.setCpuSetSubSystem(new SubSystem(mountentry[3], mountentry[4])); @@ -195,6 +196,11 @@ if (subsystem != null) { subsystem.setPath(base); + if (subsystem instanceof MemorySubSystem) { + MemorySubSystem memorySubSystem = (MemorySubSystem)subsystem; + boolean isHierarchial = getHierarchical(memorySubSystem); + memorySubSystem.setHierarchical(isHierarchial); + } metric.setActiveSubSystems(); } if (subsystem2 != null) { @@ -203,6 +209,11 @@ } + private static boolean getHierarchical(MemorySubSystem subsystem) { + long hierarchical = SubSystem.getLongValue(subsystem, "memory.use_hierarchy"); + return hierarchical > 0; + } + private void setActiveSubSystems() { activeSubSystems = true; } @@ -211,7 +222,7 @@ return activeSubSystems; } - private void setMemorySubSystem(SubSystem memory) { + private void setMemorySubSystem(MemorySubSystem memory) { this.memory = memory; } @@ -366,9 +377,29 @@ public long getMemoryLimit() { long retval = SubSystem.getLongValue(memory, "memory.limit_in_bytes"); + if (retval > unlimited_minimum) { + if (memory.isHierarchical()) { + // memory.limit_in_bytes returned unlimited, attempt + // hierarchical memory limit + String match = "hierarchical_memory_limit"; + retval = SubSystem.getLongValueMatchingLine(memory, + "memory.stat", + match, + Metrics::convertHierachicalLimitLine); + } + } return retval > unlimited_minimum ? -1L : retval; } + public static long convertHierachicalLimitLine(String line) { + String[] tokens = line.split("\\s"); + if (tokens.length == 2) { + String strVal = tokens[1]; + return SubSystem.convertStringToLong(strVal); + } + return unlimited_minimum + 1; // unlimited + } + public long getMemoryMaxUsage() { return SubSystem.getLongValue(memory, "memory.max_usage_in_bytes"); } @@ -417,6 +448,17 @@ public long getMemoryAndSwapLimit() { long retval = SubSystem.getLongValue(memory, "memory.memsw.limit_in_bytes"); + if (retval > unlimited_minimum) { + if (memory.isHierarchical()) { + // memory.memsw.limit_in_bytes returned unlimited, attempt + // hierarchical memory limit + String match = "hierarchical_memsw_limit"; + retval = SubSystem.getLongValueMatchingLine(memory, + "memory.stat", + match, + Metrics::convertHierachicalLimitLine); + } + } return retval > unlimited_minimum ? -1L : retval; }
--- a/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/SubSystem.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/linux/classes/jdk/internal/platform/cgroupv1/SubSystem.java Mon Apr 22 10:53:45 2019 +0530 @@ -29,10 +29,11 @@ import java.io.IOException; import java.math.BigInteger; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.List; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Stream; public class SubSystem { @@ -99,10 +100,32 @@ } + public static long getLongValueMatchingLine(SubSystem subsystem, + String param, + String match, + Function<String, Long> conversion) { + long retval = Metrics.unlimited_minimum + 1; // default unlimited + try { + List<String> lines = Files.readAllLines(Paths.get(subsystem.path(), param)); + for (String line: lines) { + if (line.contains(match)) { + retval = conversion.apply(line); + break; + } + } + } catch (IOException e) { + // Ignore. Default is unlimited. + } + return retval; + } + public static long getLongValue(SubSystem subsystem, String parm) { String strval = getStringValue(subsystem, parm); + return convertStringToLong(strval); + } + + public static long convertStringToLong(String strval) { long retval = 0; - if (strval == null) return 0L; try { @@ -215,4 +238,22 @@ return ints; } + + public static class MemorySubSystem extends SubSystem { + + private boolean hierarchical; + + public MemorySubSystem(String root, String mountPoint) { + super(root, mountPoint); + } + + boolean isHierarchical() { + return hierarchical; + } + + void setHierarchical(boolean hierarchical) { + this.hierarchical = hierarchical; + } + + } }
--- a/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java Mon Apr 22 10:53:45 2019 +0530 @@ -263,13 +263,13 @@ throw new InvalidKeyException("Unknown mode: " + opmode); } RSAKey rsaKey = RSAKeyFactory.toRSAKey(key); - if (key instanceof RSAPublicKey) { + if (rsaKey instanceof RSAPublicKey) { mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY; - publicKey = (RSAPublicKey)key; + publicKey = (RSAPublicKey)rsaKey; privateKey = null; } else { // must be RSAPrivateKey per check in toRSAKey mode = encrypt ? MODE_SIGN : MODE_DECRYPT; - privateKey = (RSAPrivateKey)key; + privateKey = (RSAPrivateKey)rsaKey; publicKey = null; } int n = RSACore.getByteLength(rsaKey.getModulus());
--- a/src/java.base/share/classes/java/lang/Class.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/java/lang/Class.java Mon Apr 22 10:53:45 2019 +0530 @@ -277,8 +277,7 @@ .collect(Collectors.joining(",", "<", ">"))); } - for (int i = 0; i < arrayDepth; i++) - sb.append("[]"); + if (arrayDepth > 0) sb.append("[]".repeat(arrayDepth)); return sb.toString(); } @@ -1589,12 +1588,7 @@ dimensions++; cl = cl.getComponentType(); } while (cl.isArray()); - StringBuilder sb = new StringBuilder(); - sb.append(cl.getName()); - for (int i = 0; i < dimensions; i++) { - sb.append("[]"); - } - return sb.toString(); + return cl.getName() + "[]".repeat(dimensions); } catch (Throwable e) { /*FALLTHRU*/ } } return getName(); @@ -3418,15 +3412,12 @@ * Helper method to get the method name from arguments. */ private String methodToString(String name, Class<?>[] argTypes) { - StringBuilder sb = new StringBuilder(); - sb.append(getName() + "." + name + "("); - if (argTypes != null) { - sb.append(Arrays.stream(argTypes) - .map(c -> (c == null) ? "null" : c.getName()) - .collect(Collectors.joining(","))); - } - sb.append(")"); - return sb.toString(); + return getName() + '.' + name + + ((argTypes == null || argTypes.length == 0) ? + "()" : + Arrays.stream(argTypes) + .map(c -> c == null ? "null" : c.getName()) + .collect(Collectors.joining(",", "(", ")"))); } /** use serialVersionUID from JDK 1.1 for interoperability */
--- a/src/java.base/share/classes/java/lang/String.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/java/lang/String.java Mon Apr 22 10:53:45 2019 +0530 @@ -1965,20 +1965,7 @@ if (str.isEmpty()) { return this; } - if (coder() == str.coder()) { - byte[] val = this.value; - byte[] oval = str.value; - int len = val.length + oval.length; - byte[] buf = Arrays.copyOf(val, len); - System.arraycopy(oval, 0, buf, val.length, oval.length); - return new String(buf, coder); - } - int len = length(); - int olen = str.length(); - byte[] buf = StringUTF16.newBytesFor(len + olen); - getBytes(buf, 0, UTF16); - str.getBytes(buf, len, UTF16); - return new String(buf, UTF16); + return StringConcatHelper.simpleConcat(this, str); } /**
--- a/src/java.base/share/classes/java/lang/StringConcatHelper.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/java/lang/StringConcatHelper.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,6 +25,9 @@ package java.lang; +import jdk.internal.misc.Unsafe; +import jdk.internal.vm.annotation.ForceInline; + /** * Helper for string concatenation. These methods are mostly looked up with private lookups * from {@link java.lang.invoke.StringConcatFactory}, and used in {@link java.lang.invoke.MethodHandle} @@ -38,8 +41,10 @@ /** * Check for overflow, throw exception on overflow. - * @param lengthCoder String length and coder - * @return lengthCoder + * + * @param lengthCoder String length with coder packed into higher bits + * the upper word. + * @return the given parameter value, if valid */ private static long checkOverflow(long lengthCoder) { if ((int)lengthCoder >= 0) { @@ -50,76 +55,83 @@ /** * Mix value length and coder into current length and coder. - * @param current current length - * @param value value to mix in - * @return new length and coder + * @param lengthCoder String length with coder packed into higher bits + * the upper word. + * @param value value to mix in + * @return new length and coder */ - static long mix(long current, boolean value) { - return checkOverflow(current + (value ? 4 : 5)); + static long mix(long lengthCoder, boolean value) { + return checkOverflow(lengthCoder + (value ? 4 : 5)); } /** * Mix value length and coder into current length and coder. - * @param current current length - * @param value value to mix in - * @return new length and coder + * @param lengthCoder String length with coder packed into higher bits + * the upper word. + * @param value value to mix in + * @return new length and coder */ - static long mix(long current, byte value) { - return mix(current, (int)value); + static long mix(long lengthCoder, byte value) { + return mix(lengthCoder, (int)value); } /** * Mix value length and coder into current length and coder. - * @param current current length - * @param value value to mix in - * @return new length and coder + * @param lengthCoder String length with coder packed into higher bits + * the upper word. + * @param value value to mix in + * @return new length and coder */ - static long mix(long current, char value) { - return checkOverflow(current + 1) | (StringLatin1.canEncode(value) ? 0 : UTF16); + static long mix(long lengthCoder, char value) { + return checkOverflow(lengthCoder + 1) | (StringLatin1.canEncode(value) ? 0 : UTF16); } /** * Mix value length and coder into current length and coder. - * @param current current length - * @param value value to mix in - * @return new length and coder + * @param lengthCoder String length with coder packed into higher bits + * the upper word. + * @param value value to mix in + * @return new length and coder */ - static long mix(long current, short value) { - return mix(current, (int)value); + static long mix(long lengthCoder, short value) { + return mix(lengthCoder, (int)value); } /** * Mix value length and coder into current length and coder. - * @param current current length - * @param value value to mix in - * @return new length and coder + * @param lengthCoder String length with coder packed into higher bits + * the upper word. + * @param value value to mix in + * @return new length and coder */ - static long mix(long current, int value) { - return checkOverflow(current + Integer.stringSize(value)); + static long mix(long lengthCoder, int value) { + return checkOverflow(lengthCoder + Integer.stringSize(value)); } /** * Mix value length and coder into current length and coder. - * @param current current length - * @param value value to mix in - * @return new length and coder + * @param lengthCoder String length with coder packed into higher bits + * the upper word. + * @param value value to mix in + * @return new length and coder */ - static long mix(long current, long value) { - return checkOverflow(current + Long.stringSize(value)); + static long mix(long lengthCoder, long value) { + return checkOverflow(lengthCoder + Long.stringSize(value)); } /** * Mix value length and coder into current length and coder. - * @param current current length - * @param value value to mix in - * @return new length and coder + * @param lengthCoder String length with coder packed into higher bits + * the upper word. + * @param value value to mix in + * @return new length and coder */ - static long mix(long current, String value) { - current += value.length(); + static long mix(long lengthCoder, String value) { + lengthCoder += value.length(); if (value.coder() == String.UTF16) { - current |= UTF16; + lengthCoder |= UTF16; } - return checkOverflow(current); + return checkOverflow(lengthCoder); } /** @@ -285,10 +297,62 @@ } } + /** + * Perform a simple concatenation between two objects. Added for startup + * performance, but also demonstrates the code that would be emitted by + * {@code java.lang.invoke.StringConcatFactory$MethodHandleInlineCopyStrategy} + * for two Object arguments. + * + * @param first first argument + * @param second second argument + * @return String resulting string + */ + @ForceInline + static String simpleConcat(Object first, Object second) { + String s1 = stringOf(first); + String s2 = stringOf(second); + // start "mixing" in length and coder or arguments, order is not + // important + long indexCoder = mix(initialCoder(), s2); + indexCoder = mix(indexCoder, s1); + byte[] buf = newArray(indexCoder); + // prepend each argument in reverse order, since we prepending + // from the end of the byte array + indexCoder = prepend(indexCoder, buf, s2); + indexCoder = prepend(indexCoder, buf, s1); + return newString(buf, indexCoder); + } + + /** + * We need some additional conversion for Objects in general, because + * {@code String.valueOf(Object)} may return null. String conversion rules + * in Java state we need to produce "null" String in this case, so we + * provide a customized version that deals with this problematic corner case. + */ + static String stringOf(Object value) { + String s; + return (value == null || (s = value.toString()) == null) ? "null" : s; + } + private static final long LATIN1 = (long)String.LATIN1 << 32; private static final long UTF16 = (long)String.UTF16 << 32; + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + + /** + * Allocates an uninitialized byte array based on the length and coder information + * in indexCoder + * @param indexCoder + * @return the newly allocated byte array + */ + @ForceInline + static byte[] newArray(long indexCoder) { + byte coder = (byte)(indexCoder >> 32); + int index = (int)indexCoder; + return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, index << coder); + } + /** * Provides the initial coder for the String. * @return initial coder, adjusted into the upper half
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -26,6 +26,7 @@ package java.lang.invoke; import jdk.internal.misc.Unsafe; +import jdk.internal.misc.VM; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Label; import jdk.internal.org.objectweb.asm.MethodVisitor; @@ -191,6 +192,8 @@ */ private static final ProxyClassesDumper DUMPER; + private static final Class<?> STRING_HELPER; + static { // In case we need to double-back onto the StringConcatFactory during this // static initialization, make sure we have the reasonable defaults to complete @@ -202,15 +205,20 @@ // DEBUG = false; // implied // DUMPER = null; // implied - Properties props = GetPropertyAction.privilegedGetProperties(); + try { + STRING_HELPER = Class.forName("java.lang.StringConcatHelper"); + } catch (Throwable e) { + throw new AssertionError(e); + } + final String strategy = - props.getProperty("java.lang.invoke.stringConcat"); + VM.getSavedProperty("java.lang.invoke.stringConcat"); CACHE_ENABLE = Boolean.parseBoolean( - props.getProperty("java.lang.invoke.stringConcat.cache")); + VM.getSavedProperty("java.lang.invoke.stringConcat.cache")); DEBUG = Boolean.parseBoolean( - props.getProperty("java.lang.invoke.stringConcat.debug")); + VM.getSavedProperty("java.lang.invoke.stringConcat.debug")); final String dumpPath = - props.getProperty("java.lang.invoke.stringConcat.dumpClasses"); + VM.getSavedProperty("java.lang.invoke.stringConcat.dumpClasses"); STRATEGY = (strategy == null) ? DEFAULT_STRATEGY : Strategy.valueOf(strategy); CACHE = CACHE_ENABLE ? new ConcurrentHashMap<>() : null; @@ -1519,6 +1527,33 @@ static MethodHandle generate(MethodType mt, Recipe recipe) throws Throwable { + // Fast-path two-argument Object + Object concatenations + if (recipe.getElements().size() == 2) { + // Two object arguments + if (mt.parameterCount() == 2 && + !mt.parameterType(0).isPrimitive() && + !mt.parameterType(1).isPrimitive()) { + return SIMPLE; + } + // One element is a constant + if (mt.parameterCount() == 1 && !mt.parameterType(0).isPrimitive()) { + MethodHandle mh = SIMPLE; + // Insert constant element + + // First recipe element is a constant + if (recipe.getElements().get(0).getTag() == TAG_CONST && + recipe.getElements().get(1).getTag() != TAG_CONST) { + return MethodHandles.insertArguments(mh, 0, + recipe.getElements().get(0).getValue()); + } else if (recipe.getElements().get(1).getTag() == TAG_CONST && + recipe.getElements().get(0).getTag() != TAG_CONST) { + return MethodHandles.insertArguments(mh, 1, + recipe.getElements().get(1).getValue()); + } + // else... fall-through to slow-path + } + } + // Create filters and obtain filtered parameter types. Filters would be used in the beginning // to convert the incoming arguments into the arguments we can process (e.g. Objects -> Strings). // The filtered argument type list is used all over in the combinators below. @@ -1626,13 +1661,6 @@ return mh; } - @ForceInline - private static byte[] newArray(long indexCoder) { - byte coder = (byte)(indexCoder >> 32); - int index = (int)indexCoder; - return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, index << coder); - } - private static MethodHandle prepender(Class<?> cl) { return PREPENDERS.computeIfAbsent(cl, PREPEND); } @@ -1659,16 +1687,15 @@ } }; + private static final MethodHandle SIMPLE; private static final MethodHandle NEW_STRING; private static final MethodHandle NEW_ARRAY; private static final ConcurrentMap<Class<?>, MethodHandle> PREPENDERS; private static final ConcurrentMap<Class<?>, MethodHandle> MIXERS; private static final long INITIAL_CODER; - static final Class<?> STRING_HELPER; static { try { - STRING_HELPER = Class.forName("java.lang.StringConcatHelper"); MethodHandle initCoder = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "initialCoder", long.class); INITIAL_CODER = (long) initCoder.invoke(); } catch (Throwable e) { @@ -1678,8 +1705,9 @@ PREPENDERS = new ConcurrentHashMap<>(); MIXERS = new ConcurrentHashMap<>(); + SIMPLE = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "simpleConcat", String.class, Object.class, Object.class); NEW_STRING = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "newString", String.class, byte[].class, long.class); - NEW_ARRAY = lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleInlineCopyStrategy.class, "newArray", byte[].class, long.class); + NEW_ARRAY = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "newArray", byte[].class, long.class); } } @@ -1692,22 +1720,8 @@ // no instantiation } - private static class ObjectStringifier { - - // We need some additional conversion for Objects in general, because String.valueOf(Object) - // may return null. String conversion rules in Java state we need to produce "null" String - // in this case, so we provide a customized version that deals with this problematic corner case. - private static String valueOf(Object value) { - String s; - return (value == null || (s = value.toString()) == null) ? "null" : s; - } - - // Could have used MethodHandles.lookup() instead of Lookup.IMPL_LOOKUP, if not for the fact - // java.lang.invoke Lookups are explicitly forbidden to be retrieved using that API. - private static final MethodHandle INSTANCE = - lookupStatic(Lookup.IMPL_LOOKUP, ObjectStringifier.class, "valueOf", String.class, Object.class); - - } + private static final MethodHandle OBJECT_INSTANCE = + lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "stringOf", String.class, Object.class); private static class FloatStringifiers { private static final MethodHandle FLOAT_INSTANCE = @@ -1751,7 +1765,7 @@ */ static MethodHandle forMost(Class<?> t) { if (!t.isPrimitive()) { - return ObjectStringifier.INSTANCE; + return OBJECT_INSTANCE; } else if (t == float.class) { return FloatStringifiers.FLOAT_INSTANCE; } else if (t == double.class) {
--- a/src/java.base/share/classes/java/math/BigDecimal.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/java/math/BigDecimal.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3414,9 +3414,32 @@ */ @Override public long longValue(){ - return (intCompact != INFLATED && scale == 0) ? - intCompact: - toBigInteger().longValue(); + if (intCompact != INFLATED && scale == 0) { + return intCompact; + } else { + // Fastpath zero and small values + if (this.signum() == 0 || fractionOnly() || + // Fastpath very large-scale values that will result + // in a truncated value of zero. If the scale is -64 + // or less, there are at least 64 powers of 10 in the + // value of the numerical result. Since 10 = 2*5, in + // that case there would also be 64 powers of 2 in the + // result, meaning all 64 bits of a long will be zero. + scale <= -64) { + return 0; + } else { + return toBigInteger().longValue(); + } + } + } + + /** + * Return true if a nonzero BigDecimal has an absolute value less + * than one; i.e. only has fraction digits. + */ + private boolean fractionOnly() { + assert this.signum() != 0; + return (this.precision() - this.scale) <= 0; } /** @@ -3434,15 +3457,20 @@ public long longValueExact() { if (intCompact != INFLATED && scale == 0) return intCompact; + + // Fastpath zero + if (this.signum() == 0) + return 0; + + // Fastpath numbers less than 1.0 (the latter can be very slow + // to round if very small) + if (fractionOnly()) + throw new ArithmeticException("Rounding necessary"); + // If more than 19 digits in integer part it cannot possibly fit if ((precision() - scale) > 19) // [OK for negative scale too] throw new java.lang.ArithmeticException("Overflow"); - // Fastpath zero and < 1.0 numbers (the latter can be very slow - // to round if very small) - if (this.signum() == 0) - return 0; - if ((this.precision() - this.scale) <= 0) - throw new ArithmeticException("Rounding necessary"); + // round to an integer, with Exception if decimal part non-0 BigDecimal num = this.setScale(0, ROUND_UNNECESSARY); if (num.precision() >= 19) // need to check carefully @@ -3486,7 +3514,7 @@ public int intValue() { return (intCompact != INFLATED && scale == 0) ? (int)intCompact : - toBigInteger().intValue(); + (int)longValue(); } /**
--- a/src/java.base/share/classes/java/nio/channels/FileChannel.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/java/nio/channels/FileChannel.java Mon Apr 22 10:53:45 2019 +0530 @@ -791,7 +791,7 @@ // -- Memory-mapped buffers -- /** - * A typesafe enumeration for file-mapping modes. + * A file-mapping mode. * * @since 1.4 * @@ -819,6 +819,12 @@ private final String name; + /** + * Constructs an instance of this class. This constructor may be used + * by code in java.base to create file mapping modes beyond the file + * mapping modes defined here. + * @param name the name of the map mode + */ private MapMode(String name) { this.name = name; } @@ -837,8 +843,8 @@ /** * Maps a region of this channel's file directly into memory. * - * <p> A region of a file may be mapped into memory in one of three modes: - * </p> + * <p> The {@code mode} parameter specifies how the region of the file is + * mapped and may be one of the following modes: * * <ul> * @@ -859,6 +865,8 @@ * * </ul> * + * <p> An implementation may support additional map modes. + * * <p> For a read-only mapping, this channel must have been opened for * reading; for a read/write or private mapping, this channel must have * been opened for both reading and writing. @@ -892,7 +900,8 @@ * MapMode#READ_WRITE READ_WRITE}, or {@link MapMode#PRIVATE * PRIVATE} defined in the {@link MapMode} class, according to * whether the file is to be mapped read-only, read/write, or - * privately (copy-on-write), respectively + * privately (copy-on-write), respectively, or an implementation + * specific map mode * * @param position * The position within the file at which the mapped region @@ -905,25 +914,29 @@ * @return The mapped byte buffer * * @throws NonReadableChannelException - * If the {@code mode} is {@link MapMode#READ_ONLY READ_ONLY} but - * this channel was not opened for reading + * If the {@code mode} is {@link MapMode#READ_ONLY READ_ONLY} or + * an implementation specific map mode requiring read access + * but this channel was not opened for reading * * @throws NonWritableChannelException - * If the {@code mode} is {@link MapMode#READ_WRITE READ_WRITE} or - * {@link MapMode#PRIVATE PRIVATE} but this channel was not opened - * for both reading and writing + * If the {@code mode} is {@link MapMode#READ_WRITE READ_WRITE}. + * {@link MapMode#PRIVATE PRIVATE} or an implementation specific + * map mode requiring write access but this channel was not + * opened for both reading and writing * * @throws IllegalArgumentException * If the preconditions on the parameters do not hold * + * @throws UnsupportedOperationException + * If an unsupported map mode is specified + * * @throws IOException * If some other I/O error occurs * * @see java.nio.channels.FileChannel.MapMode * @see java.nio.MappedByteBuffer */ - public abstract MappedByteBuffer map(MapMode mode, - long position, long size) + public abstract MappedByteBuffer map(MapMode mode, long position, long size) throws IOException;
--- a/src/java.base/share/classes/java/time/chrono/JapaneseEra.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/java/time/chrono/JapaneseEra.java Mon Apr 22 10:53:45 2019 +0530 @@ -154,6 +154,8 @@ * The singleton instance for the 'Reiwa' era (2019-05-01 - ) * which has the value 3. The end date of this era is not specified, unless * the Japanese Government defines it. + * + * @since 13 */ public static final JapaneseEra REIWA = new JapaneseEra(3, LocalDate.of(2019, 5, 1));
--- a/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java Mon Apr 22 10:53:45 2019 +0530 @@ -940,14 +940,15 @@ if (size > Integer.MAX_VALUE) throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE"); - int imode = -1; + int imode; if (mode == MapMode.READ_ONLY) imode = MAP_RO; else if (mode == MapMode.READ_WRITE) imode = MAP_RW; else if (mode == MapMode.PRIVATE) imode = MAP_PV; - assert (imode >= 0); + else + throw new UnsupportedOperationException(); if ((mode != MapMode.READ_ONLY) && !writable) throw new NonWritableChannelException(); if (!readable)
--- a/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -28,10 +28,20 @@ package sun.nio.cs; -import java.io.*; -import java.nio.*; -import java.nio.channels.*; -import java.nio.charset.*; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.io.Reader; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.ReadableByteChannel; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.IllegalCharsetNameException; public class StreamDecoder extends Reader { @@ -190,8 +200,11 @@ synchronized (lock) { if (closed) return; - implClose(); - closed = true; + try { + implClose(); + } finally { + closed = true; + } } }
--- a/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -23,15 +23,21 @@ * questions. */ -/* - */ - package sun.nio.cs; -import java.io.*; -import java.nio.*; -import java.nio.channels.*; -import java.nio.charset.*; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.channels.WritableByteChannel; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.IllegalCharsetNameException; public class StreamEncoder extends Writer { @@ -158,8 +164,11 @@ synchronized (lock) { if (closed) return; - implClose(); - closed = true; + try { + implClose(); + } finally { + closed = true; + } } } @@ -337,8 +346,13 @@ writeBytes(); if (ch != null) ch.close(); - else - out.close(); + else { + try { + out.flush(); + } finally { + out.close(); + } + } } catch (IOException x) { encoder.reset(); throw x;
--- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Mon Apr 22 10:53:45 2019 +0530 @@ -980,7 +980,7 @@ } try { - shutdownInput(false); + SSLSocketImpl.this.close(); } catch (IOException ioe) { // ignore the exception if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { @@ -1146,7 +1146,7 @@ } try { - shutdownOutput(); + SSLSocketImpl.this.close(); } catch (IOException ioe) { // ignore the exception if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
--- a/src/java.base/share/native/libjli/java.c Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/share/native/libjli/java.c Mon Apr 22 10:53:45 2019 +0530 @@ -204,11 +204,14 @@ */ static jlong threadStackSize = 0; /* stack size of the new thread */ static jlong maxHeapSize = 0; /* max heap size */ -static jlong initialHeapSize = 0; /* inital heap size */ +static jlong initialHeapSize = 0; /* initial heap size */ /* - * A minimum -Xss stack size suitable for all platforms. - */ + * A minimum initial-thread stack size suitable for most platforms. + * This is the minimum amount of stack needed to load the JVM such + * that it can reject a too small -Xss value. If this is too small + * JVM initialization would cause a StackOverflowError. + */ #ifndef STACK_SIZE_MINIMUM #define STACK_SIZE_MINIMUM (64 * KB) #endif @@ -934,16 +937,18 @@ options[numOptions].optionString = str; options[numOptions++].extraInfo = info; + /* + * -Xss is used both by the JVM and here to establish the stack size of the thread + * created to launch the JVM. In the latter case we need to ensure we don't go + * below the minimum stack size allowed. If -Xss is zero that tells the JVM to use + * 'default' sizes (either from JVM or system configuration, e.g. 'ulimit -s' on linux), + * and is not itself a small stack size that will be rejected. So we ignore -Xss0 here. + */ if (JLI_StrCCmp(str, "-Xss") == 0) { jlong tmp; if (parse_size(str + 4, &tmp)) { threadStackSize = tmp; - /* - * Make sure the thread stack size is big enough that we won't get a stack - * overflow before the JVM startup code can check to make sure the stack - * is big enough. - */ - if (threadStackSize < (jlong)STACK_SIZE_MINIMUM) { + if (threadStackSize > 0 && threadStackSize < (jlong)STACK_SIZE_MINIMUM) { threadStackSize = STACK_SIZE_MINIMUM; } } @@ -2322,38 +2327,38 @@ int argc, char **argv, int mode, char *what, int ret) { - - /* - * If user doesn't specify stack size, check if VM has a preference. - * Note that HotSpot no longer supports JNI_VERSION_1_1 but it will - * return its default stack size through the init args structure. - */ if (threadStackSize == 0) { - struct JDK1_1InitArgs args1_1; - memset((void*)&args1_1, 0, sizeof(args1_1)); - args1_1.version = JNI_VERSION_1_1; - ifn->GetDefaultJavaVMInitArgs(&args1_1); /* ignore return value */ - if (args1_1.javaStackSize > 0) { - threadStackSize = args1_1.javaStackSize; - } + /* + * If the user hasn't specified a non-zero stack size ask the JVM for its default. + * A returned 0 means 'use the system default' for a platform, e.g., Windows. + * Note that HotSpot no longer supports JNI_VERSION_1_1 but it will + * return its default stack size through the init args structure. + */ + struct JDK1_1InitArgs args1_1; + memset((void*)&args1_1, 0, sizeof(args1_1)); + args1_1.version = JNI_VERSION_1_1; + ifn->GetDefaultJavaVMInitArgs(&args1_1); /* ignore return value */ + if (args1_1.javaStackSize > 0) { + threadStackSize = args1_1.javaStackSize; + } } { /* Create a new thread to create JVM and invoke main method */ - JavaMainArgs args; - int rslt; + JavaMainArgs args; + int rslt; - args.argc = argc; - args.argv = argv; - args.mode = mode; - args.what = what; - args.ifn = *ifn; + args.argc = argc; + args.argv = argv; + args.mode = mode; + args.what = what; + args.ifn = *ifn; - rslt = CallJavaMainInNewThread(threadStackSize, (void*)&args); - /* If the caller has deemed there is an error we - * simply return that, otherwise we return the value of - * the callee - */ - return (ret != 0) ? ret : rslt; + rslt = CallJavaMainInNewThread(threadStackSize, (void*)&args); + /* If the caller has deemed there is an error we + * simply return that, otherwise we return the value of + * the callee + */ + return (ret != 0) ? ret : rslt; } }
--- a/src/java.base/windows/native/common/version.rc Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.base/windows/native/common/version.rc Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ // -// Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2004, 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 @@ -55,15 +55,15 @@ BEGIN BLOCK "000004b0" BEGIN - VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" - VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0" - VALUE "FileVersion", XSTR(JDK_VER) "\0" + VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" + VALUE "FileDescription", XSTR(JDK_FILEDESC) "\0" + VALUE "FileVersion", XSTR(JDK_VER) "\0" VALUE "Full Version", XSTR(JDK_VERSION_STRING) "\0" - VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" - VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" - VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" - VALUE "ProductName", XSTR(JDK_NAME) "\0" - VALUE "ProductVersion", XSTR(JDK_VER) "\0" + VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" + VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" + VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" + VALUE "ProductName", XSTR(JDK_NAME) "\0" + VALUE "ProductVersion", XSTR(JDK_VER) "\0" END END BLOCK "VarFileInfo"
--- a/src/java.compiler/share/classes/javax/annotation/processing/ProcessingEnvironment.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.compiler/share/classes/javax/annotation/processing/ProcessingEnvironment.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -131,4 +131,18 @@ * effect */ Locale getLocale(); + + /** + * Returns {@code true} if <em>preview features</em> are enabled + * and {@code false} otherwise. + * @return whether or not preview features are enabled + * + * @implSpec The default implementation of this method returns + * {@code false}. + * + * @since 13 + */ + default boolean isPreviewEnabled() { + return false; + } }
--- a/src/java.desktop/windows/native/libawt/windows/awt.rc Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.desktop/windows/native/libawt/windows/awt.rc Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ // -// Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 1997, 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 @@ -65,15 +65,15 @@ BEGIN BLOCK "040904b0" BEGIN - VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" - VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0" - VALUE "FileVersion", XSTR(JDK_VER) "\0" + VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" + VALUE "FileDescription", XSTR(JDK_FILEDESC) "\0" + VALUE "FileVersion", XSTR(JDK_VER) "\0" VALUE "Full Version", XSTR(JDK_VERSION_STRING) "\0" - VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" - VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" - VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" - VALUE "ProductName", XSTR(JDK_NAME) "\0" - VALUE "ProductVersion", XSTR(JDK_VER) "\0" + VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" + VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" + VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" + VALUE "ProductName", XSTR(JDK_NAME) "\0" + VALUE "ProductVersion", XSTR(JDK_VER) "\0" END END BLOCK "VarFileInfo"
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http1Request.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -103,7 +103,8 @@ HttpClient client = http1Exchange.client(); // Filter overridable headers from userHeaders - userHeaders = HttpHeaders.of(userHeaders.map(), Utils.CONTEXT_RESTRICTED(client)); + userHeaders = HttpHeaders.of(userHeaders.map(), + connection.contextRestricted(request, client)); final HttpHeaders uh = userHeaders;
--- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpConnection.java Mon Apr 22 10:53:45 2019 +0530 @@ -285,6 +285,16 @@ } } + BiPredicate<String,String> contextRestricted(HttpRequestImpl request, HttpClient client) { + if (!isTunnel() && request.isConnect()) { + // establishing a proxy tunnel + assert request.proxy() == null; + return Utils.PROXY_TUNNEL_RESTRICTED(client); + } else { + return Utils.CONTEXT_RESTRICTED(client); + } + } + // Composes a new immutable HttpHeaders that combines the // user and system header but only keeps those headers that // start with "proxy-"
--- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java Mon Apr 22 10:53:45 2019 +0530 @@ -178,7 +178,12 @@ ! (k.equalsIgnoreCase("Authorization") && k.equalsIgnoreCase("Proxy-Authorization")); } + private static final BiPredicate<String, String> HOST_RESTRICTED = (k,v) -> !"host".equalsIgnoreCase(k); + public static final BiPredicate<String, String> PROXY_TUNNEL_RESTRICTED(HttpClient client) { + return CONTEXT_RESTRICTED(client).and(HOST_RESTRICTED); + } + private static final Predicate<String> IS_HOST = "host"::equalsIgnoreCase; private static final Predicate<String> IS_PROXY_HEADER = (k) -> k != null && k.length() > 6 && "proxy-".equalsIgnoreCase(k.substring(0,6)); private static final Predicate<String> NO_PROXY_HEADER = @@ -250,7 +255,8 @@ public static final BiPredicate<String, String> PROXY_TUNNEL_FILTER = (s,v) -> isAllowedForProxy(s, v, PROXY_AUTH_TUNNEL_DISABLED_SCHEMES, - IS_PROXY_HEADER); + // Allows Proxy-* and Host headers when establishing the tunnel. + IS_PROXY_HEADER.or(IS_HOST)); public static final BiPredicate<String, String> PROXY_FILTER = (s,v) -> isAllowedForProxy(s, v, PROXY_AUTH_DISABLED_SCHEMES, ALL_HEADERS);
--- a/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Skel.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Skel.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -58,8 +58,24 @@ public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash) throws java.lang.Exception { - if (hash != interfaceHash) - throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch"); + if (opnum < 0) { + if (hash == 7583982177005850366L) { + opnum = 0; + } else if (hash == 2571371476350237748L) { + opnum = 1; + } else if (hash == -7538657168040752697L) { + opnum = 2; + } else if (hash == -8381844669958460146L) { + opnum = 3; + } else if (hash == 7305022919901907578L) { + opnum = 4; + } else { + throw new java.rmi.UnmarshalException("invalid method hash"); + } + } else { + if (hash != interfaceHash) + throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch"); + } sun.rmi.registry.RegistryImpl server = (sun.rmi.registry.RegistryImpl) obj; switch (opnum) {
--- a/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ import java.rmi.ServerException; import java.rmi.UnmarshalException; import java.rmi.server.ExportException; +import java.rmi.server.Operation; import java.rmi.server.RemoteCall; import java.rmi.server.RemoteRef; import java.rmi.server.RemoteStub; @@ -292,15 +293,14 @@ throw new UnmarshalException("error unmarshalling call header", readEx); } - if (num >= 0) { - if (skel != null) { + if (skel != null) { + // If there is a skeleton, use it oldDispatch(obj, call, num); return; - } else { - throw new UnmarshalException( - "skeleton class not found but required " + - "for client version"); - } + + } else if (num >= 0){ + throw new UnmarshalException( + "skeleton class not found but required for client version"); } try { op = in.readLong(); @@ -428,8 +428,8 @@ /** * Handle server-side dispatch using the RMI 1.1 stub/skeleton - * protocol, given a non-negative operation number that has - * already been read from the call stream. + * protocol, given a non-negative operation number or negative method hash + * that has already been read from the call stream. * Exceptions are handled by the caller to be sent to the remote client. * * @param obj the target remote object for the call @@ -461,7 +461,8 @@ } // if calls are being logged, write out object id and operation - logCall(obj, skel.getOperations()[op]); + Operation[] operations = skel.getOperations(); + logCall(obj, op >= 0 && op < operations.length ? operations[op] : "op: " + op); unmarshalCustomCallData(in); // dispatch to skeleton for remote object skel.dispatch(obj, call, op, hash);
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -22,6 +22,7 @@ import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader; import com.sun.org.apache.xerces.internal.impl.io.UCSReader; +import com.sun.org.apache.xerces.internal.impl.io.UTF16Reader; import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; @@ -89,7 +90,7 @@ * @author K.Venugopal SUN Microsystems * @author Neeraj Bajaj SUN Microsystems * @author Sunitha Reddy SUN Microsystems - * @LastModified: Nov 2018 + * @LastModified: Apr 2019 */ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { @@ -412,9 +413,6 @@ /** Augmentations for entities. */ private final Augmentations fEntityAugs = new AugmentationsImpl(); - /** Pool of character buffers. */ - private CharacterBufferPool fBufferPool = new CharacterBufferPool(fBufferSize, DEFAULT_INTERNAL_BUFFER_SIZE); - /** indicate whether Catalog should be used for resolving external resources */ private boolean fUseCatalog = true; CatalogFeatures fCatalogFeatures; @@ -694,7 +692,8 @@ } // wrap this stream in RewindableInputStream - stream = new RewindableInputStream(stream); + RewindableInputStream rewindableStream = new RewindableInputStream(stream); + stream = rewindableStream; // perform auto-detect of encoding if necessary if (encoding == null) { @@ -702,27 +701,30 @@ final byte[] b4 = new byte[4]; int count = 0; for (; count<4; count++ ) { - b4[count] = (byte)stream.read(); + b4[count] = (byte)rewindableStream.readAndBuffer(); } if (count == 4) { - Object [] encodingDesc = getEncodingName(b4, count); - encoding = (String)(encodingDesc[0]); - isBigEndian = (Boolean)(encodingDesc[1]); - + final EncodingInfo info = getEncodingInfo(b4, count); + encoding = info.autoDetectedEncoding; + final String readerEncoding = info.readerEncoding; + isBigEndian = info.isBigEndian; stream.reset(); - // Special case UTF-8 files with BOM created by Microsoft - // tools. It's more efficient to consume the BOM than make - // the reader perform extra checks. -Ac - if (count > 2 && encoding.equals("UTF-8")) { - int b0 = b4[0] & 0xFF; - int b1 = b4[1] & 0xFF; - int b2 = b4[2] & 0xFF; - if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) { - // ignore first three bytes... + if (info.hasBOM) { + // Special case UTF-8 files with BOM created by Microsoft + // tools. It's more efficient to consume the BOM than make + // the reader perform extra checks. -Ac + if (EncodingInfo.STR_UTF8.equals(readerEncoding)) { + // UTF-8 BOM: 0xEF 0xBB 0xBF stream.skip(3); } + // It's also more efficient to consume the UTF-16 BOM. + else if (EncodingInfo.STR_UTF16.equals(readerEncoding)) { + // UTF-16 BE BOM: 0xFE 0xFF + // UTF-16 LE BOM: 0xFF 0xFE + stream.skip(2); + } } - reader = createReader(stream, encoding, isBigEndian); + reader = createReader(stream, readerEncoding, isBigEndian); } else { reader = createReader(stream, encoding, isBigEndian); } @@ -733,11 +735,11 @@ encoding = encoding.toUpperCase(Locale.ENGLISH); // If encoding is UTF-8, consume BOM if one is present. - if (encoding.equals("UTF-8")) { + if (EncodingInfo.STR_UTF8.equals(encoding)) { final int[] b3 = new int[3]; int count = 0; for (; count < 3; ++count) { - b3[count] = stream.read(); + b3[count] = rewindableStream.readAndBuffer(); if (b3[count] == -1) break; } @@ -750,56 +752,51 @@ stream.reset(); } } - // If encoding is UTF-16, we still need to read the first four bytes - // in order to discover the byte order. - else if (encoding.equals("UTF-16")) { + // If encoding is UTF-16, we still need to read the first + // four bytes, in order to discover the byte order. + else if (EncodingInfo.STR_UTF16.equals(encoding)) { final int[] b4 = new int[4]; int count = 0; for (; count < 4; ++count) { - b4[count] = stream.read(); + b4[count] = rewindableStream.readAndBuffer(); if (b4[count] == -1) break; } stream.reset(); - - String utf16Encoding = "UTF-16"; if (count >= 2) { final int b0 = b4[0]; final int b1 = b4[1]; if (b0 == 0xFE && b1 == 0xFF) { // UTF-16, big-endian - utf16Encoding = "UTF-16BE"; isBigEndian = Boolean.TRUE; + stream.skip(2); } else if (b0 == 0xFF && b1 == 0xFE) { // UTF-16, little-endian - utf16Encoding = "UTF-16LE"; isBigEndian = Boolean.FALSE; + stream.skip(2); } else if (count == 4) { final int b2 = b4[2]; final int b3 = b4[3]; if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) { // UTF-16, big-endian, no BOM - utf16Encoding = "UTF-16BE"; isBigEndian = Boolean.TRUE; } if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) { // UTF-16, little-endian, no BOM - utf16Encoding = "UTF-16LE"; isBigEndian = Boolean.FALSE; } } } - reader = createReader(stream, utf16Encoding, isBigEndian); } // If encoding is UCS-4, we still need to read the first four bytes // in order to discover the byte order. - else if (encoding.equals("ISO-10646-UCS-4")) { + else if (EncodingInfo.STR_UCS4.equals(encoding)) { final int[] b4 = new int[4]; int count = 0; for (; count < 4; ++count) { - b4[count] = stream.read(); + b4[count] = rewindableStream.readAndBuffer(); if (b4[count] == -1) break; } @@ -819,11 +816,11 @@ } // If encoding is UCS-2, we still need to read the first four bytes // in order to discover the byte order. - else if (encoding.equals("ISO-10646-UCS-2")) { + else if (EncodingInfo.STR_UCS2.equals(encoding)) { final int[] b4 = new int[4]; int count = 0; for (; count < 4; ++count) { - b4[count] = stream.read(); + b4[count] = rewindableStream.readAndBuffer(); if (b4[count] == -1) break; } @@ -1798,7 +1795,6 @@ bufferSize.intValue() > DEFAULT_XMLDECL_BUFFER_SIZE) { fBufferSize = bufferSize.intValue(); fEntityScanner.setBufferSize(fBufferSize); - fBufferPool.setExternalBufferSize(fBufferSize); } } if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() && @@ -2425,14 +2421,12 @@ * * @param b4 The first four bytes of the input. * @param count The number of bytes actually read. - * @return a 2-element array: the first element, an IANA-encoding string, - * the second element a Boolean which is true iff the document is big endian, false - * if it's little-endian, and null if the distinction isn't relevant. + * @return an instance of EncodingInfo which represents the auto-detected encoding. */ - protected Object[] getEncodingName(byte[] b4, int count) { + protected EncodingInfo getEncodingInfo(byte[] b4, int count) { if (count < 2) { - return defaultEncoding; + return EncodingInfo.UTF_8; } // UTF-16, with BOM @@ -2440,69 +2434,70 @@ int b1 = b4[1] & 0xFF; if (b0 == 0xFE && b1 == 0xFF) { // UTF-16, big-endian - return new Object [] {"UTF-16BE", true}; + return EncodingInfo.UTF_16_BIG_ENDIAN_WITH_BOM; } if (b0 == 0xFF && b1 == 0xFE) { // UTF-16, little-endian - return new Object [] {"UTF-16LE", false}; + return EncodingInfo.UTF_16_LITTLE_ENDIAN_WITH_BOM; } // default to UTF-8 if we don't have enough bytes to make a // good determination of the encoding if (count < 3) { - return defaultEncoding; + return EncodingInfo.UTF_8; } // UTF-8 with a BOM int b2 = b4[2] & 0xFF; if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) { - return defaultEncoding; + return EncodingInfo.UTF_8_WITH_BOM; } // default to UTF-8 if we don't have enough bytes to make a // good determination of the encoding if (count < 4) { - return defaultEncoding; + return EncodingInfo.UTF_8; } // other encodings int b3 = b4[3] & 0xFF; if (b0 == 0x00 && b1 == 0x00 && b2 == 0x00 && b3 == 0x3C) { // UCS-4, big endian (1234) - return new Object [] {"ISO-10646-UCS-4", true}; + return EncodingInfo.UCS_4_BIG_ENDIAN; } if (b0 == 0x3C && b1 == 0x00 && b2 == 0x00 && b3 == 0x00) { // UCS-4, little endian (4321) - return new Object [] {"ISO-10646-UCS-4", false}; + return EncodingInfo.UCS_4_LITTLE_ENDIAN; } if (b0 == 0x00 && b1 == 0x00 && b2 == 0x3C && b3 == 0x00) { // UCS-4, unusual octet order (2143) // REVISIT: What should this be? - return new Object [] {"ISO-10646-UCS-4", null}; + return EncodingInfo.UCS_4_UNUSUAL_BYTE_ORDER; } if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x00) { // UCS-4, unusual octect order (3412) // REVISIT: What should this be? - return new Object [] {"ISO-10646-UCS-4", null}; + return EncodingInfo.UCS_4_UNUSUAL_BYTE_ORDER; } if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) { // UTF-16, big-endian, no BOM // (or could turn out to be UCS-2... // REVISIT: What should this be? - return new Object [] {"UTF-16BE", true}; + return EncodingInfo.UTF_16_BIG_ENDIAN; } if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) { // UTF-16, little-endian, no BOM // (or could turn out to be UCS-2... - return new Object [] {"UTF-16LE", false}; + return EncodingInfo.UTF_16_LITTLE_ENDIAN; } if (b0 == 0x4C && b1 == 0x6F && b2 == 0xA7 && b3 == 0x94) { // EBCDIC // a la xerces1, return CP037 instead of EBCDIC here - return new Object [] {"CP037", null}; + return EncodingInfo.EBCDIC; } - return defaultEncoding; + // default encoding + return EncodingInfo.UTF_8; } // getEncodingName(byte[],int):Object[] @@ -2517,95 +2512,95 @@ * encoding name may be a Java encoding name; * otherwise, it is an ianaEncoding name. * @param isBigEndian For encodings (like uCS-4), whose names cannot - * specify a byte order, this tells whether the order is bigEndian. null menas - * unknown or not relevant. + * specify a byte order, this tells whether the order + * is bigEndian. null if unknown or irrelevant. * * @return Returns a reader. */ protected Reader createReader(InputStream inputStream, String encoding, Boolean isBigEndian) - throws IOException { - - // normalize encoding name - if (encoding == null) { - encoding = "UTF-8"; - } - - // try to use an optimized reader - String ENCODING = encoding.toUpperCase(Locale.ENGLISH); - if (ENCODING.equals("UTF-8")) { - if (DEBUG_ENCODINGS) { - System.out.println("$$$ creating UTF8Reader"); - } - return new UTF8Reader(inputStream, fBufferSize, fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN), fErrorReporter.getLocale() ); - } - if (ENCODING.equals("US-ASCII")) { - if (DEBUG_ENCODINGS) { - System.out.println("$$$ creating ASCIIReader"); - } - return new ASCIIReader(inputStream, fBufferSize, fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN), fErrorReporter.getLocale()); - } - if(ENCODING.equals("ISO-10646-UCS-4")) { - if(isBigEndian != null) { - boolean isBE = isBigEndian.booleanValue(); - if(isBE) { - return new UCSReader(inputStream, UCSReader.UCS4BE); + throws IOException { + + String enc = (encoding != null) ? encoding : EncodingInfo.STR_UTF8; + enc = enc.toUpperCase(Locale.ENGLISH); + MessageFormatter f = fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN); + Locale l = fErrorReporter.getLocale(); + switch (enc) { + case EncodingInfo.STR_UTF8: + return new UTF8Reader(inputStream, fBufferSize, f, l); + case EncodingInfo.STR_UTF16: + if (isBigEndian != null) { + return new UTF16Reader(inputStream, fBufferSize, isBigEndian, f, l); + } + break; + case EncodingInfo.STR_UTF16BE: + return new UTF16Reader(inputStream, fBufferSize, true, f, l); + case EncodingInfo.STR_UTF16LE: + return new UTF16Reader(inputStream, fBufferSize, false, f, l); + case EncodingInfo.STR_UCS4: + if(isBigEndian != null) { + if(isBigEndian) { + return new UCSReader(inputStream, UCSReader.UCS4BE); + } else { + return new UCSReader(inputStream, UCSReader.UCS4LE); + } } else { - return new UCSReader(inputStream, UCSReader.UCS4LE); + fErrorReporter.reportError(this.getEntityScanner(), + XMLMessageFormatter.XML_DOMAIN, + "EncodingByteOrderUnsupported", + new Object[] { encoding }, + XMLErrorReporter.SEVERITY_FATAL_ERROR); } - } else { - fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN, - "EncodingByteOrderUnsupported", - new Object[] { encoding }, - XMLErrorReporter.SEVERITY_FATAL_ERROR); - } - } - if(ENCODING.equals("ISO-10646-UCS-2")) { - if(isBigEndian != null) { // sould never happen with this encoding... - boolean isBE = isBigEndian.booleanValue(); - if(isBE) { - return new UCSReader(inputStream, UCSReader.UCS2BE); + break; + case EncodingInfo.STR_UCS2: + if(isBigEndian != null) { + if(isBigEndian) { + return new UCSReader(inputStream, UCSReader.UCS2BE); + } else { + return new UCSReader(inputStream, UCSReader.UCS2LE); + } } else { - return new UCSReader(inputStream, UCSReader.UCS2LE); + fErrorReporter.reportError(this.getEntityScanner(), + XMLMessageFormatter.XML_DOMAIN, + "EncodingByteOrderUnsupported", + new Object[] { encoding }, + XMLErrorReporter.SEVERITY_FATAL_ERROR); } - } else { - fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN, - "EncodingByteOrderUnsupported", - new Object[] { encoding }, - XMLErrorReporter.SEVERITY_FATAL_ERROR); - } + break; } // check for valid name boolean validIANA = XMLChar.isValidIANAEncoding(encoding); boolean validJava = XMLChar.isValidJavaEncoding(encoding); if (!validIANA || (fAllowJavaEncodings && !validJava)) { - fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN, + fErrorReporter.reportError(this.getEntityScanner(), + XMLMessageFormatter.XML_DOMAIN, "EncodingDeclInvalid", new Object[] { encoding }, XMLErrorReporter.SEVERITY_FATAL_ERROR); - // NOTE: AndyH suggested that, on failure, we use ISO Latin 1 - // because every byte is a valid ISO Latin 1 character. - // It may not translate correctly but if we failed on - // the encoding anyway, then we're expecting the content - // of the document to be bad. This will just prevent an - // invalid UTF-8 sequence to be detected. This is only - // important when continue-after-fatal-error is turned - // on. -Ac + // NOTE: AndyH suggested that, on failure, we use ISO Latin 1 + // because every byte is a valid ISO Latin 1 character. + // It may not translate correctly but if we failed on + // the encoding anyway, then we're expecting the content + // of the document to be bad. This will just prevent an + // invalid UTF-8 sequence to be detected. This is only + // important when continue-after-fatal-error is turned + // on. -Ac encoding = "ISO-8859-1"; } // try to use a Java reader - String javaEncoding = EncodingMap.getIANA2JavaMapping(ENCODING); + String javaEncoding = EncodingMap.getIANA2JavaMapping(enc); if (javaEncoding == null) { - if(fAllowJavaEncodings) { + if (fAllowJavaEncodings) { javaEncoding = encoding; } else { - fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN, + fErrorReporter.reportError(this.getEntityScanner(), + XMLMessageFormatter.XML_DOMAIN, "EncodingDeclInvalid", new Object[] { encoding }, XMLErrorReporter.SEVERITY_FATAL_ERROR); - // see comment above. - javaEncoding = "ISO8859_1"; + // see comment above. + javaEncoding = "ISO8859_1"; } } if (DEBUG_ENCODINGS) { @@ -2898,108 +2893,78 @@ } // print() /** - * Buffer used in entity manager to reuse character arrays instead - * of creating new ones every time. - * - * @xerces.internal - * - * @author Ankit Pasricha, IBM - */ - private static class CharacterBuffer { - - /** character buffer */ - private char[] ch; - - /** whether the buffer is for an external or internal scanned entity */ - private boolean isExternal; - - public CharacterBuffer(boolean isExternal, int size) { - this.isExternal = isExternal; - ch = new char[size]; - } - } - - - /** - * Stores a number of character buffers and provides it to the entity - * manager to use when an entity is seen. + * Information about auto-detectable encodings. * * @xerces.internal * - * @author Ankit Pasricha, IBM + * @author Michael Glavassevich, IBM */ - private static class CharacterBufferPool { - - private static final int DEFAULT_POOL_SIZE = 3; - - private CharacterBuffer[] fInternalBufferPool; - private CharacterBuffer[] fExternalBufferPool; - - private int fExternalBufferSize; - private int fInternalBufferSize; - private int poolSize; - - private int fInternalTop; - private int fExternalTop; - - public CharacterBufferPool(int externalBufferSize, int internalBufferSize) { - this(DEFAULT_POOL_SIZE, externalBufferSize, internalBufferSize); - } - - public CharacterBufferPool(int poolSize, int externalBufferSize, int internalBufferSize) { - fExternalBufferSize = externalBufferSize; - fInternalBufferSize = internalBufferSize; - this.poolSize = poolSize; - init(); - } - - /** Initializes buffer pool. **/ - private void init() { - fInternalBufferPool = new CharacterBuffer[poolSize]; - fExternalBufferPool = new CharacterBuffer[poolSize]; - fInternalTop = -1; - fExternalTop = -1; - } - - /** Retrieves buffer from pool. **/ - public CharacterBuffer getBuffer(boolean external) { - if (external) { - if (fExternalTop > -1) { - return fExternalBufferPool[fExternalTop--]; - } - else { - return new CharacterBuffer(true, fExternalBufferSize); - } - } - else { - if (fInternalTop > -1) { - return fInternalBufferPool[fInternalTop--]; - } - else { - return new CharacterBuffer(false, fInternalBufferSize); - } - } - } - - /** Returns buffer to pool. **/ - public void returnToPool(CharacterBuffer buffer) { - if (buffer.isExternal) { - if (fExternalTop < fExternalBufferPool.length - 1) { - fExternalBufferPool[++fExternalTop] = buffer; - } - } - else if (fInternalTop < fInternalBufferPool.length - 1) { - fInternalBufferPool[++fInternalTop] = buffer; - } - } - - /** Sets the size of external buffers and dumps the old pool. **/ - public void setExternalBufferSize(int bufferSize) { - fExternalBufferSize = bufferSize; - fExternalBufferPool = new CharacterBuffer[poolSize]; - fExternalTop = -1; - } - } + private static class EncodingInfo { + public static final String STR_UTF8 = "UTF-8"; + public static final String STR_UTF16 = "UTF-16"; + public static final String STR_UTF16BE = "UTF-16BE"; + public static final String STR_UTF16LE = "UTF-16LE"; + public static final String STR_UCS4 = "ISO-10646-UCS-4"; + public static final String STR_UCS2 = "ISO-10646-UCS-2"; + public static final String STR_CP037 = "CP037"; + + /** UTF-8 **/ + public static final EncodingInfo UTF_8 = + new EncodingInfo(STR_UTF8, null, false); + + /** UTF-8, with BOM **/ + public static final EncodingInfo UTF_8_WITH_BOM = + new EncodingInfo(STR_UTF8, null, true); + + /** UTF-16, big-endian **/ + public static final EncodingInfo UTF_16_BIG_ENDIAN = + new EncodingInfo(STR_UTF16BE, STR_UTF16, Boolean.TRUE, false); + + /** UTF-16, big-endian with BOM **/ + public static final EncodingInfo UTF_16_BIG_ENDIAN_WITH_BOM = + new EncodingInfo(STR_UTF16BE, STR_UTF16, Boolean.TRUE, true); + + /** UTF-16, little-endian **/ + public static final EncodingInfo UTF_16_LITTLE_ENDIAN = + new EncodingInfo(STR_UTF16LE, STR_UTF16, Boolean.FALSE, false); + + /** UTF-16, little-endian with BOM **/ + public static final EncodingInfo UTF_16_LITTLE_ENDIAN_WITH_BOM = + new EncodingInfo(STR_UTF16LE, STR_UTF16, Boolean.FALSE, true); + + /** UCS-4, big-endian **/ + public static final EncodingInfo UCS_4_BIG_ENDIAN = + new EncodingInfo(STR_UCS4, Boolean.TRUE, false); + + /** UCS-4, little-endian **/ + public static final EncodingInfo UCS_4_LITTLE_ENDIAN = + new EncodingInfo(STR_UCS4, Boolean.FALSE, false); + + /** UCS-4, unusual byte-order (2143) or (3412) **/ + public static final EncodingInfo UCS_4_UNUSUAL_BYTE_ORDER = + new EncodingInfo(STR_UCS4, null, false); + + /** EBCDIC **/ + public static final EncodingInfo EBCDIC = new EncodingInfo(STR_CP037, null, false); + + public final String autoDetectedEncoding; + public final String readerEncoding; + public final Boolean isBigEndian; + public final boolean hasBOM; + + private EncodingInfo(String autoDetectedEncoding, Boolean isBigEndian, boolean hasBOM) { + this(autoDetectedEncoding, autoDetectedEncoding, isBigEndian, hasBOM); + } // <init>(String,Boolean,boolean) + + private EncodingInfo(String autoDetectedEncoding, String readerEncoding, + Boolean isBigEndian, boolean hasBOM) { + this.autoDetectedEncoding = autoDetectedEncoding; + this.readerEncoding = readerEncoding; + this.isBigEndian = isBigEndian; + this.hasBOM = hasBOM; + } // <init>(String,String,Boolean,boolean) + + } // class EncodingInfo /** * This class wraps the byte inputstreams we're presented with. @@ -3052,20 +3017,13 @@ fOffset = fStartOffset; } - public int read() throws IOException { - int b = 0; - if (fOffset < fLength) { - return fData[fOffset++] & 0xff; - } - if (fOffset == fEndOffset) { - return -1; - } + public int readAndBuffer() throws IOException { if (fOffset == fData.length) { byte[] newData = new byte[fOffset << 1]; System.arraycopy(fData, 0, newData, 0, fOffset); fData = newData; } - b = fInputStream.read(); + final int b = fInputStream.read(); if (b == -1) { fEndOffset = fOffset; return -1; @@ -3075,18 +3033,27 @@ return b & 0xff; } + public int read() throws IOException { + if (fOffset < fLength) { + return fData[fOffset++] & 0xff; + } + if (fOffset == fEndOffset) { + return -1; + } + if (fCurrentEntity.mayReadChunks) { + return fInputStream.read(); + } + return readAndBuffer(); + } + public int read(byte[] b, int off, int len) throws IOException { - int bytesLeft = fLength - fOffset; + final int bytesLeft = fLength - fOffset; if (bytesLeft == 0) { if (fOffset == fEndOffset) { return -1; } - /** - * //System.out.println("fCurrentEntitty = " + fCurrentEntity ); - * //System.out.println("fInputStream = " + fInputStream ); - * // better get some more for the voracious reader... */ - + // read a block of data as requested if(fCurrentEntity.mayReadChunks || !fCurrentEntity.xmlDeclChunkRead) { if (!fCurrentEntity.xmlDeclChunkRead) @@ -3096,15 +3063,13 @@ } return fInputStream.read(b, off, len); } - - int returnedVal = read(); - if(returnedVal == -1) { - fEndOffset = fOffset; - return -1; + int returnedVal = readAndBuffer(); + if (returnedVal == -1) { + fEndOffset = fOffset; + return -1; } b[off] = (byte)returnedVal; return 1; - } if (len < bytesLeft) { if (len <= 0) { @@ -3120,8 +3085,7 @@ return len; } - public long skip(long n) - throws IOException { + public long skip(long n) throws IOException { int bytesLeft; if (n <= 0) { return 0; @@ -3142,7 +3106,7 @@ return bytesLeft; } n -= bytesLeft; - /* + /* * In a manner of speaking, when this class isn't permitting more * than one byte at a time to be read, it is "blocking". The * available() method should indicate how much can be read without @@ -3154,13 +3118,13 @@ } public int available() throws IOException { - int bytesLeft = fLength - fOffset; + final int bytesLeft = fLength - fOffset; if (bytesLeft == 0) { if (fOffset == fEndOffset) { return -1; } return fCurrentEntity.mayReadChunks ? fInputStream.available() - : 0; + : 0; } return bytesLeft; } @@ -3171,7 +3135,6 @@ public void reset() { fOffset = fMark; - //test(); } public boolean markSupported() {
--- a/src/jdk.accessibility/windows/native/common/AccessBridgeStatusWindow.RC Tue Apr 16 10:09:11 2019 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" -#include "accessBridgeResource.h" - -#define XSTR(x) STR(x) -#define STR(x) #x - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -ACCESSBRIDGESTATUSWINDOW DIALOGEX 160, 78, 209, 163 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_CLIENTEDGE -CAPTION "Access Bridge status" -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - EDITTEXT cVMID,67,23,121,13,ES_READONLY - EDITTEXT cStatusText,40,147,162,13,ES_READONLY - LTEXT "Java VM ID:",IDC_STATIC,23,25,40,8 - LTEXT "Status:",IDC_STATIC,11,149,23,8 - EDITTEXT cWindowsID,67,39,121,13,ES_READONLY - LTEXT "Windows ID:",IDC_STATIC,21,41,42,8 - EDITTEXT cCallInfo,12,65,184,75,ES_MULTILINE | ES_AUTOVSCROLL | - ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL - GROUPBOX "Call info",IDC_STATIC,4,55,197,90 - EDITTEXT cInvokedByText,67,1,121,13,ES_READONLY - LTEXT "Invoked by:",IDC_STATIC,25,3,38,8 -END - -IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Dialog" -FONT 8, "MS Sans Serif" -BEGIN - DEFPUSHBUTTON "OK",IDOK,129,7,50,14 - PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - "ACCESSBRIDGESTATUSWINDOW", DIALOG - BEGIN - LEFTMARGIN, 4 - RIGHTMARGIN, 202 - BOTTOMMARGIN, 160 - END - - "IDD_DIALOG1", DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 179 - TOPMARGIN, 7 - BOTTOMMARGIN, 88 - END -END -#endif // APSTUDIO_INVOKED - - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION JDK_FVER - PRODUCTVERSION JDK_FVER - FILEFLAGSMASK 0x3fL -#ifdef DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE JDK_FTYPE - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "Java Access Bridge\0" - VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" - VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0" - VALUE "FileVersion", XSTR(JDK_VER) "\0" - VALUE "Full Version", XSTR(JDK_VERSION_STRING) "\0" - VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" - VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" - VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" - VALUE "ProductName", XSTR(JDK_NAME) "\0" - VALUE "ProductVersion", XSTR(JDK_VER) "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // !_MAC - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.accessibility/windows/native/common/AccessBridgeStatusWindow.rc Mon Apr 22 10:53:45 2019 +0530 @@ -0,0 +1,174 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" +#include "accessBridgeResource.h" + +#define XSTR(x) STR(x) +#define STR(x) #x + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +ACCESSBRIDGESTATUSWINDOW DIALOGEX 160, 78, 209, 163 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CLIENTEDGE +CAPTION "Access Bridge status" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + EDITTEXT cVMID,67,23,121,13,ES_READONLY + EDITTEXT cStatusText,40,147,162,13,ES_READONLY + LTEXT "Java VM ID:",IDC_STATIC,23,25,40,8 + LTEXT "Status:",IDC_STATIC,11,149,23,8 + EDITTEXT cWindowsID,67,39,121,13,ES_READONLY + LTEXT "Windows ID:",IDC_STATIC,21,41,42,8 + EDITTEXT cCallInfo,12,65,184,75,ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL + GROUPBOX "Call info",IDC_STATIC,4,55,197,90 + EDITTEXT cInvokedByText,67,1,121,13,ES_READONLY + LTEXT "Invoked by:",IDC_STATIC,25,3,38,8 +END + +IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14 +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + "ACCESSBRIDGESTATUSWINDOW", DIALOG + BEGIN + LEFTMARGIN, 4 + RIGHTMARGIN, 202 + BOTTOMMARGIN, 160 + END + + "IDD_DIALOG1", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 88 + END +END +#endif // APSTUDIO_INVOKED + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION JDK_FVER + PRODUCTVERSION JDK_FVER + FILEFLAGSMASK 0x3fL +#ifdef DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE JDK_FTYPE + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "Java Access Bridge" "\0" + VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" + VALUE "FileDescription", XSTR(JDK_FILEDESC) "\0" + VALUE "FileVersion", XSTR(JDK_VER) "\0" + VALUE "Full Version", XSTR(JDK_VERSION_STRING) "\0" + VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" + VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" + VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" + VALUE "ProductName", XSTR(JDK_NAME) "\0" + VALUE "ProductVersion", XSTR(JDK_VER) "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED
--- a/src/jdk.accessibility/windows/native/common/resource.h Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.accessibility/windows/native/common/resource.h Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,7 +25,7 @@ //{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. -// Used by AccessBridgeStatusWindow.RC +// Used by AccessBridgeStatusWindow.rc // //#define IDB_BITMAP1 102
--- a/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspectorWindow.rc Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.accessibility/windows/native/jaccessinspector/jaccessinspectorWindow.rc Mon Apr 22 10:53:45 2019 +0530 @@ -199,15 +199,15 @@ BEGIN BLOCK "000004b0" BEGIN - VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" - VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0" - VALUE "FileVersion", XSTR(JDK_VER) "\0" + VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" + VALUE "FileDescription", XSTR(JDK_FILEDESC) "\0" + VALUE "FileVersion", XSTR(JDK_VER) "\0" VALUE "Full Version", XSTR(JDK_VERSION_STRING) "\0" - VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" - VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" - VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" - VALUE "ProductName", XSTR(JDK_NAME) "\0" - VALUE "ProductVersion", XSTR(JDK_VER) "\0" + VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" + VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" + VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" + VALUE "ProductName", XSTR(JDK_NAME) "\0" + VALUE "ProductVersion", XSTR(JDK_VER) "\0" END END BLOCK "VarFileInfo"
--- a/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalkerWindow.rc Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.accessibility/windows/native/jaccesswalker/jaccesswalkerWindow.rc Mon Apr 22 10:53:45 2019 +0530 @@ -164,15 +164,15 @@ BEGIN BLOCK "000004b0" BEGIN - VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" - VALUE "FileDescription", XSTR(JDK_COMPONENT) "\0" - VALUE "FileVersion", XSTR(JDK_VER) "\0" + VALUE "CompanyName", XSTR(JDK_COMPANY) "\0" + VALUE "FileDescription", XSTR(JDK_FILEDESC) "\0" + VALUE "FileVersion", XSTR(JDK_VER) "\0" VALUE "Full Version", XSTR(JDK_VERSION_STRING) "\0" - VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" - VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" - VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" - VALUE "ProductName", XSTR(JDK_NAME) "\0" - VALUE "ProductVersion", XSTR(JDK_VER) "\0" + VALUE "InternalName", XSTR(JDK_INTERNAL_NAME) "\0" + VALUE "LegalCopyright", XSTR(JDK_COPYRIGHT) "\0" + VALUE "OriginalFilename", XSTR(JDK_FNAME) "\0" + VALUE "ProductName", XSTR(JDK_NAME) "\0" + VALUE "ProductVersion", XSTR(JDK_VER) "\0" END END BLOCK "VarFileInfo"
--- a/src/jdk.compiler/share/classes/com/sun/source/util/JavacTask.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/source/util/JavacTask.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -29,6 +29,7 @@ import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; +import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; @@ -137,6 +138,27 @@ public abstract void removeTaskListener(TaskListener taskListener); /** + * Sets the specified {@link ParameterNameProvider}. It may be used when + * {@link VariableElement#getSimpleName()} is called for a method parameter + * for which an authoritative name is not found. The given + * {@code ParameterNameProvider} may infer a user-friendly name + * for the method parameter. + * + * Setting a new {@code ParameterNameProvider} will clear any previously set + * {@code ParameterNameProvider}, which won't be queried any more. + * + * When no {@code ParameterNameProvider} is set, or when it returns null from + * {@link ParameterNameProvider#getParameterName(javax.lang.model.element.VariableElement)}, + * an automatically synthesized name is returned from {@code VariableElement.getSimpleName()}. + * + * @implSpec The default implementation of this method does nothing. + * + * @param provider the provider. + * @since 13 + */ + public void setParameterNameProvider(ParameterNameProvider provider) {} + + /** * Returns a type mirror of the tree node determined by the specified path. * This method has been superceded by methods on * {@link com.sun.source.util.Trees Trees}.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.compiler/share/classes/com/sun/source/util/ParameterNameProvider.java Mon Apr 22 10:53:45 2019 +0530 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.source.util; + +import javax.lang.model.element.VariableElement; + +/** + * A provider for parameter names when the parameter names are not determined from + * a reliable source, like a classfile. + * + * @since 13 + */ +public interface ParameterNameProvider { + + /** + * Infer a parameter name for the given parameter. The implementations of this method + * should infer parameter names in such a way that the parameter names are distinct + * for any given owning method. + * + * If the implementation of this method returns null, an automatically synthesized name is used. + * + * @param parameter the parameter for which the name should be inferred. + * @return a user-friendly name for the parameter, or null if unknown + */ + public CharSequence getParameterName(VariableElement parameter); + +}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/BasicJavacTask.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -43,9 +43,11 @@ import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.Tree; import com.sun.source.util.JavacTask; +import com.sun.source.util.ParameterNameProvider; import com.sun.source.util.Plugin; import com.sun.source.util.TaskListener; import com.sun.tools.doclint.DocLint; +import com.sun.tools.javac.code.MissingInfoHandler; import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.model.JavacTypes; @@ -123,6 +125,11 @@ mtl.remove(taskListener); } + @Override + public void setParameterNameProvider(ParameterNameProvider handler) { + MissingInfoHandler.instance(context).setDelegate(handler); + } + public Collection<TaskListener> getTaskListeners() { MultiTaskListener mtl = MultiTaskListener.instance(context); return mtl.getTaskListeners();
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -319,6 +319,11 @@ */ public static final long BODY_ONLY_FINALIZE = 1L<<17; //blocks only + /** + * Flag to indicate the given ParamSymbol has a user-friendly name filled. + */ + public static final long NAME_FILLED = 1L<<58; //ParamSymbols only + /** Modifier masks. */ public static final int @@ -435,7 +440,8 @@ DEPRECATED_REMOVAL(Flags.DEPRECATED_REMOVAL), HAS_RESOURCE(Flags.HAS_RESOURCE), POTENTIALLY_AMBIGUOUS(Flags.POTENTIALLY_AMBIGUOUS), - ANONCONSTR_BASED(Flags.ANONCONSTR_BASED); + ANONCONSTR_BASED(Flags.ANONCONSTR_BASED), + NAME_FILLED(Flags.NAME_FILLED); Flag(long flag) { this.value = flag;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/MissingInfoHandler.java Mon Apr 22 10:53:45 2019 +0530 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javac.code; + +import com.sun.source.util.ParameterNameProvider; +import com.sun.tools.javac.code.Symbol.ParamSymbol; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.Name; +import com.sun.tools.javac.util.Names; + +/** + * A Context class, that can return additional useful information for Symbols, currently + * parameter names. It does so by calling user-supplied {@link ParameterNameProvider}. + * + * <p><b>This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice.</b> + */ +public class MissingInfoHandler { + protected static final Context.Key<MissingInfoHandler> missingInfoHandlerWrapperKey = new Context.Key<>(); + + public static MissingInfoHandler instance(Context context) { + MissingInfoHandler instance = context.get(missingInfoHandlerWrapperKey); + if (instance == null) + instance = new MissingInfoHandler(context); + return instance; + } + + private final Names names; + private ParameterNameProvider parameterNameProvider; + + protected MissingInfoHandler(Context context) { + context.put(missingInfoHandlerWrapperKey, this); + names = Names.instance(context); + } + + public Name getParameterName(ParamSymbol parameter) { + if (parameterNameProvider != null) { + CharSequence name = parameterNameProvider.getParameterName(parameter); + if (name != null) { + return names.fromString(name.toString()); + } + } + + return null; + } + + public void setDelegate(ParameterNameProvider delegate) { + this.parameterNameProvider = delegate; + } +}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -55,6 +55,7 @@ import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.jvm.*; +import com.sun.tools.javac.jvm.PoolConstant; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.JCTree.Tag; @@ -65,9 +66,12 @@ import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.Kind.*; +import com.sun.tools.javac.code.MissingInfoHandler; import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; import com.sun.tools.javac.code.Scope.WriteableScope; +import com.sun.tools.javac.code.Symbol; import static com.sun.tools.javac.code.Symbol.OperatorSymbol.AccessCode.FIRSTASGOP; +import com.sun.tools.javac.code.Type; import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.FORALL; import static com.sun.tools.javac.code.TypeTag.TYPEVAR; @@ -76,6 +80,7 @@ import static com.sun.tools.javac.jvm.ByteCodes.lushrl; import static com.sun.tools.javac.jvm.ByteCodes.lxor; import static com.sun.tools.javac.jvm.ByteCodes.string_add; +import com.sun.tools.javac.util.Name; /** Root class for Java symbols. It contains subclasses * for specific sorts of symbols, such as variables, methods and operators, @@ -87,7 +92,7 @@ * This code and its internal interfaces are subject to change or * deletion without notice.</b> */ -public abstract class Symbol extends AnnoConstruct implements Element { +public abstract class Symbol extends AnnoConstruct implements PoolConstant, Element { /** The kind of this symbol. * @see Kinds @@ -282,6 +287,11 @@ this.name = name; } + @Override + public int poolTag() { + throw new AssertionError("Invalid pool entry"); + } + /** Clone this symbol with new owner. * Legal only for fields and methods. */ @@ -967,6 +977,11 @@ this.type = new ModuleType(this); } + @Override + public int poolTag() { + return ClassFile.CONSTANT_Module; + } + @Override @DefinedBy(Api.LANGUAGE_MODEL) public Name getSimpleName() { return Convert.shortName(name); @@ -1133,6 +1148,11 @@ return members_field; } + @Override + public int poolTag() { + return ClassFile.CONSTANT_Package; + } + public long flags() { complete(); return flags_field; @@ -1189,6 +1209,16 @@ } + public static class RootPackageSymbol extends PackageSymbol { + public final MissingInfoHandler missingInfoHandler; + + public RootPackageSymbol(Name name, Symbol owner, MissingInfoHandler missingInfoHandler) { + super(name, owner); + this.missingInfoHandler = missingInfoHandler; + } + + } + /** A class for class symbols */ public static class ClassSymbol extends TypeSymbol implements TypeElement { @@ -1223,10 +1253,6 @@ */ public List<ClassSymbol> trans_local; - /** the constant pool of the class - */ - public Pool pool; - /** the annotation metadata attached to this class */ private AnnotationTypeMetadata annotationTypeMetadata; @@ -1237,7 +1263,6 @@ this.flatname = formFlatName(name, owner); this.sourcefile = null; this.classfile = null; - this.pool = null; this.annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType(); } @@ -1529,6 +1554,11 @@ super(VAR, flags, name, type, owner); } + @Override + public int poolTag() { + return ClassFile.CONSTANT_Fieldref; + } + /** Clone this symbol with new owner. */ public VarSymbol clone(Symbol newOwner) { @@ -1537,6 +1567,11 @@ public Symbol baseSymbol() { return VarSymbol.this; } + + @Override + public Object poolKey(Types types) { + return new Pair<>(newOwner, baseSymbol()); + } }; v.pos = pos; v.adr = adr; @@ -1634,6 +1669,32 @@ } } + public static class ParamSymbol extends VarSymbol { + public ParamSymbol(long flags, Name name, Type type, Symbol owner) { + super(flags, name, type, owner); + } + + @Override + public Name getSimpleName() { + if ((flags_field & NAME_FILLED) == 0) { + flags_field |= NAME_FILLED; + Symbol rootPack = this; + while (rootPack != null && !(rootPack instanceof RootPackageSymbol)) { + rootPack = rootPack.owner; + } + if (rootPack != null) { + Name inferredName = + ((RootPackageSymbol) rootPack).missingInfoHandler.getParameterName(this); + if (inferredName != null) { + this.name = inferredName; + } + } + } + return super.getSimpleName(); + } + + } + /** A class for method symbols. */ public static class MethodSymbol extends Symbol implements ExecutableElement { @@ -1671,6 +1732,11 @@ public Symbol baseSymbol() { return MethodSymbol.this; } + + @Override + public Object poolKey(Types types) { + return new Pair<>(newOwner, baseSymbol()); + } }; m.code = code; return m; @@ -1700,10 +1766,25 @@ } } + @Override + public int poolTag() { + return owner.isInterface() ? + ClassFile.CONSTANT_InterfaceMethodref : ClassFile.CONSTANT_Methodref; + } + public boolean isDynamic() { return false; } + public boolean isHandle() { + return false; + } + + + public MethodHandleSymbol asHandle() { + return new MethodHandleSymbol(this); + } + /** find a symbol that this (proxy method) symbol implements. * @param c The class whose members are searched for * implementations @@ -1987,16 +2068,14 @@ /** A class for invokedynamic method calls. */ - public static class DynamicMethodSymbol extends MethodSymbol { + public static class DynamicMethodSymbol extends MethodSymbol implements Dynamic { - public Object[] staticArgs; - public Symbol bsm; - public int bsmKind; + public LoadableConstant[] staticArgs; + public MethodHandleSymbol bsm; - public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) { + public DynamicMethodSymbol(Name name, Symbol owner, MethodHandleSymbol bsm, Type type, LoadableConstant[] staticArgs) { super(0, name, type, owner); this.bsm = bsm; - this.bsmKind = bsmKind; this.staticArgs = staticArgs; } @@ -2004,6 +2083,83 @@ public boolean isDynamic() { return true; } + + @Override + public LoadableConstant[] staticArgs() { + return staticArgs; + } + + @Override + public MethodHandleSymbol bootstrapMethod() { + return bsm; + } + + @Override + public int poolTag() { + return ClassFile.CONSTANT_InvokeDynamic; + } + + @Override + public Type dynamicType() { + return type; + } + } + + /** A class for method handles. + */ + public static class MethodHandleSymbol extends MethodSymbol implements LoadableConstant { + + private Symbol refSym; + + public MethodHandleSymbol(Symbol msym) { + super(msym.flags_field, msym.name, msym.type, msym.owner); + this.refSym = msym; + } + + /** + * Returns the kind associated with this method handle. + */ + public int referenceKind() { + if (refSym.isConstructor()) { + return ClassFile.REF_newInvokeSpecial; + } else { + if (refSym.isStatic()) { + return ClassFile.REF_invokeStatic; + } else if ((refSym.flags() & PRIVATE) != 0) { + return ClassFile.REF_invokeSpecial; + } else if (refSym.enclClass().isInterface()) { + return ClassFile.REF_invokeInterface; + } else { + return ClassFile.REF_invokeVirtual; + } + } + } + + @Override + public int poolTag() { + return ClassFile.CONSTANT_MethodHandle; + } + + @Override + public Object poolKey(Types types) { + return new Pair<>(baseSymbol(), referenceKind()); + } + + @Override + public MethodHandleSymbol asHandle() { + return this; + } + + @Override + public Symbol baseSymbol() { + return refSym; + } + + + @Override + public boolean isHandle() { + return true; + } } /** A class for predefined operators.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Mon Apr 22 10:53:45 2019 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -42,6 +42,7 @@ import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.ModuleSymbol; import com.sun.tools.javac.code.Symbol.PackageSymbol; +import com.sun.tools.javac.code.Symbol.RootPackageSymbol; import com.sun.tools.javac.code.Symbol.TypeSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Type.BottomType; @@ -382,7 +383,9 @@ messages = JavacMessages.instance(context); - rootPackage = new PackageSymbol(names.empty, null); + MissingInfoHandler missingInfoHandler = MissingInfoHandler.instance(context); + + rootPackage = new RootPackageSymbol(names.empty, null, missingInfoHandler); // create the basic builtin symbols unnamedModule = new ModuleSymbol(names.empty, null) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java Mon Apr 22 10:53:45 2019 +0530 @@ -36,7 +36,10 @@ import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.TypeMetadata.Entry; import com.sun.tools.javac.code.Types.TypeMapping; +import com.sun.tools.javac.code.Types.UniqueType; import com.sun.tools.javac.comp.Infer.IncorporationAction; +import com.sun.tools.javac.jvm.ClassFile; +import com.sun.tools.javac.jvm.PoolConstant; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.DefinedBy.Api; @@ -73,7 +76,7 @@ * * @see TypeTag */ -public abstract class Type extends AnnoConstruct implements TypeMirror { +public abstract class Type extends AnnoConstruct implements TypeMirror, PoolConstant { /** * Type metadata, Should be {@code null} for the default value. @@ -125,6 +128,16 @@ */ public TypeSymbol tsym; + @Override + public int poolTag() { + throw new AssertionError("Invalid pool entry"); + } + + @Override + public Object poolKey(Types types) { + return new UniqueType(this, types); + } + /** * Checks if the current type tag is equal to the given tag. * @return true if tag is equal to the current type tag. @@ -930,7 +943,7 @@ } } - public static class ClassType extends Type implements DeclaredType, + public static class ClassType extends Type implements DeclaredType, LoadableConstant, javax.lang.model.type.ErrorType { /** The enclosing type of this type. If this is the type of an inner @@ -975,6 +988,10 @@ this.interfaces_field = null; } + public int poolTag() { + return ClassFile.CONSTANT_Class; + } + @Override public ClassType cloneWithMetadata(TypeMetadata md) { return new ClassType(outer_field, typarams_field, tsym, md) { @@ -1277,7 +1294,7 @@ } public static class ArrayType extends Type - implements javax.lang.model.type.ArrayType { + implements LoadableConstant, javax.lang.model.type.ArrayType { public Type elemtype; @@ -1297,6 +1314,10 @@ this(that.elemtype, that.tsym, that.getMetadata()); } + public int poolTag() { + return ClassFile.CONSTANT_Class; + } + @Override public ArrayType cloneWithMetadata(TypeMetadata md) { return new ArrayType(elemtype, tsym, md) { @@ -1412,7 +1433,7 @@ } } - public static class MethodType extends Type implements ExecutableType { + public static class MethodType extends Type implements ExecutableType, LoadableConstant { public List<Type> argtypes; public Type restype; @@ -1479,6 +1500,11 @@ restype != null && restype.isErroneous(); } + @Override + public int poolTag() { + return ClassFile.CONSTANT_MethodType; + } + public boolean contains(Type elem) { return elem.equalsIgnoreMetadata(this) || contains(argtypes, elem) || restype.contains(elem) || contains(thrown, elem); }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Mon Apr 22 10:53:45 2019 +0530 @@ -48,6 +48,8 @@ import com.sun.tools.javac.comp.Check; import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.comp.Env; +import com.sun.tools.javac.comp.LambdaToMethod; +import com.sun.tools.javac.jvm.ClassFile; import com.sun.tools.javac.util.*; import static com.sun.tools.javac.code.BoundKind.*; @@ -5181,6 +5183,29 @@ } } } + + public Type constantType(LoadableConstant c) { + switch (c.poolTag()) { + case ClassFile.CONSTANT_Class: + return syms.classType; + case ClassFile.CONSTANT_String: + return syms.stringType; + case ClassFile.CONSTANT_Integer: + return syms.intType; + case ClassFile.CONSTANT_Float: + return syms.floatType; + case ClassFile.CONSTANT_Long: + return syms.longType; + case ClassFile.CONSTANT_Double: + return syms.doubleType; + case ClassFile.CONSTANT_MethodHandle: + return syms.methodHandleType; + case ClassFile.CONSTANT_MethodType: + return syms.methodTypeType; + default: + throw new AssertionError("Not a loadable constant: " + c.poolTag()); + } + } // </editor-fold> public void newRound() {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Mon Apr 22 10:53:45 2019 +0530 @@ -25,7 +25,9 @@ package com.sun.tools.javac.comp; +import com.sun.tools.javac.code.Symbol.MethodHandleSymbol; import com.sun.tools.javac.code.Types.SignatureGenerator.InvalidSignatureException; +import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant; import com.sun.tools.javac.resources.CompilerProperties.Errors; import com.sun.tools.javac.resources.CompilerProperties.Fragments; import com.sun.tools.javac.tree.*; @@ -59,7 +61,6 @@ import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -70,13 +71,10 @@ import static com.sun.tools.javac.code.Kinds.Kind.*; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*; -import static com.sun.tools.javac.jvm.Pool.DynamicMethod; import javax.lang.model.element.ElementKind; import javax.lang.model.type.TypeKind; -import com.sun.tools.javac.code.Type.IntersectionClassType; -import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError; import com.sun.tools.javac.main.Option; /** @@ -214,7 +212,7 @@ private Map<DedupedLambda, DedupedLambda> dedupedLambdas; - private Map<DynamicMethod, DynamicMethodSymbol> dynMethSyms = new HashMap<>(); + private Map<Object, DynamicMethodSymbol> dynMethSyms = new HashMap<>(); /** * list of deserialization cases @@ -439,11 +437,8 @@ //then, determine the arguments to the indy call List<JCExpression> indy_args = translate(syntheticInits.toList(), localContext.prev); - //build a sam instance using an indy call to the meta-factory - int refKind = referenceKind(sym); - //convert to an invokedynamic call - result = makeMetafactoryIndyCall(context, refKind, sym, indy_args); + result = makeMetafactoryIndyCall(context, sym.asHandle(), indy_args); } // where @@ -488,7 +483,7 @@ //first determine the method symbol to be used to generate the sam instance //this is either the method reference symbol, or the bridged reference symbol - Symbol refSym = tree.sym; + MethodSymbol refSym = (MethodSymbol)tree.sym; //the qualifying expression is treated as a special captured arg JCExpression init; @@ -522,7 +517,7 @@ //build a sam instance using an indy call to the meta-factory - result = makeMetafactoryIndyCall(localContext, localContext.referenceKind(), refSym, indy_args); + result = makeMetafactoryIndyCall(localContext, refSym.asHandle(), indy_args); } /** @@ -765,8 +760,8 @@ rs.resolveConstructor(null, attrEnv, ctype, TreeInfo.types(args), List.nil())); } - private void addDeserializationCase(int implMethodKind, Symbol refSym, Type targetType, MethodSymbol samSym, - DiagnosticPosition pos, List<Object> staticArgs, MethodType indyType) { + private void addDeserializationCase(MethodHandleSymbol refSym, Type targetType, MethodSymbol samSym, + DiagnosticPosition pos, List<LoadableConstant> staticArgs, MethodType indyType) { String functionalInterfaceClass = classSig(targetType); String functionalInterfaceMethodName = samSym.getSimpleName().toString(); String functionalInterfaceMethodSignature = typeSig(types.erasure(samSym.type)); @@ -774,7 +769,8 @@ String implMethodName = refSym.getQualifiedName().toString(); String implMethodSignature = typeSig(types.erasure(refSym.type)); - JCExpression kindTest = eqTest(syms.intType, deserGetter("getImplMethodKind", syms.intType), make.Literal(implMethodKind)); + JCExpression kindTest = eqTest(syms.intType, deserGetter("getImplMethodKind", syms.intType), + make.Literal(refSym.referenceKind())); ListBuffer<JCExpression> serArgs = new ListBuffer<>(); int i = 0; for (Type t : indyType.getParameterTypes()) { @@ -1106,13 +1102,13 @@ * Generate an indy method call to the meta factory */ private JCExpression makeMetafactoryIndyCall(TranslationContext<?> context, - int refKind, Symbol refSym, List<JCExpression> indy_args) { + MethodHandleSymbol refSym, List<JCExpression> indy_args) { JCFunctionalExpression tree = context.tree; //determine the static bsm args MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.target.tsym); - List<Object> staticArgs = List.of( + List<LoadableConstant> staticArgs = List.of( typeToMethodType(samSym.type), - new Pool.MethodHandle(refKind, refSym, types), + ((MethodSymbol)refSym).asHandle(), typeToMethodType(tree.getDescriptorType(types))); //computed indy arg types @@ -1131,7 +1127,7 @@ names.altMetafactory : names.metafactory; if (context.needsAltMetafactory()) { - ListBuffer<Object> markers = new ListBuffer<>(); + ListBuffer<Type> markers = new ListBuffer<>(); List<Type> targets = tree.target.isIntersection() ? types.directSupertypes(tree.target) : List.nil(); @@ -1140,7 +1136,7 @@ if (t.tsym != syms.serializableType.tsym && t.tsym != tree.type.tsym && t.tsym != syms.objectType.tsym) { - markers.append(t.tsym); + markers.append(t); } } int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0; @@ -1152,17 +1148,17 @@ if (hasBridges) { flags |= FLAG_BRIDGES; } - staticArgs = staticArgs.append(flags); + staticArgs = staticArgs.append(LoadableConstant.Int(flags)); if (hasMarkers) { - staticArgs = staticArgs.append(markers.length()); - staticArgs = staticArgs.appendList(markers.toList()); + staticArgs = staticArgs.append(LoadableConstant.Int(markers.length())); + staticArgs = staticArgs.appendList(List.convert(LoadableConstant.class, markers.toList())); } if (hasBridges) { - staticArgs = staticArgs.append(context.bridges.length() - 1); + staticArgs = staticArgs.append(LoadableConstant.Int(context.bridges.length() - 1)); for (Symbol s : context.bridges) { Type s_erasure = s.erasure(types); if (!types.isSameType(s_erasure, samSym.erasure(types))) { - staticArgs = staticArgs.append(s.erasure(types)); + staticArgs = staticArgs.append(((MethodType)s.erasure(types))); } } } @@ -1170,7 +1166,7 @@ int prevPos = make.pos; try { make.at(kInfo.clazz); - addDeserializationCase(refKind, refSym, tree.type, samSym, + addDeserializationCase(refSym, tree.type, samSym, tree, staticArgs, indyType); } finally { make.at(prevPos); @@ -1186,14 +1182,14 @@ * arguments types */ private JCExpression makeIndyCall(DiagnosticPosition pos, Type site, Name bsmName, - List<Object> staticArgs, MethodType indyType, List<JCExpression> indyArgs, - Name methName) { + List<LoadableConstant> staticArgs, MethodType indyType, List<JCExpression> indyArgs, + Name methName) { int prevPos = make.pos; try { make.at(pos); List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType, - syms.stringType, - syms.methodTypeType).appendList(bsmStaticArgToTypes(staticArgs)); + syms.stringType, + syms.methodTypeType).appendList(staticArgs.map(types::constantType)); Symbol bsm = rs.resolveInternalMethod(pos, attrEnv, site, bsmName, bsm_staticArgs, List.nil()); @@ -1201,15 +1197,12 @@ DynamicMethodSymbol dynSym = new DynamicMethodSymbol(methName, syms.noSymbol, - bsm.isStatic() ? - ClassFile.REF_invokeStatic : - ClassFile.REF_invokeVirtual, - (MethodSymbol)bsm, + ((MethodSymbol)bsm).asHandle(), indyType, - staticArgs.toArray()); + staticArgs.toArray(new LoadableConstant[staticArgs.length()])); JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), bsmName); DynamicMethodSymbol existing = kInfo.dynMethSyms.putIfAbsent( - new DynamicMethod(dynSym, types), dynSym); + dynSym.poolKey(types), dynSym); qualifier.sym = existing != null ? existing : dynSym; qualifier.type = indyType.getReturnType(); @@ -1220,57 +1213,6 @@ make.at(prevPos); } } - //where - private List<Type> bsmStaticArgToTypes(List<Object> args) { - ListBuffer<Type> argtypes = new ListBuffer<>(); - for (Object arg : args) { - argtypes.append(bsmStaticArgToType(arg)); - } - return argtypes.toList(); - } - - private Type bsmStaticArgToType(Object arg) { - Assert.checkNonNull(arg); - if (arg instanceof ClassSymbol) { - return syms.classType; - } else if (arg instanceof Integer) { - return syms.intType; - } else if (arg instanceof Long) { - return syms.longType; - } else if (arg instanceof Float) { - return syms.floatType; - } else if (arg instanceof Double) { - return syms.doubleType; - } else if (arg instanceof String) { - return syms.stringType; - } else if (arg instanceof Pool.MethodHandle) { - return syms.methodHandleType; - } else if (arg instanceof MethodType) { - return syms.methodTypeType; - } else { - Assert.error("bad static arg " + arg.getClass()); - return null; - } - } - - /** - * Get the opcode associated with this method reference - */ - private int referenceKind(Symbol refSym) { - if (refSym.isConstructor()) { - return ClassFile.REF_newInvokeSpecial; - } else { - if (refSym.isStatic()) { - return ClassFile.REF_invokeStatic; - } else if ((refSym.flags() & PRIVATE) != 0) { - return ClassFile.REF_invokeSpecial; - } else if (refSym.enclClass().isInterface()) { - return ClassFile.REF_invokeInterface; - } else { - return ClassFile.REF_invokeVirtual; - } - } - } // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer"> /** @@ -2312,13 +2254,6 @@ this.isSuper = tree.hasKind(ReferenceKind.SUPER); } - /** - * Get the opcode associated with this method reference - */ - int referenceKind() { - return LambdaToMethod.this.referenceKind(tree.sym); - } - boolean needsVarArgsConversion() { return tree.varargsElement != null; }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Mon Apr 22 10:53:45 2019 +0530 @@ -93,7 +93,6 @@ private final Attr attr; private TreeMaker make; private DiagnosticPosition make_pos; - private final ClassWriter writer; private final ConstFold cfolder; private final Target target; private final Source source; @@ -116,7 +115,6 @@ chk = Check.instance(context); attr = Attr.instance(context); make = TreeMaker.instance(context); - writer = ClassWriter.instance(context); cfolder = ConstFold.instance(context); target = Target.instance(context); source = Source.instance(context); @@ -475,7 +473,7 @@ .fromString(target.syntheticNameChar() + "SwitchMap" + target.syntheticNameChar() + - writer.xClassName(forEnum.type).toString() + names.fromUtf(ClassWriter.externalize(forEnum.type.tsym.flatName())).toString() .replace('/', '.') .replace('.', target.syntheticNameChar())); ClassSymbol outerCacheClass = outerCacheClass();
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java Mon Apr 22 10:53:45 2019 +0530 @@ -25,9 +25,6 @@ package com.sun.tools.javac.jvm; -import com.sun.tools.javac.code.Type; -import com.sun.tools.javac.code.Types; -import com.sun.tools.javac.code.Types.UniqueType; import com.sun.tools.javac.util.Name; @@ -189,38 +186,4 @@ public static byte[] externalize(Name name) { return externalize(name.getByteArray(), name.getByteOffset(), name.getByteLength()); } - -/************************************************************************ - * Name-and-type - ***********************************************************************/ - - /** A class for the name-and-type signature of a method or field. - */ - public static class NameAndType { - Name name; - UniqueType uniqueType; - Types types; - - NameAndType(Name name, Type type, Types types) { - this.name = name; - this.uniqueType = new UniqueType(type, types); - this.types = types; - } - - void setType(Type type) { - this.uniqueType = new UniqueType(type, types); - } - - @Override - public boolean equals(Object other) { - return (other instanceof NameAndType && - name == ((NameAndType) other).name && - uniqueType.equals(((NameAndType) other).uniqueType)); - } - - @Override - public int hashCode() { - return name.hashCode() * uniqueType.hashCode(); - } - } }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Apr 16 10:09:11 2019 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Mon Apr 22 10:53:45 2019 +0530 @@ -36,6 +36,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.function.IntFunction; import javax.lang.model.element.Modifier; import javax.lang.model.element.NestingKind; @@ -55,8 +56,8 @@ import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata; import com.sun.tools.javac.file.BaseFileManager; import com.sun.tools.javac.file.PathFileObject; -import com.sun.tools.javac.jvm.ClassFile.NameAndType; import com.sun.tools.javac.jvm.ClassFile.Version; +import com.sun.tools.javac.jvm.PoolConstant.NameAndType; import com.sun.tools.javac.main.Option; import com.sun.tools.javac.resources.CompilerProperties.Fragments; import com.sun.tools.javac.resources.CompilerProperties.Warnings; @@ -100,11 +101,6 @@ */ boolean verbose; - /** Switch: read constant pool and code sections. This switch is initially - * set to false but can be turned on from outside. - */ - public boolean readAllOfClassFile = false; - /** Switch: allow modules. */ boolean allowModules; @@ -170,20 +166,15 @@ /** The buffer containing the currently read class file. */ - byte[] buf = new byte[INITIAL_BUFFER_SIZE]; + ByteBuffer buf = new ByteBuffer(INITIAL_BUFFER_SIZE); /** The current input pointer. */ protected int bp; - /** The objects of the constant pool. + /** The pool reader. */ - Object[] poolObj; - - /** For every constant pool entry, an index into buf where the - * defining section of the entry is found. - */ - int[] poolIdx; + PoolReader poolReader; /** The major version number of the class file being read. */ int majorVersion; @@ -323,294 +314,29 @@ /** Read a character. */ char nextChar() { - return (char)(((buf[bp++] & 0xFF) << 8) + (buf[bp++] & 0xFF)); + char res = buf.getChar(bp); + bp += 2; + return res; } /** Read a byte. */ int nextByte() { - return buf[bp++] & 0xFF; + return buf.getByte(bp++) & 0xFF; } /** Read an integer. */ int nextInt() { - return - ((buf[bp++] & 0xFF) << 24) + - ((buf[bp++] & 0xFF) << 16) + - ((buf[bp++] & 0xFF) << 8) + - (buf[bp++] & 0xFF); - } - - /** Extract a character at position bp from buf. - */ - char getChar(int bp) { - return - (char)(((buf[bp] & 0xFF) << 8) + (buf[bp+1] & 0xFF)); - } - - /** Extract an integer at position bp from buf. - */ - int getInt(int bp) { - return - ((buf[bp] & 0xFF) << 24) + - ((buf[bp+1] & 0xFF) << 16) + - ((buf[bp+2] & 0xFF) << 8) + - (buf[bp+3] & 0xFF); - } - - - /** Extract a long integer at position bp from buf. - */ - long getLong(int bp) { - DataInputStream bufin = - new DataInputStream(new ByteArrayInputStream(buf, bp, 8)); - try { - return bufin.readLong(); - } catch (IOException e) { - throw new AssertionError(e); - } - } - - /** Extract a float at position bp from buf. - */ - float getFloat(int bp) { - DataInputStream bufin = - new DataInputStream(new ByteArrayInputStream(buf, bp, 4)); - try { - return bufin.readFloat(); - } catch (IOException e) { - throw new AssertionError(e); - } - } - - /** Extract a double at position bp from buf. - */ - double getDouble(int bp) { - DataInputStream bufin = - new DataInputStream(new ByteArrayInputStream(buf, bp, 8)); - try { - return bufin.readDouble(); - } catch (IOException e) { - throw new AssertionError(e); - } + int res = buf.getInt(bp); + bp += 4; + return res; } /************************************************************************ * Constant Pool Access ***********************************************************************/ - /** Index all constant pool entries, writing their start addresses into - * poolIdx. - */ - void indexPool() { - poolIdx = new int[nextChar()]; - poolObj = new Object[poolIdx.length]; - int i = 1; - while (i < poolIdx.length) { - poolIdx[i++] = bp; - byte tag = buf[bp++]; - switch (tag) { - case CONSTANT_Utf8: case CONSTANT_Unicode: { - int len = nextChar(); - bp = bp + len; - break; - } - case CONSTANT_Class: - case CONSTANT_String: - case CONSTANT_MethodType: - case CONSTANT_Module: - case CONSTANT_Package: - bp = bp + 2; - break; - case CONSTANT_MethodHandle: - bp = bp + 3; - break; - case CONSTANT_Fieldref: - case CONSTANT_Methodref: - case CONSTANT_InterfaceMethodref: - case CONSTANT_NameandType: - case CONSTANT_Integer: - case CONSTANT_Float: - case CONSTANT_Dynamic: - case CONSTANT_InvokeDynamic: - bp = bp + 4; - break; - case CONSTANT_Long: - case CONSTANT_Double: - bp = bp + 8; - i++; - break; - default: - throw badClassFile("bad.const.pool.tag.at", - Byte.toString(tag), - Integer.toString(bp -1)); - } - } - } - - /** Read constant pool entry at start address i, use pool as a cache. - */ - Object readPool(int i) { - Object result = poolObj[i]; - if (result != null) return result; - - int index = poolIdx[i]; - if (index == 0) return null; - - byte tag = buf[index]; - switch (tag) { - case CONSTANT_Utf8: - poolObj[i] = names.fromUtf(buf, index + 3, getChar(index + 1)); - break; - case CONSTANT_Unicode: - throw badClassFile("unicode.str.not.supported"); - case CONSTANT_Class: - poolObj[i] = readClassOrType(getChar(index + 1)); - break; - case CONSTANT_String: - // FIXME: (footprint) do not use toString here - poolObj[i] = readName(getChar(index + 1)).toString(); - break; - case CONSTANT_Fieldref: { - ClassSymbol owner = readClassSymbol(getChar(index + 1)); - NameAndType nt = readNameAndType(getChar(index + 3)); - poolObj[i] = new VarSymbol(0, nt.name, nt.uniqueType.type, owner); - break; - } - case CONSTANT_Methodref: - case CONSTANT_InterfaceMethodref: { - ClassSymbol owner = readClassSymbol(getChar(index + 1)); - NameAndType nt = readNameAndType(getChar(index + 3)); - poolObj[i] = new MethodSymbol(0, nt.name, nt.uniqueType.type, owner); - break; - } - case CONSTANT_NameandType: - poolObj[i] = new NameAndType( - readName(getChar(index + 1)), - readType(getChar(index + 3)), types); - break; - case CONSTANT_Integer: - poolObj[i] = getInt(index + 1); - break; - case CONSTANT_Float: - poolObj[i] = Float.valueOf(getFloat(index + 1)); - break; - case CONSTANT_Long: - poolObj[i] = Long.valueOf(getLong(index + 1)); - break; - case CONSTANT_Double: - poolObj[i] = Double.valueOf(getDouble(index + 1)); - break; - case CONSTANT_MethodHandle: - skipBytes(4); - break; - case CONSTANT_MethodType: - skipBytes(3); - break; - case CONSTANT_Dynamic: - case CONSTANT_InvokeDynamic: - skipBytes(5); - break; - case CONSTANT_Module: - case CONSTANT_Package: - // this is temporary for now: treat as a simple reference to the underlying Utf8. - poolObj[i] = readName(getChar(index + 1)); - break; - default: - throw badClassFile("bad.const.pool.tag", Byte.toString(tag)); - } - return poolObj[i]; - } - - /** Read signature and convert to type. - */ - Type readType(int i) { - int index = poolIdx[i]; - return sigToType(buf, index + 3, getChar(index + 1)); - } - - /** If name is an array type or class signature, return the - * corresponding type; otherwise return a ClassSymbol with given name. - */ - Object readClassOrType(int i) { - int index = poolIdx[i]; - int len = getChar(index + 1); - int start = index + 3; - Assert.check(buf[start] == '[' || buf[start + len - 1] != ';'); - // by the above assertion, the following test can be - // simplified to (buf[start] == '[') - return (buf[start] == '[' || buf[start + len - 1] == ';') - ? (Object)sigToType(buf, start, len) - : (Object)enterClass(names.fromUtf(internalize(buf, start, - len))); - } - - /** Read signature and convert to type parameters. - */ - List<Type> readTypeParams(int i) { - int index = poolIdx[i]; - return sigToTypeParams(buf, index + 3, getChar(index + 1)); - } - - /** Read class entry. - */ - ClassSymbol readClassSymbol(int i) { - Object obj = readPool(i); - if (obj != null && !(obj instanceof ClassSymbol)) - throw badClassFile("bad.const.pool.entry", - currentClassFile.toString(), - "CONSTANT_Class_info", i); - return (ClassSymbol)obj; - } - - Name readClassName(int i) { - int index = poolIdx[i]; - if (index == 0) return null; - byte tag = buf[index]; - if (tag != CONSTANT_Class) { - throw badClassFile("bad.const.pool.entry", - currentClassFile.toString(), - "CONSTANT_Class_info", i); - } - int nameIndex = poolIdx[getChar(index + 1)]; - int len = getChar(nameIndex + 1); - int start = nameIndex + 3; - if (buf[start] == '[' || buf[start + len - 1] == ';') - throw badClassFile("wrong class name"); //TODO: proper diagnostics - return names.fromUtf(internalize(buf, start, len)); - } - - /** Read name. - */ - Name readName(int i) { - Object obj = readPool(i); - if (obj != null && !(obj instanceof Name)) - throw badClassFile("bad.const.pool.entry", - currentClassFile.toString(), - "CONSTANT_Utf8_info or CONSTANT_String_info", i); - return (Name)obj; - } - - /** Read name and type. - */ - NameAndType readNameAndType(int i) { - Object obj = readPool(i); - if (obj != null && !(obj instanceof NameAndType)) - throw badClassFile("bad.const.pool.entry", - currentClassFile.toString(), - "CONSTANT_NameAndType_info", i); - return (NameAndType)obj; - } - - /** Read the name of a module. - * The name is stored in a CONSTANT_Module entry, in - * JVMS 4.2 binary form (using ".", not "/") - */ - Name readModuleName(int i) { - return readName(i); - } - /** Read module_flags. */ Set<ModuleFlags> readModuleFlags(int flags) { @@ -762,7 +488,7 @@ List<Type> argtypes = sigToTypes(')'); Type restype = sigToType(); List<Type> thrown = List.nil(); - while (signature[sigp] == '^') { + while (sigp < siglimit && signature[sigp] == '^') { sigp++; thrown = thrown.prepend(sigToType()); } @@ -855,7 +581,7 @@ }; switch (signature[sigp++]) { case ';': - if (sigp < signature.length && signature[sigp] == '.') { + if (sigp < siglimit && signature[sigp] == '.') { // support old-style GJC signatures // The signature produced was // Lfoo/Outer<Lfoo/X;>;.Lfoo/Outer$Inner<Lfoo/Y;>; @@ -1049,7 +775,7 @@ new AttributeReader(names.Code, V45_3, MEMBER_ATTRIBUTE) { protected void read(Symbol sym, int attrLen) { - if (readAllOfClassFile || saveParameterNames) + if (saveParameterNames) ((MethodSymbol)sym).code = readCode(sym); else bp = bp + attrLen; @@ -1058,7 +784,7 @@ new AttributeReader(names.ConstantValue, V45_3, MEMBER_ATTRIBUTE) { protected void read(Symbol sym, int attrLen) { - Object v = readPool(nextChar()); + Object v = poolReader.getConstant(nextChar()); // Ignore ConstantValue attribute if field not final. if ((sym.flags() & FINAL) == 0) { return; @@ -1115,7 +841,7 @@ int nexceptions = nextChar(); List<Type> thrown = List.nil(); for (int j = 0; j < nexceptions; j++) - thrown = thrown.prepend(readClassSymbol(nextChar()).type); + thrown = thrown.prepend(poolReader.getClass(nextChar()).type); if (sym.type.getThrownTypes().isEmpty()) sym.type.asMethodType().thrown = thrown.reverse(); } @@ -1173,7 +899,7 @@ new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) { protected void read(Symbol sym, int attrLen) { ClassSymbol c = (ClassSymbol) sym; - Name n = readName(nextChar()); + Name n = poolReader.getName(nextChar()); c.sourcefile = new SourceFileObject(n); // If the class is a toplevel class, originating from a Java source file, // but the class name does not match the file name, then it is @@ -1211,7 +937,8 @@ try { ClassType ct1 = (ClassType)c.type; Assert.check(c == currentOwner); - ct1.typarams_field = readTypeParams(nextChar()); + ct1.typarams_field = poolReader.getName(nextChar()) + .map(ClassReader.this::sigToTypeParams); ct1.supertype_field = sigToType(); ListBuffer<Type> is = new ListBuffer<>(); while (sigp != siglimit) is.append(sigToType()); @@ -1221,7 +948,7 @@ } } else { List<Type> thrown = sym.type.getThrownTypes(); - sym.type = readType(nextChar()); + sym.type = poolReader.getType(nextChar()); //- System.err.println(" # " + sym.type); if (sym.kind == MTH && sym.type.getThrownTypes().isEmpty()) sym.type.asMethodType().thrown = thrown; @@ -1342,19 +1069,19 @@ ModuleSymbol msym = (ModuleSymbol) sym.owner; ListBuffer<Directive> directives = new ListBuffer<>(); - Name moduleName = readModuleName(nextChar()); + Name moduleName = poolReader.peekModuleName(nextChar(), names::fromUtf); if (currentModule.name != moduleName) { throw badClassFile("module.name.mismatch", moduleName, currentModule.name); } Set<ModuleFlags> moduleFlags = readModuleFlags(nextChar()); msym.flags.addAll(moduleFlags); - msym.version = readName(nextChar()); + msym.version = optPoolEntry(nextChar(), poolReader::getName, null); ListBuffer<RequiresDirective> requires = new ListBuffer<>(); int nrequires = nextChar(); for (int i = 0; i < nrequires; i++) { - ModuleSymbol rsym = syms.enterModule(readModuleName(nextChar())); + ModuleSymbol rsym = poolReader.getModule(nextChar()); Set<RequiresFlag> flags = readRequiresFlags(nextChar()); if (rsym == syms.java_base && majorVersion >= V54.major) { if (flags.contains(RequiresFlag.TRANSITIVE)) { @@ -1373,8 +1100,7 @@ ListBuffer<ExportsDirective> exports = new ListBuffer<>(); int nexports = nextChar(); for (int i = 0; i < nexports; i++) { - Name n = readName(nextChar()); - PackageSymbol p = syms.enterPackage(currentModule, names.fromUtf(internalize(n))); + PackageSymbol p = poolReader.getPackage(nextChar()); Set<ExportsFlag> flags = readExportsFlags(nextChar()); int nto = nextChar(); List<ModuleSymbol> to; @@ -1383,7 +1109,7 @@ } else { ListBuffer<ModuleSymbol> lb = new ListBuffer<>(); for (int t = 0; t < nto; t++) - lb.append(syms.enterModule(readModuleName(nextChar()))); + lb.append(poolReader.getModule(nextChar())); to = lb.toList(); } exports.add(new ExportsDirective(p, to, flags)); @@ -1396,8 +1122,7 @@ throw badClassFile("module.non.zero.opens", currentModule.name); } for (int i = 0; i < nopens; i++) { - Name n = readName(nextChar()); - PackageSymbol p = syms.enterPackage(currentModule, names.fromUtf(internalize(n))); + PackageSymbol p = poolReader.getPackage(nextChar()); Set<OpensFlag> flags = readOpensFlags(nextChar()); int nto = nextChar(); List<ModuleSymbol> to; @@ -1406,7 +1131,7 @@ } else { ListBuffer<ModuleSymbol> lb = new ListBuffer<>(); for (int t = 0; t < nto; t++) - lb.append(syms.enterModule(readModuleName(nextChar()))); + lb.append(poolReader.getModule(nextChar())); to = lb.toList(); } opens.add(new OpensDirective(p, to, flags)); @@ -1419,7 +1144,7 @@ ListBuffer<InterimUsesDirective> uses = new ListBuffer<>(); int nuses = nextChar(); for (int i = 0; i < nuses; i++) { - Name srvc = readClassName(nextChar()); + Name srvc = poolReader.peekClassName(nextChar(), this::classNameMapper); uses.add(new InterimUsesDirective(srvc)); } interimUses = uses.toList(); @@ -1427,17 +1152,21 @@ ListBuffer<InterimProvidesDirective> provides = new ListBuffer<>(); int nprovides = nextChar(); for (int p = 0; p < nprovides; p++) { - Name srvc = readClassName(nextChar()); + Name srvc = poolReader.peekClassName(nextChar(), this::classNameMapper); int nimpls = nextChar(); ListBuffer<Name> impls = new ListBuffer<>(); for (int i = 0; i < nimpls; i++) { -