diff --git a/.github/actions/get-msys2/action.yml b/.github/actions/get-msys2/action.yml index 7dac1538536c6..d36957e3b37e6 100644 --- a/.github/actions/get-msys2/action.yml +++ b/.github/actions/get-msys2/action.yml @@ -1,5 +1,5 @@ # -# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/.github/workflows/build-cross-compile.yml b/.github/workflows/build-cross-compile.yml index 5db69f07d98c5..77620640f13bc 100644 --- a/.github/workflows/build-cross-compile.yml +++ b/.github/workflows/build-cross-compile.yml @@ -1,5 +1,5 @@ # -# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 43a41b939b666..ebc0f3d961d36 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -30,6 +30,7 @@ on: branches-ignore: - master - pr/* + - jdk* workflow_dispatch: inputs: platforms: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6f2757fe97ff9..b3590166264bf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -60,7 +60,9 @@ jobs: - 'jdk/tier1 part 3' - 'langtools/tier1' - 'hs/tier1 common' - - 'hs/tier1 compiler' + - 'hs/tier1 compiler part 1' + - 'hs/tier1 compiler part 2' + - 'hs/tier1 compiler part 3' - 'hs/tier1 gc' - 'hs/tier1 runtime' - 'hs/tier1 serviceability' @@ -83,8 +85,16 @@ jobs: test-suite: 'test/hotspot/jtreg/:tier1_common' debug-suffix: -debug - - test-name: 'hs/tier1 compiler' - test-suite: 'test/hotspot/jtreg/:tier1_compiler' + - test-name: 'hs/tier1 compiler part 1' + test-suite: 'test/hotspot/jtreg/:tier1_compiler_1' + debug-suffix: -debug + + - test-name: 'hs/tier1 compiler part 2' + test-suite: 'test/hotspot/jtreg/:tier1_compiler_2 test/hotspot/jtreg/:tier1_compiler_not_xcomp' + debug-suffix: -debug + + - test-name: 'hs/tier1 compiler part 3' + test-suite: 'test/hotspot/jtreg/:tier1_compiler_3' debug-suffix: -debug - test-name: 'hs/tier1 gc' diff --git a/.jcheck/conf b/.jcheck/conf index 9d53db9f99664..18228df5dfe46 100644 --- a/.jcheck/conf +++ b/.jcheck/conf @@ -1,7 +1,7 @@ [general] project=jdk jbs=JDK -version=22 +version=23 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists diff --git a/make/CompileDemos.gmk b/make/CompileDemos.gmk index c85bc102acbe7..dfe30c701731a 100644 --- a/make/CompileDemos.gmk +++ b/make/CompileDemos.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,7 @@ DEMO_MANIFEST := $(SUPPORT_OUTPUTDIR)/demos/java-main-manifest.mf # This rule will be depended on due to the MANIFEST line in SetupBuildDemo # and SetupBuildJvmtiDemo. $(eval $(call SetupTextFileProcessing, BUILD_JAVA_MANIFEST, \ - SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf, \ + SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf.template, \ OUTPUT_FILE := $(DEMO_MANIFEST), \ REPLACEMENTS := \ @@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION) ; \ diff --git a/make/CompileInterimLangtools.gmk b/make/CompileInterimLangtools.gmk index bbc2d10369632..855b88ca0a2d6 100644 --- a/make/CompileInterimLangtools.gmk +++ b/make/CompileInterimLangtools.gmk @@ -99,6 +99,9 @@ define SetupInterimModule EXCLUDE_FILES := $(TOPDIR)/src/$1/share/classes/module-info.java \ $(TOPDIR)/src/$1/share/classes/javax/tools/ToolProvider.java \ $(TOPDIR)/src/$1/share/classes/com/sun/tools/javac/launcher/Main.java \ + $(TOPDIR)/src/$1/share/classes/com/sun/tools/javac/launcher/MemoryContext.java \ + $(TOPDIR)/src/$1/share/classes/com/sun/tools/javac/launcher/MemoryModuleFinder.java \ + $(TOPDIR)/src/$1/share/classes/com/sun/tools/javac/launcher/SourceLauncher.java \ Standard.java, \ EXTRA_FILES := $(BUILDTOOLS_OUTPUTDIR)/gensrc/$1.interim/module-info.java \ $($1.interim_EXTRA_FILES), \ diff --git a/make/CompileModuleTools.gmk b/make/CompileModuleTools.gmk index 59d651d2d9625..bb3948f377ede 100644 --- a/make/CompileModuleTools.gmk +++ b/make/CompileModuleTools.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/Global.gmk b/make/Global.gmk index b41c4051cfafd..e5e76b475b941 100644 --- a/make/Global.gmk +++ b/make/Global.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,6 @@ help: $(info $(_) make docs # Create all docs) $(info $(_) make docs-jdk-api # Create just JDK javadocs) $(info $(_) make bootcycle-images # Build images twice, second time with newly built JDK) - $(info $(_) make install # Install the generated images locally) $(info $(_) make check # Run basic testing (currently tier1)) $(info $(_) make test- # Run test, e.g. test-tier1) $(info $(_) make test TEST= # Run test(s) given by TEST specification) diff --git a/make/Hsdis.gmk b/make/Hsdis.gmk index bcf01dbe1529a..7496a3a2cf1b4 100644 --- a/make/Hsdis.gmk +++ b/make/Hsdis.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/Install.gmk b/make/Install.gmk deleted file mode 100644 index bfe989ffe3100..0000000000000 --- a/make/Install.gmk +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -default: install - -include $(SPEC) - -BINARIES := $(notdir $(wildcard $(JDK_IMAGE_DIR)/bin/*)) -INSTALLDIR := openjdk-$(VERSION_SHORT) - -# Install the jdk image, in a very crude way. Not taking into -# account, how to install properly on macosx or windows etc. -install: - echo Installing jdk image into $(INSTALL_PREFIX)/jvm/$(INSTALLDIR) - echo and creating $(words $(BINARIES)) links from $(INSTALL_PREFIX)/bin into the jdk. - $(MKDIR) -p $(INSTALL_PREFIX)/jvm/$(INSTALLDIR) - $(RM) -r $(INSTALL_PREFIX)/jvm/$(INSTALLDIR)/* - $(CP) -rp $(JDK_IMAGE_DIR)/* $(INSTALL_PREFIX)/jvm/$(INSTALLDIR) - $(MKDIR) -p $(INSTALL_PREFIX)/bin - $(RM) $(addprefix $(INSTALL_PREFIX)/bin/, $(BINARIES)) - $(foreach b, $(BINARIES), $(LN) -s $(INSTALL_PREFIX)/jvm/$(INSTALLDIR)/bin/$b $(INSTALL_PREFIX)/bin/$b &&) true diff --git a/make/JrtfsJar.gmk b/make/JrtfsJar.gmk index 50ae82ca56567..b0b7ed6ce08a0 100644 --- a/make/JrtfsJar.gmk +++ b/make/JrtfsJar.gmk @@ -33,7 +33,7 @@ include TextFileProcessing.gmk # This rule will be depended on due to the MANIFEST line $(eval $(call SetupTextFileProcessing, BUILD_JAVA_MANIFEST, \ - SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf, \ + SOURCE_FILES := $(TOPDIR)/make/data/mainmanifest/manifest.mf.template, \ OUTPUT_FILE := $(SUPPORT_OUTPUTDIR)/java-main-manifest.mf, \ REPLACEMENTS := \ @@VERSION_SPECIFICATION@@ => $(VERSION_SPECIFICATION) ; \ diff --git a/make/MacBundles.gmk b/make/MacBundles.gmk index c1c51570a1dbf..39da6c9cdb30f 100644 --- a/make/MacBundles.gmk +++ b/make/MacBundles.gmk @@ -69,7 +69,7 @@ ifeq ($(call isTargetOs, macosx), true) )) $(eval $(call SetupTextFileProcessing, BUILD_JDK_PLIST, \ - SOURCE_FILES := $(MACOSX_PLIST_SRC)/JDK-Info.plist, \ + SOURCE_FILES := $(MACOSX_PLIST_SRC)/JDK-Info.plist.template, \ OUTPUT_FILE := $(JDK_MACOSX_CONTENTS_DIR)/Info.plist, \ REPLACEMENTS := \ @@ID@@ => $(MACOSX_BUNDLE_ID_BASE).jdk ; \ @@ -82,7 +82,7 @@ ifeq ($(call isTargetOs, macosx), true) )) $(eval $(call SetupTextFileProcessing, BUILD_JRE_PLIST, \ - SOURCE_FILES := $(MACOSX_PLIST_SRC)/JRE-Info.plist, \ + SOURCE_FILES := $(MACOSX_PLIST_SRC)/JRE-Info.plist.template, \ OUTPUT_FILE := $(JRE_MACOSX_CONTENTS_DIR)/Info.plist, \ REPLACEMENTS := \ @@ID@@ => $(MACOSX_BUNDLE_ID_BASE).jre ; \ diff --git a/make/Main.gmk b/make/Main.gmk index 1817416867738..5534a68f13bab 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -744,9 +744,16 @@ endif $(eval $(call SetupTarget, build-test-lib, \ MAKEFILE := test/BuildTestLib, \ + TARGET := build-test-lib, \ DEPS := exploded-image, \ )) +$(eval $(call SetupTarget, test-image-lib, \ + MAKEFILE := test/BuildTestLib, \ + TARGET := test-image-lib, \ + DEPS := build-test-lib, \ +)) + ifeq ($(BUILD_FAILURE_HANDLER), true) # Builds the failure handler jtreg extension $(eval $(call SetupTarget, build-test-failure-handler, \ @@ -781,7 +788,7 @@ endif $(eval $(call SetupTarget, build-microbenchmark, \ MAKEFILE := test/BuildMicrobenchmark, \ - DEPS := interim-langtools exploded-image, \ + DEPS := interim-langtools exploded-image build-test-lib, \ )) ################################################################################ @@ -866,14 +873,6 @@ ifeq ($(JCOV_ENABLED), true) )) endif -################################################################################ -# Install targets - -$(eval $(call SetupTarget, install, \ - MAKEFILE := Install, \ - DEPS := product-images, \ -)) - ################################################################################ # # Dependency declarations between targets. @@ -1272,7 +1271,7 @@ all-docs-bundles: docs-jdk-bundles docs-javase-bundles docs-reference-bundles # This target builds the test image test-image: prepare-test-image test-image-jdk-jtreg-native \ test-image-demos-jdk test-image-libtest-jtreg-native \ - test-image-lib-native + test-image-lib test-image-lib-native ifneq ($(JVM_TEST_IMAGE_TARGETS), ) # If JVM_TEST_IMAGE_TARGETS is externally defined, use it instead of the diff --git a/make/ReleaseFile.gmk b/make/ReleaseFile.gmk index 5e8d123fac9c8..dc6f66a69a2af 100644 --- a/make/ReleaseFile.gmk +++ b/make/ReleaseFile.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/RunTestsPrebuilt.gmk b/make/RunTestsPrebuilt.gmk index 93febe5ed31d9..eea325184f3d7 100644 --- a/make/RunTestsPrebuilt.gmk +++ b/make/RunTestsPrebuilt.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/RunTestsPrebuiltSpec.gmk b/make/RunTestsPrebuiltSpec.gmk index 7fcaf56ff527e..16a14fbd2a072 100644 --- a/make/RunTestsPrebuiltSpec.gmk +++ b/make/RunTestsPrebuiltSpec.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/ToolsJdk.gmk b/make/ToolsJdk.gmk index b7310811f0299..e7cc3fc871128 100644 --- a/make/ToolsJdk.gmk +++ b/make/ToolsJdk.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/autoconf/Makefile.in b/make/autoconf/Makefile.template similarity index 97% rename from make/autoconf/Makefile.in rename to make/autoconf/Makefile.template index 8badd0f43ac84..4cb5057c05c7e 100644 --- a/make/autoconf/Makefile.in +++ b/make/autoconf/Makefile.template @@ -24,4 +24,4 @@ # This Makefile was generated by configure @DATE_WHEN_CONFIGURED@ # GENERATED FILE, DO NOT EDIT SPEC:=@OUTPUTDIR@/spec.gmk -include @TOPDIR@/Makefile +include @WORKSPACE_ROOT@/Makefile diff --git a/make/autoconf/basic.m4 b/make/autoconf/basic.m4 index af9633595838a..5a1fbc0795274 100644 --- a/make/autoconf/basic.m4 +++ b/make/autoconf/basic.m4 @@ -448,17 +448,17 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR], AC_SUBST(CONFIGURESUPPORT_OUTPUTDIR) # The spec.gmk file contains all variables for the make system. - AC_CONFIG_FILES([$OUTPUTDIR/spec.gmk:$AUTOCONF_DIR/spec.gmk.in]) + AC_CONFIG_FILES([$OUTPUTDIR/spec.gmk:$AUTOCONF_DIR/spec.gmk.template]) # The bootcycle-spec.gmk file contains support for boot cycle builds. - AC_CONFIG_FILES([$OUTPUTDIR/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.in]) + AC_CONFIG_FILES([$OUTPUTDIR/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.template]) # The buildjdk-spec.gmk file contains support for building a buildjdk when cross compiling. - AC_CONFIG_FILES([$OUTPUTDIR/buildjdk-spec.gmk:$AUTOCONF_DIR/buildjdk-spec.gmk.in]) + AC_CONFIG_FILES([$OUTPUTDIR/buildjdk-spec.gmk:$AUTOCONF_DIR/buildjdk-spec.gmk.template]) # The compare.sh is used to compare the build output to other builds. - AC_CONFIG_FILES([$OUTPUTDIR/compare.sh:$AUTOCONF_DIR/compare.sh.in]) + AC_CONFIG_FILES([$OUTPUTDIR/compare.sh:$AUTOCONF_DIR/compare.sh.template]) # The generated Makefile knows where the spec.gmk is and where the source is. # You can run make from the OUTPUTDIR, or from the top-level Makefile # which will look for generated configurations - AC_CONFIG_FILES([$OUTPUTDIR/Makefile:$AUTOCONF_DIR/Makefile.in]) + AC_CONFIG_FILES([$OUTPUTDIR/Makefile:$AUTOCONF_DIR/Makefile.template]) ]) ############################################################################### diff --git a/make/autoconf/basic_tools.m4 b/make/autoconf/basic_tools.m4 index 92a4582ecddc9..f9ecbab7ac099 100644 --- a/make/autoconf/basic_tools.m4 +++ b/make/autoconf/basic_tools.m4 @@ -390,6 +390,17 @@ AC_DEFUN_ONCE([BASIC_SETUP_COMPLEX_TOOLS], if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then UTIL_REQUIRE_PROGS(DSYMUTIL, dsymutil) + AC_MSG_CHECKING([if dsymutil supports --reproducer option]) + if $DSYMUTIL --help | $GREP -q '\--reproducer '; then + AC_MSG_RESULT([yes]) + # --reproducer option is supported + # set "--reproducer Off" to prevent unnecessary temporary + # directories creation + DSYMUTIL="$DSYMUTIL --reproducer Off" + else + # --reproducer option isn't supported + AC_MSG_RESULT([no]) + fi UTIL_REQUIRE_PROGS(MIG, mig) UTIL_REQUIRE_PROGS(XATTR, xattr) UTIL_LOOKUP_PROGS(CODESIGN, codesign) diff --git a/make/autoconf/bootcycle-spec.gmk.in b/make/autoconf/bootcycle-spec.gmk.template similarity index 100% rename from make/autoconf/bootcycle-spec.gmk.in rename to make/autoconf/bootcycle-spec.gmk.template diff --git a/make/autoconf/buildjdk-spec.gmk.in b/make/autoconf/buildjdk-spec.gmk.template similarity index 98% rename from make/autoconf/buildjdk-spec.gmk.in rename to make/autoconf/buildjdk-spec.gmk.template index 3e7c4a39f60a6..993ed50390210 100644 --- a/make/autoconf/buildjdk-spec.gmk.in +++ b/make/autoconf/buildjdk-spec.gmk.template @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/autoconf/compare.sh.in b/make/autoconf/compare.sh.template similarity index 100% rename from make/autoconf/compare.sh.in rename to make/autoconf/compare.sh.template diff --git a/make/autoconf/flags-other.m4 b/make/autoconf/flags-other.m4 index 0af7c02cff6c2..7e2521ffef3b0 100644 --- a/make/autoconf/flags-other.m4 +++ b/make/autoconf/flags-other.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/autoconf/jdk-version.m4 b/make/autoconf/jdk-version.m4 index 6a7662556fdaf..7c9ecad77791b 100644 --- a/make/autoconf/jdk-version.m4 +++ b/make/autoconf/jdk-version.m4 @@ -110,6 +110,15 @@ AC_DEFUN_ONCE([JDKVER_SETUP_JDK_VERSION_NUMBERS], CHECK_VALUE: [UTIL_CHECK_STRING_NON_EMPTY_PRINTABLE]) AC_SUBST(COMPANY_NAME) + # Set the JDK RC Company name + # Otherwise uses the value set for "vendor-name". + UTIL_ARG_WITH(NAME: jdk-rc-company-name, TYPE: string, + DEFAULT: $COMPANY_NAME, + DESC: [Set JDK RC company name. This is used for CompanyName properties of MS Windows binaries.], + DEFAULT_DESC: [from branding.conf], + CHECK_VALUE: [UTIL_CHECK_STRING_NON_EMPTY_PRINTABLE]) + AC_SUBST(JDK_RC_COMPANY_NAME) + # The vendor URL, if any # Only set VENDOR_URL if '--with-vendor-url' was used and is not empty. # Otherwise we will use the value from "branding.conf" included above. diff --git a/make/autoconf/lib-ffi.m4 b/make/autoconf/lib-ffi.m4 index 3a11bec4a97d6..101065a1ecec1 100644 --- a/make/autoconf/lib-ffi.m4 +++ b/make/autoconf/lib-ffi.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.template similarity index 92% rename from make/autoconf/spec.gmk.in rename to make/autoconf/spec.gmk.template index 26b7d3ec9586c..90168e6df0f52 100644 --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.template @@ -191,11 +191,12 @@ PRODUCT_NAME := @PRODUCT_NAME@ PRODUCT_SUFFIX := @PRODUCT_SUFFIX@ JDK_RC_PLATFORM_NAME := @JDK_RC_PLATFORM_NAME@ JDK_RC_NAME := @JDK_RC_NAME@ +JDK_RC_COMPANY_NAME:=@JDK_RC_COMPANY_NAME@ COMPANY_NAME := @COMPANY_NAME@ HOTSPOT_VM_DISTRO := @HOTSPOT_VM_DISTRO@ -MACOSX_BUNDLE_NAME_BASE = @MACOSX_BUNDLE_NAME_BASE@ -MACOSX_BUNDLE_ID_BASE = @MACOSX_BUNDLE_ID_BASE@ -MACOSX_BUNDLE_BUILD_VERSION = @MACOSX_BUNDLE_BUILD_VERSION@ +MACOSX_BUNDLE_NAME_BASE := @MACOSX_BUNDLE_NAME_BASE@ +MACOSX_BUNDLE_ID_BASE := @MACOSX_BUNDLE_ID_BASE@ +MACOSX_BUNDLE_BUILD_VERSION := @MACOSX_BUNDLE_BUILD_VERSION@ USERNAME := @USERNAME@ VENDOR_URL := @VENDOR_URL@ VENDOR_URL_BUG := @VENDOR_URL_BUG@ @@ -439,18 +440,18 @@ JMH_VERSION := @JMH_VERSION@ GTEST_FRAMEWORK_SRC := @GTEST_FRAMEWORK_SRC@ # Source file for cacerts -CACERTS_FILE = @CACERTS_FILE@ +CACERTS_FILE := @CACERTS_FILE@ # Source folder for user provided cacerts PEM files -CACERTS_SRC = @CACERTS_SRC@ +CACERTS_SRC := @CACERTS_SRC@ # Enable unlimited crypto policy -UNLIMITED_CRYPTO = @UNLIMITED_CRYPTO@ +UNLIMITED_CRYPTO := @UNLIMITED_CRYPTO@ -GCOV_ENABLED = @GCOV_ENABLED@ -JCOV_ENABLED = @JCOV_ENABLED@ -JCOV_HOME = @JCOV_HOME@ -JCOV_INPUT_JDK = @JCOV_INPUT_JDK@ -JCOV_FILTERS = @JCOV_FILTERS@ +GCOV_ENABLED := @GCOV_ENABLED@ +JCOV_ENABLED := @JCOV_ENABLED@ +JCOV_HOME := @JCOV_HOME@ +JCOV_INPUT_JDK := @JCOV_INPUT_JDK@ +JCOV_FILTERS := @JCOV_FILTERS@ # AddressSanitizer ASAN_ENABLED := @ASAN_ENABLED@ @@ -468,13 +469,13 @@ X_CFLAGS := @X_CFLAGS@ X_LIBS := @X_LIBS@ # The lowest required version of macosx -MACOSX_VERSION_MIN = @MACOSX_VERSION_MIN@ +MACOSX_VERSION_MIN := @MACOSX_VERSION_MIN@ # The highest allowed version of macosx -MACOSX_VERSION_MAX = @MACOSX_VERSION_MAX@ +MACOSX_VERSION_MAX := @MACOSX_VERSION_MAX@ # The macosx code signing configuration MACOSX_CODESIGN_MODE := @MACOSX_CODESIGN_MODE@ -MACOSX_CODESIGN_IDENTITY = @MACOSX_CODESIGN_IDENTITY@ +MACOSX_CODESIGN_IDENTITY := @MACOSX_CODESIGN_IDENTITY@ # Toolchain type: gcc, clang, xlc, microsoft... TOOLCHAIN_TYPE := @TOOLCHAIN_TYPE@ @@ -487,7 +488,7 @@ HOTSPOT_TOOLCHAIN_TYPE := @HOTSPOT_TOOLCHAIN_TYPE@ # Option used to tell the compiler whether to create 32- or 64-bit executables COMPILER_TARGET_BITS_FLAG := @COMPILER_TARGET_BITS_FLAG@ -COMPILER_SUPPORTS_TARGET_BITS_FLAG = @COMPILER_SUPPORTS_TARGET_BITS_FLAG@ +COMPILER_SUPPORTS_TARGET_BITS_FLAG := @COMPILER_SUPPORTS_TARGET_BITS_FLAG@ # Option used to pass a command file to the compiler COMPILER_COMMAND_FILE_FLAG := @COMPILER_COMMAND_FILE_FLAG@ @@ -526,8 +527,8 @@ DISABLED_WARNINGS_CXX := @DISABLED_WARNINGS_CXX@ WARNINGS_AS_ERRORS := @WARNINGS_AS_ERRORS@ CFLAGS_CCACHE := @CFLAGS_CCACHE@ -ADLC_LANGSTD_CXXFLAGS = @ADLC_LANGSTD_CXXFLAGS@ -ADLC_LDFLAGS = @ADLC_LDFLAGS@ +ADLC_LANGSTD_CXXFLAGS := @ADLC_LANGSTD_CXXFLAGS@ +ADLC_LDFLAGS := @ADLC_LDFLAGS@ # Tools that potentially need to be cross compilation aware. CC := @CCACHE@ @ICECC@ @CC@ @@ -551,10 +552,10 @@ BASIC_ASFLAGS := @BASIC_ASFLAGS@ MACHINE_FLAG := @MACHINE_FLAG@ # These flags might contain variables set by a custom extension that is included later. -EXTRA_CFLAGS = @EXTRA_CFLAGS@ -EXTRA_CXXFLAGS = @EXTRA_CXXFLAGS@ -EXTRA_LDFLAGS = @EXTRA_LDFLAGS@ -EXTRA_ASFLAGS = @EXTRA_ASFLAGS@ +EXTRA_CFLAGS := @EXTRA_CFLAGS@ +EXTRA_CXXFLAGS := @EXTRA_CXXFLAGS@ +EXTRA_LDFLAGS := @EXTRA_LDFLAGS@ +EXTRA_ASFLAGS := @EXTRA_ASFLAGS@ CXX := @CCACHE@ @ICECC@ @CXX@ @@ -633,13 +634,13 @@ ASFLAGS_DEBUG_SYMBOLS := @ASFLAGS_DEBUG_SYMBOLS@ # # Compress (or not) jars -COMPRESS_JARS = @COMPRESS_JARS@ +COMPRESS_JARS := @COMPRESS_JARS@ # Options to linker to specify the library name. # (Note absence of := assignment, because we do not want to evaluate the macro body here) SET_SHARED_LIBRARY_NAME = @SET_SHARED_LIBRARY_NAME@ -SHARED_LIBRARY_FLAGS = @SHARED_LIBRARY_FLAGS@ +SHARED_LIBRARY_FLAGS := @SHARED_LIBRARY_FLAGS@ # Set origin using the linker, ie use the relative path to the dependent library to find the dependencies. # (Note absence of := assignment, because we do not want to evaluate the macro body here) @@ -647,11 +648,12 @@ SET_SHARED_LIBRARY_ORIGIN = @SET_SHARED_LIBRARY_ORIGIN@ SET_EXECUTABLE_ORIGIN = @SET_EXECUTABLE_ORIGIN@ # Different OS:es have different ways of naming shared libraries. -# The SHARED_LIBRARY macro takes "verify" as and argument and returns: +# The SHARED_LIBRARY and STATIC_LIBRARY macros takes "verify" as and argument and returns: # "libverify.so" or "libverify.dylib" or "verify.dll" depending on platform. # (Note absence of := assignment, because we do not want to evaluate the macro body here) SHARED_LIBRARY = @SHARED_LIBRARY@ STATIC_LIBRARY = @STATIC_LIBRARY@ + LIBRARY_PREFIX := @LIBRARY_PREFIX@ SHARED_LIBRARY_SUFFIX := @SHARED_LIBRARY_SUFFIX@ STATIC_LIBRARY_SUFFIX := @STATIC_LIBRARY_SUFFIX@ @@ -719,8 +721,8 @@ INTERIM_LANGTOOLS_ARGS := \ --patch-module java.base=$(BUILDTOOLS_OUTPUTDIR)/gensrc/java.base.interim \ $(INTERIM_LANGTOOLS_ADD_EXPORTS) \ # -JAVAC_MAIN_CLASS = -m jdk.compiler.interim/com.sun.tools.javac.Main -JAVADOC_MAIN_CLASS = -m jdk.javadoc.interim/jdk.javadoc.internal.tool.Main +JAVAC_MAIN_CLASS := -m jdk.compiler.interim/com.sun.tools.javac.Main +JAVADOC_MAIN_CLASS := -m jdk.javadoc.interim/jdk.javadoc.internal.tool.Main # You run the new javac using the boot jdk with $(BOOT_JDK)/bin/java $(NEW_JAVAC) ... # Use = assignment to be able to override in bootcycle-spec.gmk @@ -823,57 +825,6 @@ UCRT_DLL_DIR := @UCRT_DLL_DIR@ ENABLE_PANDOC := @ENABLE_PANDOC@ PANDOC_MARKDOWN_FLAG := @PANDOC_MARKDOWN_FLAG@ -#################################################### -# -# INSTALLATION -# - -# Common prefix for all installed files. Defaults to /usr/local, -# but /opt/myjdk is another common version. -INSTALL_PREFIX = @prefix@ - -# Directories containing architecture-dependent files should be relative to exec_prefix -INSTALL_EXECPREFIX = @exec_prefix@ - -# java,javac,javap etc are installed here. -INSTALL_BINDIR = @bindir@ - -# Read only architecture-independent data -INSTALL_DATADIR = @datadir@ - -# Root of above. -INSTALL_DATAROOTDIR = @datarootdir@ - -# Doc files, other than info and man. -INSTALL_DOCDIR = @docdir@ - -# Html documentation -INSTALL_HTMLDIR = @htmldir@ - -# Installing C header files, JNI headers for example. -INSTALL_INCLUDEDIR = @includedir@ - -# Installing library files.... -INSTALL_INCLUDEDIR = @libdir@ - -# Executables that other programs run. -INSTALL_LIBEXECDIR = @libexecdir@ - -# Locale-dependent but architecture-independent data, such as message catalogs. -INSTALL_LOCALEDIR = @localedir@ - -# Modifiable single-machine data -INSTALL_LOCALSTATEDIR = @localstatedir@ - -# Man pages -INSTALL_MANDIR = @mandir@ - -# Modifiable architecture-independent data. -INSTALL_SHAREDSTATEDIR = @sharedstatedir@ - -# Read-only single-machine data -INSTALL_SYSCONFDIR = @sysconfdir@ - #################################################### # # Libraries @@ -896,9 +847,9 @@ PNG_CFLAGS := @PNG_CFLAGS@ # Misc # -INCLUDE_SA = @INCLUDE_SA@ -INCLUDE_JVMCI = @INCLUDE_JVMCI@ -INCLUDE_COMPILER2 = @INCLUDE_COMPILER2@ +INCLUDE_SA := @INCLUDE_SA@ +INCLUDE_JVMCI := @INCLUDE_JVMCI@ +INCLUDE_COMPILER2 := @INCLUDE_COMPILER2@ OS_VERSION_MAJOR := @OS_VERSION_MAJOR@ OS_VERSION_MINOR := @OS_VERSION_MINOR@ @@ -949,10 +900,10 @@ GRAAL_BUILDER_IMAGE_SUBDIR := graal-builder-jdk GRAAL_BUILDER_IMAGE_DIR := $(IMAGES_OUTPUTDIR)/$(GRAAL_BUILDER_IMAGE_SUBDIR) # Macosx bundles directory definitions -JDK_MACOSX_BUNDLE_SUBDIR = jdk-bundle -JRE_MACOSX_BUNDLE_SUBDIR = jre-bundle -JDK_MACOSX_BUNDLE_SUBDIR_SIGNED = jdk-bundle-signed -JRE_MACOSX_BUNDLE_SUBDIR_SIGNED = jre-bundle-signed +JDK_MACOSX_BUNDLE_SUBDIR := jdk-bundle +JRE_MACOSX_BUNDLE_SUBDIR := jre-bundle +JDK_MACOSX_BUNDLE_SUBDIR_SIGNED := jdk-bundle-signed +JRE_MACOSX_BUNDLE_SUBDIR_SIGNED := jre-bundle-signed JDK_MACOSX_BUNDLE_DIR = $(IMAGES_OUTPUTDIR)/$(JDK_MACOSX_BUNDLE_SUBDIR) JRE_MACOSX_BUNDLE_DIR = $(IMAGES_OUTPUTDIR)/$(JRE_MACOSX_BUNDLE_SUBDIR) JDK_MACOSX_BUNDLE_DIR_SIGNED = $(IMAGES_OUTPUTDIR)/$(JDK_MACOSX_BUNDLE_SUBDIR_SIGNED) diff --git a/make/common/JdkNativeCompilation.gmk b/make/common/JdkNativeCompilation.gmk index 6a963ac2c498a..1a1333cf51707 100644 --- a/make/common/JdkNativeCompilation.gmk +++ b/make/common/JdkNativeCompilation.gmk @@ -98,7 +98,7 @@ GLOBAL_VERSION_INFO_RESOURCE := $(TOPDIR)/src/java.base/windows/native/common/ve JDK_RCFLAGS=$(RCFLAGS) \ -D"JDK_VERSION_STRING=$(VERSION_STRING)" \ - -D"JDK_COMPANY=$(COMPANY_NAME)" \ + -D"JDK_COMPANY=$(JDK_RC_COMPANY_NAME)" \ -D"JDK_VER=$(VERSION_NUMBER_FOUR_POSITIONS)" \ -D"JDK_COPYRIGHT=Copyright \xA9 $(COPYRIGHT_YEAR)" \ -D"JDK_NAME=$(JDK_RC_NAME) $(VERSION_SHORT)" \ diff --git a/make/common/MakeIO.gmk b/make/common/MakeIO.gmk index 6075e034a19a5..75a387c34d947 100644 --- a/make/common/MakeIO.gmk +++ b/make/common/MakeIO.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/common/Modules.gmk b/make/common/Modules.gmk index bcbb6d1bab150..fa885dacb6da6 100644 --- a/make/common/Modules.gmk +++ b/make/common/Modules.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/common/ProcessMarkdown.gmk b/make/common/ProcessMarkdown.gmk index b5dc020be2c94..e78c026a89c37 100644 --- a/make/common/ProcessMarkdown.gmk +++ b/make/common/ProcessMarkdown.gmk @@ -1,4 +1,4 @@ -# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/common/modules/LauncherCommon.gmk b/make/common/modules/LauncherCommon.gmk index 21d2b9a930078..8041e9fe681c3 100644 --- a/make/common/modules/LauncherCommon.gmk +++ b/make/common/modules/LauncherCommon.gmk @@ -112,7 +112,7 @@ define SetupBuildLauncherBody $1_PLIST_FILE := $$(SUPPORT_OUTPUTDIR)/native/$$(MODULE)/$1/Info.plist $$(eval $$(call SetupTextFileProcessing, BUILD_PLIST_$1, \ - SOURCE_FILES := $(TOPDIR)/make/data/bundle/cmdline-Info.plist, \ + SOURCE_FILES := $(TOPDIR)/make/data/bundle/cmdline-Info.plist.template, \ OUTPUT_FILE := $$($1_PLIST_FILE), \ REPLACEMENTS := \ @@ID@@ => $(MACOSX_BUNDLE_ID_BASE).$1 ; \ diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index c26c648ba3808..d8bca3551217b 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -407,6 +407,8 @@ var getJibProfilesCommon = function (input, data) { * @returns {{}} Profiles part of the configuration */ var getJibProfilesProfiles = function (input, common, data) { + var cross_compiling = input.build_platform != input.target_platform; + // Main SE profiles var profiles = { @@ -484,14 +486,12 @@ var getJibProfilesProfiles = function (input, common, data) { "linux-aarch64": { target_os: "linux", target_cpu: "aarch64", - build_cpu: "x64", dependencies: ["devkit", "gtest", "build_devkit", "pandoc"], configure_args: [ - "--openjdk-target=aarch64-linux-gnu", "--with-zlib=system", "--disable-dtrace", "--enable-compatible-cds-alignment", - ], + ].concat(cross_compiling ? ["--openjdk-target=aarch64-linux-gnu"] : []), }, "linux-arm32": { @@ -1206,7 +1206,7 @@ var getJibProfilesDependencies = function (input, common) { jcov: { organization: common.organization, - revision: "3.0-15-jdk-asm+1.0", + revision: "3.0-16-jdk-asm+1.0", ext: "zip", environment_name: "JCOV_HOME", }, diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index b902ba7624fab..fbd359800de3e 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -26,17 +26,17 @@ # Default version, product, and vendor information to use, # unless overridden by configure -DEFAULT_VERSION_FEATURE=22 +DEFAULT_VERSION_FEATURE=23 DEFAULT_VERSION_INTERIM=0 DEFAULT_VERSION_UPDATE=0 DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2024-03-19 -DEFAULT_VERSION_CLASSFILE_MAJOR=66 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" +DEFAULT_VERSION_DATE=2024-09-17 +DEFAULT_VERSION_CLASSFILE_MAJOR=67 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 -DEFAULT_ACCEPTABLE_BOOT_VERSIONS="21 22" -DEFAULT_JDK_SOURCE_TARGET_VERSION=22 +DEFAULT_ACCEPTABLE_BOOT_VERSIONS="21 22 23" +DEFAULT_JDK_SOURCE_TARGET_VERSION=23 DEFAULT_PROMOTED_VERSION_PRE=ea diff --git a/make/data/bundle/JDK-Info.plist b/make/data/bundle/JDK-Info.plist.template similarity index 100% rename from make/data/bundle/JDK-Info.plist rename to make/data/bundle/JDK-Info.plist.template diff --git a/make/data/bundle/JRE-Info.plist b/make/data/bundle/JRE-Info.plist.template similarity index 100% rename from make/data/bundle/JRE-Info.plist rename to make/data/bundle/JRE-Info.plist.template diff --git a/make/data/bundle/cmdline-Info.plist b/make/data/bundle/cmdline-Info.plist.template similarity index 100% rename from make/data/bundle/cmdline-Info.plist rename to make/data/bundle/cmdline-Info.plist.template diff --git a/make/data/mainmanifest/manifest.mf b/make/data/mainmanifest/manifest.mf.template similarity index 100% rename from make/data/mainmanifest/manifest.mf rename to make/data/mainmanifest/manifest.mf.template diff --git a/make/data/ubsan/ubsan_default_options.c b/make/data/ubsan/ubsan_default_options.c index ee426ebbc39fe..011d1a675a90f 100644 --- a/make/data/ubsan/ubsan_default_options.c +++ b/make/data/ubsan/ubsan_default_options.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/make/data/ubsan/ubsan_default_options.cpp b/make/data/ubsan/ubsan_default_options.cpp index dbebb5b2977e0..b0eb8eea0e2a5 100644 --- a/make/data/ubsan/ubsan_default_options.cpp +++ b/make/data/ubsan/ubsan_default_options.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/make/devkit/createMacosxDevkit.sh b/make/devkit/createMacosxDevkit.sh index 0c15ebfaa1fc1..414773194d9ca 100644 --- a/make/devkit/createMacosxDevkit.sh +++ b/make/devkit/createMacosxDevkit.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/hotspot/gensrc/GenerateSources.gmk b/make/hotspot/gensrc/GenerateSources.gmk index 9b42493f6284f..c92408b7d54b4 100644 --- a/make/hotspot/gensrc/GenerateSources.gmk +++ b/make/hotspot/gensrc/GenerateSources.gmk @@ -48,7 +48,7 @@ $(eval $(call IncludeCustomExtension, hotspot/gensrc/GenerateSources.gmk)) # Setup the hotspot launcher script for developer use $(eval $(call SetupTextFileProcessing, CREATE_HOTSPOT_LAUNCHER, \ - SOURCE_FILES := $(TOPDIR)/make/scripts/hotspot.sh, \ + SOURCE_FILES := $(TOPDIR)/make/scripts/hotspot.sh.template, \ OUTPUT_FILE := $(JVM_OUTPUTDIR)/hotspot, \ REPLACEMENTS := \ @@LIBARCH@@ => $(OPENJDK_TARGET_CPU_LEGACY_LIB) ; \ diff --git a/make/hotspot/lib/CompileGtest.gmk b/make/hotspot/lib/CompileGtest.gmk index bba3ce15bb152..0d17f7a3be562 100644 --- a/make/hotspot/lib/CompileGtest.gmk +++ b/make/hotspot/lib/CompileGtest.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/hotspot/lib/JvmFeatures.gmk b/make/hotspot/lib/JvmFeatures.gmk index cbe60fde20522..8eb57d76536a8 100644 --- a/make/hotspot/lib/JvmFeatures.gmk +++ b/make/hotspot/lib/JvmFeatures.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/hotspot/lib/JvmFlags.gmk b/make/hotspot/lib/JvmFlags.gmk index 1fadd5331aa38..e5929ab994ba0 100644 --- a/make/hotspot/lib/JvmFlags.gmk +++ b/make/hotspot/lib/JvmFlags.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/ide/eclipse/CreateWorkspace.gmk b/make/ide/eclipse/CreateWorkspace.gmk index 51257d65ae298..a7937a33d9e7e 100644 --- a/make/ide/eclipse/CreateWorkspace.gmk +++ b/make/ide/eclipse/CreateWorkspace.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/ide/idea/jdk/template/src/idea/JdkIdeaAntLogger.java b/make/ide/idea/jdk/template/src/idea/JdkIdeaAntLogger.java index 9634fb9d388d4..dd640bd95a09a 100644 --- a/make/ide/idea/jdk/template/src/idea/JdkIdeaAntLogger.java +++ b/make/ide/idea/jdk/template/src/idea/JdkIdeaAntLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/make/ide/idea/langtools/template/src/idea/LangtoolsIdeaAntLogger.java b/make/ide/idea/langtools/template/src/idea/LangtoolsIdeaAntLogger.java index 8eb5313fb8407..5ff0f116ce0f5 100644 --- a/make/ide/idea/langtools/template/src/idea/LangtoolsIdeaAntLogger.java +++ b/make/ide/idea/langtools/template/src/idea/LangtoolsIdeaAntLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/make/ide/visualstudio/hotspot/CreateVSProject.gmk b/make/ide/visualstudio/hotspot/CreateVSProject.gmk index 17051fd03d0bb..cd093d3c6de85 100644 --- a/make/ide/visualstudio/hotspot/CreateVSProject.gmk +++ b/make/ide/visualstudio/hotspot/CreateVSProject.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/ide/visualstudio/hotspot/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java b/make/ide/visualstudio/hotspot/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java index ed085dae09562..3a2a0242e5a1c 100644 --- a/make/ide/visualstudio/hotspot/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java +++ b/make/ide/visualstudio/hotspot/src/classes/build/tools/projectcreator/WinGammaPlatformVC10.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/make/jdk/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java b/make/jdk/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java index 90c70f75cb9c1..49c74544be66e 100644 --- a/make/jdk/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java +++ b/make/jdk/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/make/jdk/src/classes/build/tools/depend/Depend.java b/make/jdk/src/classes/build/tools/depend/Depend.java index 4dcf130411f3d..def3265b213b7 100644 --- a/make/jdk/src/classes/build/tools/depend/Depend.java +++ b/make/jdk/src/classes/build/tools/depend/Depend.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/make/jdk/src/classes/build/tools/depend/DependTest.java b/make/jdk/src/classes/build/tools/depend/DependTest.java index 810397b62d88e..614b91bc0379d 100644 --- a/make/jdk/src/classes/build/tools/depend/DependTest.java +++ b/make/jdk/src/classes/build/tools/depend/DependTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/make/jdk/src/classes/build/tools/generatecharacter/PropList.java b/make/jdk/src/classes/build/tools/generatecharacter/PropList.java index 8d354ab4d5fd6..7af57da4b9e46 100644 --- a/make/jdk/src/classes/build/tools/generatecharacter/PropList.java +++ b/make/jdk/src/classes/build/tools/generatecharacter/PropList.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/make/jdk/src/classes/build/tools/module/GenModuleInfoSource.java b/make/jdk/src/classes/build/tools/module/GenModuleInfoSource.java index ce9b94db7a627..82bd065efcefb 100644 --- a/make/jdk/src/classes/build/tools/module/GenModuleInfoSource.java +++ b/make/jdk/src/classes/build/tools/module/GenModuleInfoSource.java @@ -473,6 +473,11 @@ private void process(Parser parser, boolean extraFile) throws IOException { if (parser.peekToken() != null) { // must be EOF throw parser.newError("is malformed"); } + } else if (token.equals("import")) { + nextIdentifier(parser); + skipTokenOrThrow(parser, ";", "missing semicolon"); + } else if (token.startsWith("@")) { + continue; } else { throw parser.newError("missing keyword"); } diff --git a/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java b/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java index 860a96f2b677d..154810e20f2d2 100644 --- a/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java +++ b/make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java @@ -230,7 +230,8 @@ public class CreateSymbols { */ @SuppressWarnings("unchecked") public void createSymbols(String ctDescriptionFileExtra, String ctDescriptionFile, String ctSymLocation, - long timestamp, String currentVersion, String preReleaseTag, String moduleClasses) throws IOException { + long timestamp, String currentVersion, String preReleaseTag, String moduleClasses, + String includedModulesFile) throws IOException { LoadDescriptions data = load(ctDescriptionFileExtra != null ? Paths.get(ctDescriptionFileExtra) : null, Paths.get(ctDescriptionFile)); @@ -246,8 +247,12 @@ public void createSymbols(String ctDescriptionFileExtra, String ctDescriptionFil //load current version classes: Path moduleClassPath = Paths.get(moduleClasses); + Set includedModules = Files.lines(Paths.get(includedModulesFile)) + .flatMap(l -> Arrays.stream(l.split(" "))) + .collect(Collectors.toSet()); - loadVersionClassesFromDirectory(data.classes, data.modules, moduleClassPath, currentVersion, previousVersion); + loadVersionClassesFromDirectory(data.classes, data.modules, moduleClassPath, + includedModules, currentVersion, previousVersion); stripNonExistentAnnotations(data); splitHeaders(data.classes); @@ -1540,7 +1545,7 @@ private void loadVersionClasses(ClassList classes, } ClassList currentVersionClasses = new ClassList(); - Map extraModulesPackagesToDerive = new HashMap<>(); + Map> extraModulesPackagesToDerive = new HashMap<>(); for (byte[] classFileData : classData) { try (InputStream in = new ByteArrayInputStream(classFileData)) { @@ -1557,7 +1562,8 @@ private void loadVersionClasses(ClassList classes, if (!currentEIList.accepts(permittedClassName, false)) { String permittedPack = permittedClassName.substring(0, permittedClassName.lastIndexOf('/')); - extraModulesPackagesToDerive.put(permittedPack, currentPack); + extraModulesPackagesToDerive.computeIfAbsent(permittedPack, x -> new HashSet<>()) + .add(currentPack); } } } catch (ConstantPoolException ex) { @@ -1576,15 +1582,18 @@ private void loadVersionClasses(ClassList classes, do { modified = false; - for (Iterator> it = extraModulesPackagesToDerive.entrySet().iterator(); it.hasNext();) { - Entry e = it.next(); - Optional module = currentVersionModules.values().stream().map(md -> md.header.get(0)).filter(d -> containsPackage(d, e.getValue())).findAny(); - if (module.isPresent()) { - if (!module.get().extraModulePackages.contains(e.getKey())) { - module.get().extraModulePackages.add(e.getKey()); + for (Iterator>> it = extraModulesPackagesToDerive.entrySet().iterator(); it.hasNext();) { + Entry> e = it.next(); + for (String basePackage : e.getValue()) { + Optional module = currentVersionModules.values().stream().map(md -> md.header.get(0)).filter(d -> containsPackage(d, basePackage)).findAny(); + if (module.isPresent()) { + if (!module.get().extraModulePackages.contains(e.getKey())) { + module.get().extraModulePackages.add(e.getKey()); + } + it.remove(); + modified = true; + break; } - it.remove(); - modified = true; } } } while (modified); @@ -1604,6 +1613,7 @@ private boolean containsPackage(ModuleHeaderDescription module, String pack) { private void loadVersionClassesFromDirectory(ClassList classes, Map modules, Path modulesDirectory, + Set includedModules, String version, String baseline) { Map currentVersionModules = @@ -1621,6 +1631,10 @@ private void loadVersionClassesFromDirectory(ClassList classes, try (DirectoryStream ds = Files.newDirectoryStream(modulesDirectory)) { for (Path p : ds) { + if (!includedModules.contains(p.getFileName().toString())) { + continue; + } + Path moduleInfo = p.resolve("module-info.class"); if (Files.isReadable(moduleInfo)) { @@ -1646,6 +1660,10 @@ private void loadVersionClassesFromDirectory(ClassList classes, includes.add(dir); pendingExportedDirectories.add(p.resolve(dir)); } + } else { + throw new IllegalArgumentException("Included module: " + + p.getFileName() + + " does not have a module-info.class"); } } } @@ -1735,41 +1753,67 @@ private void finishClassLoading(ClassList classes, Map includedClasses = new HashSet<>(); + Map> package2ModulesUsingIt = new HashMap<>(); + Map package2Module = new HashMap<>(); + currentVersionModules.values() + .forEach(md -> { + md.header.get(0).allPackages().forEach(pack -> { + package2Module.put(pack, md.name); + }); + }); boolean modified; do { modified = false; for (ClassDescription clazz : currentVersionClasses) { + Set thisClassIncludedClasses = new HashSet<>(); ClassHeaderDescription header = clazz.header.get(0); if (includeEffectiveAccess(currentVersionClasses, clazz) && currentEIList.accepts(clazz.name, false)) { - modified |= include(includedClasses, currentVersionClasses, clazz.name); + include(thisClassIncludedClasses, currentVersionClasses, clazz.name); } if (includedClasses.contains(clazz.name)) { - modified |= include(includedClasses, currentVersionClasses, header.extendsAttr); + include(thisClassIncludedClasses, currentVersionClasses, header.extendsAttr); for (String i : header.implementsAttr) { - modified |= include(includedClasses, currentVersionClasses, i); + include(thisClassIncludedClasses, currentVersionClasses, i); } if (header.permittedSubclasses != null) { for (String i : header.permittedSubclasses) { - modified |= include(includedClasses, currentVersionClasses, i); + include(thisClassIncludedClasses, currentVersionClasses, i); } } - modified |= includeOutputType(Collections.singleton(header), - h -> "", - includedClasses, - currentVersionClasses); - modified |= includeOutputType(clazz.fields, - f -> f.descriptor, - includedClasses, - currentVersionClasses); - modified |= includeOutputType(clazz.methods, - m -> m.descriptor, - includedClasses, - currentVersionClasses); + includeOutputType(Collections.singleton(header), + h -> "", + thisClassIncludedClasses, + currentVersionClasses); + includeOutputType(clazz.fields, + f -> f.descriptor, + thisClassIncludedClasses, + currentVersionClasses); + includeOutputType(clazz.methods, + m -> m.descriptor, + thisClassIncludedClasses, + currentVersionClasses); + } + + if (includedClasses.addAll(thisClassIncludedClasses)) { + modified |= true; + } + + for (String includedClass : thisClassIncludedClasses) { + int lastSlash = includedClass.lastIndexOf('/'); + String pack; + if (lastSlash != (-1)) { + pack = includedClass.substring(0, lastSlash) + .replace('.', '/'); + } else { + pack = ""; + } + package2ModulesUsingIt.computeIfAbsent(pack, p -> new HashSet<>()) + .add(package2Module.get(clazz.packge())); } } } while (modified); @@ -1834,8 +1878,24 @@ private void finishClassLoading(ClassList classes, Map ed.isQualified() && - !allIncludedPackages.contains(ed.packageName())); + for (Iterator it = header.exports.iterator(); it.hasNext();) { + ExportsDescription ed = it.next(); + + if (!ed.isQualified()) { + continue; + } + + Set usingModules = package2ModulesUsingIt.getOrDefault(ed.packageName(), Set.of()); + + ed.to.retainAll(usingModules); + + if (ed.to.isEmpty()) { + it.remove(); + if (allIncludedPackages.contains(ed.packageName())) { + header.extraModulePackages.add(ed.packageName()); + } + } + } if (header.extraModulePackages != null) { header.extraModulePackages.retainAll(allIncludedPackages); @@ -1872,17 +1932,7 @@ private void dumpDescriptions(ClassList classes, md.header .stream() .filter(h -> h.versions.contains(v.version)) - .flatMap(h -> { - List packages = new ArrayList<>(); - h.exports.stream() - .map(ExportsDescription::packageName) - .forEach(packages::add); - if (h.extraModulePackages != null) { - packages.addAll(h.extraModulePackages); - } - return packages.stream(); - }) - .map(p -> p.replace('/', '.')) + .flatMap(ModuleHeaderDescription::allPackages) .forEach(p -> package2Modules.putIfAbsent(p, md.name)); } }); @@ -2041,7 +2091,9 @@ private void incrementalUpdate(String ctDescriptionFile, ExcludeIncludeList excludeList = ExcludeIncludeList.create(excludeFile); - loadVersionClasses(classes, modules, classBytes, excludeList, "$", version); + String computedBaseline = baseline.apply(data); + + loadVersionClasses(classes, modules, classBytes, excludeList, "$", computedBaseline); removeVersion(data, version); @@ -2064,14 +2116,14 @@ private void incrementalUpdate(String ctDescriptionFile, } if (versions.stream().noneMatch(inp -> version.equals(inp.version))) { - versions.add(new PlatformInput(null, version, baseline.apply(data), null)); + versions.add(new PlatformInput(null, version, computedBaseline, null)); } Set writeVersions = new HashSet<>(); writeVersions.add(version); - //re-write all platforms that have version as their basline: + //re-write all platforms that have version as their baseline: versions.stream() .filter(inp -> version.equals(inp.basePlatform)) .map(inp -> inp.version) @@ -2091,53 +2143,66 @@ public void createIncrementalBaseLineFromDataFile(String ctDescriptionFile, public void createIncrementalBaseLine(String ctDescriptionFile, String excludeFile, String[] args) throws IOException { - String specVersion = System.getProperty("java.specification.version"); + String platformVersion = System.getProperty("java.specification.version"); + String currentVersion = + Integer.toString(Integer.parseInt(platformVersion), Character.MAX_RADIX); + String version = currentVersion.toUpperCase(Locale.ROOT); Iterable classBytes = dumpCurrentClasses(); Function baseline = data -> { if (data.versions.isEmpty()) { return null; } else { return data.versions.stream() + .filter(v -> v.version.compareTo(version) < 0) .sorted((v1, v2) -> v2.version.compareTo(v1.version)) .findFirst() .get() .version; } }; - incrementalUpdate(ctDescriptionFile, excludeFile, specVersion, classBytes, baseline, args); + incrementalUpdate(ctDescriptionFile, excludeFile, platformVersion, classBytes, baseline, args); } private List dumpCurrentClasses() throws IOException { - JavacTool tool = JavacTool.create(); - Context ctx = new Context(); + Set includedModuleNames = new HashSet<>(); String version = System.getProperty("java.specification.version"); - JavacTask task = tool.getTask(null, null, null, - List.of("--release", version), - null, null, ctx); - task.getElements().getTypeElement("java.lang.Object"); - JavaFileManager fm = ctx.get(JavaFileManager.class); + JavaFileManager moduleFM = setupJavac("--release", version); - List data = new ArrayList<>(); for (Location modLoc : LOCATIONS) { for (Set module : - fm.listLocationsForModules(modLoc)) { + moduleFM.listLocationsForModules(modLoc)) { for (JavaFileManager.Location loc : module) { - Iterable files = - fm.list(loc, - "", - EnumSet.of(Kind.CLASS), - true); - - for (JavaFileObject jfo : files) { - try (InputStream is = jfo.openInputStream(); - InputStream in = - new BufferedInputStream(is)) { - ByteArrayOutputStream baos = - new ByteArrayOutputStream(); - - in.transferTo(baos); - data.add(baos.toByteArray()); - } + includedModuleNames.add(moduleFM.inferModuleName(loc)); + } + } + } + + JavaFileManager dumpFM = setupJavac("--source", version); + List data = new ArrayList<>(); + + for (Location modLoc : LOCATIONS) { + for (String moduleName : includedModuleNames) { + Location loc = dumpFM.getLocationForModule(modLoc, moduleName); + + if (loc == null) { + continue; + } + + Iterable files = + dumpFM.list(loc, + "", + EnumSet.of(Kind.CLASS), + true); + + for (JavaFileObject jfo : files) { + try (InputStream is = jfo.openInputStream(); + InputStream in = + new BufferedInputStream(is)) { + ByteArrayOutputStream baos = + new ByteArrayOutputStream(); + + in.transferTo(baos); + data.add(baos.toByteArray()); } } } @@ -2150,6 +2215,15 @@ private List dumpCurrentClasses() throws IOException { List.of(StandardLocation.SYSTEM_MODULES, StandardLocation.UPGRADE_MODULE_PATH); + private JavaFileManager setupJavac(String... options) { + JavacTool tool = JavacTool.create(); + Context ctx = new Context(); + JavacTask task = tool.getTask(null, null, null, + List.of(options), + null, null, ctx); + task.getElements().getTypeElement("java.lang.Object"); + return ctx.get(JavaFileManager.class); + } // //non-final for tests: public static String PROFILE_ANNOTATION = "Ljdk/Profile+Annotation;"; @@ -2351,18 +2425,20 @@ private boolean include(int accessFlags) { private void addClassHeader(ClassDescription clazzDesc, ClassHeaderDescription headerDesc, String version, String baseline) { //normalize: + Iterable headers = sortedHeaders(clazzDesc.header, baseline); boolean existed = false; - for (ClassHeaderDescription existing : clazzDesc.header) { - if (existing.equals(headerDesc) && (!existed || (baseline != null && existing.versions.contains(baseline)))) { + for (ClassHeaderDescription existing : headers) { + if (existing.equals(headerDesc)) { headerDesc = existing; existed = true; + break; } } if (!existed) { //check if the only difference between the 7 and 8 version is the Profile annotation //if so, copy it to the pre-8 version, so save space - for (ClassHeaderDescription existing : clazzDesc.header) { + for (ClassHeaderDescription existing : headers) { List annots = existing.classAnnotations; if (annots != null) { @@ -2391,6 +2467,26 @@ private void addClassHeader(ClassDescription clazzDesc, ClassHeaderDescription h } } + private Iterable sortedHeaders(List headers, String baseline) { + if (baseline == null) { + return headers; + } + + //move the description whose version contains baseline to the front: + List result = new ArrayList<>(headers); + + for (Iterator it = result.iterator(); it.hasNext();) { + T fd = it.next(); + if (fd.versions.contains(baseline)) { + it.remove(); + result.add(0, fd); + break; + } + } + + return result; + } + private void addMethod(ClassDescription clazzDesc, MethodDescription methDesc, String version, String baseline) { //normalize: boolean methodExisted = false; @@ -2797,41 +2893,35 @@ protected boolean includeEffectiveAccess(ClassList classes, ClassDescription cla return true; } - boolean include(Set includedClasses, ClassList classes, String clazzName) { + void include(Set includedClasses, ClassList classes, String clazzName) { if (clazzName == null) - return false; + return ; ClassDescription desc = classes.find(clazzName, true); if (desc == null) { - return false; + return ; } - boolean modified = includedClasses.add(clazzName); + includedClasses.add(clazzName); for (ClassDescription outer : classes.enclosingClasses(desc)) { - modified |= includedClasses.add(outer.name); + includedClasses.add(outer.name); } - - return modified; } - boolean includeOutputType(Iterable features, + void includeOutputType(Iterable features, Function feature2Descriptor, Set includedClasses, ClassList classes) { - boolean modified = false; - for (T feature : features) { CharSequence sig = feature.signature != null ? feature.signature : feature2Descriptor.apply(feature); Matcher m = OUTPUT_TYPE_PATTERN.matcher(sig); while (m.find()) { - modified |= include(includedClasses, classes, m.group(1)); + include(includedClasses, classes, m.group(1)); } } - - return modified; } static final Pattern OUTPUT_TYPE_PATTERN = Pattern.compile("L([^;<]+)(;|<)"); @@ -3255,6 +3345,20 @@ public boolean read(LineBasedReader reader) throws IOException { return true; } + public Stream allPackages() { + List packages = new ArrayList<>(); + + exports.stream() + .map(ExportsDescription::packageName) + .forEach(packages::add); + if (extraModulePackages != null) { + packages.addAll(extraModulePackages); + } + + return packages.stream() + .map(p -> p.replace('/', '.')); + } + record ExportsDescription(String packageName, List to) { public String serialize() { return packageName + @@ -3660,6 +3764,7 @@ public void write(Appendable output, String baselineVersion, String version) thr } if (isSealed) { output.append(" sealed true"); + output.append(" permittedSubclasses " + serializeList(permittedSubclasses)); } writeAttributes(output); output.append("\n"); @@ -3680,6 +3785,11 @@ public boolean read(LineBasedReader reader) throws IOException { String nestMembersList = reader.attributes.get("nestMembers"); nestMembers = deserializeList(nestMembersList); isRecord = reader.attributes.containsKey("record"); + isSealed = reader.attributes.containsKey("permittedSubclasses"); + if (isSealed) { + String subclassesList = reader.attributes.get("permittedSubclasses"); + permittedSubclasses = deserializeList(subclassesList); + } readAttributes(reader); reader.moveNext(); @@ -3688,11 +3798,6 @@ public boolean read(LineBasedReader reader) throws IOException { } readInnerClasses(reader); - isSealed = reader.attributes.containsKey("permittedSubclasses"); - if (isSealed) { - String subclassesList = reader.attributes.get("permittedSubclasses"); - permittedSubclasses = deserializeList(subclassesList); - } return true; } @@ -4642,8 +4747,9 @@ public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOExce String currentVersion; String preReleaseTag; String moduleClasses; + String includedModules; - if (args.length == 7) { + if (args.length == 8) { ctDescriptionFileExtra = null; ctDescriptionFile = args[1]; ctSymLocation = args[2]; @@ -4651,7 +4757,8 @@ public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOExce currentVersion = args[4]; preReleaseTag = args[5]; moduleClasses = args[6]; - } else if (args.length == 8) { + includedModules = args[7]; + } else if (args.length == 9) { ctDescriptionFileExtra = args[1]; ctDescriptionFile = args[2]; ctSymLocation = args[3]; @@ -4659,6 +4766,7 @@ public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOExce currentVersion = args[5]; preReleaseTag = args[6]; moduleClasses = args[7]; + includedModules = args[8]; } else { help(); return ; @@ -4675,7 +4783,8 @@ public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOExce timestamp, currentVersion, preReleaseTag, - moduleClasses); + moduleClasses, + includedModules); break; } case "build-javadoc-data": { diff --git a/make/langtools/tools/javacserver/client/Client.java b/make/langtools/tools/javacserver/client/Client.java index 9576a9923a4e5..cc4ecca941ef4 100644 --- a/make/langtools/tools/javacserver/client/Client.java +++ b/make/langtools/tools/javacserver/client/Client.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.base/Java.gmk b/make/modules/java.base/Java.gmk index 729f7b19f6d07..8621ff945ccf6 100644 --- a/make/modules/java.base/Java.gmk +++ b/make/modules/java.base/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -36,8 +36,8 @@ EXCLUDE_FILES += \ $(TOPDIR)/src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java EXCLUDES += java/lang/doc-files \ - jdk/internal/classfile/snippet-files \ - jdk/internal/classfile/components/snippet-files + java/lang/classfile/snippet-files \ + java/lang/classfile/components/snippet-files # Exclude BreakIterator classes that are just used in compile process to generate # data files and shouldn't go in the product diff --git a/make/modules/java.base/Lib.gmk b/make/modules/java.base/Lib.gmk index 30261bab6e1eb..924cb8aae268b 100644 --- a/make/modules/java.base/Lib.gmk +++ b/make/modules/java.base/Lib.gmk @@ -245,7 +245,7 @@ ifeq ($(call isTargetOs, linux)+$(call isTargetCpu, x86_64)+$(INCLUDE_COMPILER2) TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ OPTIMIZATION := HIGH, \ CFLAGS := $(CFLAGS_JDKLIB), \ - CXXFLAGS := $(CXXFLAGS_JDKLIB), \ + CXXFLAGS := $(CXXFLAGS_JDKLIB) -std=c++17, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ LIBS := $(LIBCXX), \ diff --git a/make/modules/java.base/gensrc/GensrcCharacterData.gmk b/make/modules/java.base/gensrc/GensrcCharacterData.gmk index 23544c6a4cf70..beee18000f149 100644 --- a/make/modules/java.base/gensrc/GensrcCharacterData.gmk +++ b/make/modules/java.base/gensrc/GensrcCharacterData.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.datatransfer/Java.gmk b/make/modules/java.datatransfer/Java.gmk index 12eb67cff5153..6c5332f645737 100644 --- a/make/modules/java.datatransfer/Java.gmk +++ b/make/modules/java.datatransfer/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.desktop/Java.gmk b/make/modules/java.desktop/Java.gmk index 3b43862dd8049..66ef88dcf14d6 100644 --- a/make/modules/java.desktop/Java.gmk +++ b/make/modules/java.desktop/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.logging/Java.gmk b/make/modules/java.logging/Java.gmk index 04409a6f33173..781370b2e1879 100644 --- a/make/modules/java.logging/Java.gmk +++ b/make/modules/java.logging/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.management/Java.gmk b/make/modules/java.management/Java.gmk index 04409a6f33173..781370b2e1879 100644 --- a/make/modules/java.management/Java.gmk +++ b/make/modules/java.management/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.naming/Java.gmk b/make/modules/java.naming/Java.gmk index 519156b578e7b..a7ade637af579 100644 --- a/make/modules/java.naming/Java.gmk +++ b/make/modules/java.naming/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.rmi/Java.gmk b/make/modules/java.rmi/Java.gmk index caab120444132..6c607bd0572f2 100644 --- a/make/modules/java.rmi/Java.gmk +++ b/make/modules/java.rmi/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.security.jgss/Java.gmk b/make/modules/java.security.jgss/Java.gmk index 837cdd0809619..781370b2e1879 100644 --- a/make/modules/java.security.jgss/Java.gmk +++ b/make/modules/java.security.jgss/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.sql.rowset/Java.gmk b/make/modules/java.sql.rowset/Java.gmk index bfb6f8f034e47..6548dd46cae54 100644 --- a/make/modules/java.sql.rowset/Java.gmk +++ b/make/modules/java.sql.rowset/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.sql/Java.gmk b/make/modules/java.sql/Java.gmk index 837cdd0809619..781370b2e1879 100644 --- a/make/modules/java.sql/Java.gmk +++ b/make/modules/java.sql/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.xml.crypto/Java.gmk b/make/modules/java.xml.crypto/Java.gmk index ce9bb131d3c94..53e282aca272b 100644 --- a/make/modules/java.xml.crypto/Java.gmk +++ b/make/modules/java.xml.crypto/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/java.xml/Java.gmk b/make/modules/java.xml/Java.gmk index 70ae760066305..cf6f1753f1c3d 100644 --- a/make/modules/java.xml/Java.gmk +++ b/make/modules/java.xml/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.charsets/Java.gmk b/make/modules/jdk.charsets/Java.gmk index 7198efd9fcf51..fad05cc29f147 100644 --- a/make/modules/jdk.charsets/Java.gmk +++ b/make/modules/jdk.charsets/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.compiler/Gendata.gmk b/make/modules/jdk.compiler/Gendata.gmk index df0ced743e7d6..e9ff3c439bea5 100644 --- a/make/modules/jdk.compiler/Gendata.gmk +++ b/make/modules/jdk.compiler/Gendata.gmk @@ -42,6 +42,9 @@ CT_MODULES_API_TARGETS := \ $(foreach m, $(CT_MODULES) $(CT_TRANSITIVE_MODULES), \ $(call SetupJavaCompilationApiTarget, $m, $(JDK_OUTPUTDIR)/modules/$m)) +#undocumented modules which should also be included in ct.sym: +CT_EXTRA_MODULES := jdk.unsupported + SYMBOL_FILES := $(wildcard $(MODULE_SRC)/share/data/symbols/*) CT_DATA_DESCRIPTION += $(MODULE_SRC)/share/data/symbols/symbols @@ -72,6 +75,7 @@ $(SUPPORT_OUTPUTDIR)/symbols/ct.sym: $(COMPILE_CREATE_SYMBOLS) $(SYMBOL_FILES) \ $(RM) -r $(@D) $(MKDIR) -p $(@D) $(ECHO) Creating ct.sym classes + $(ECHO) $(CT_MODULES) $(CT_TRANSITIVE_MODULES) $(CT_EXTRA_MODULES) >$(SUPPORT_OUTPUTDIR)/symbols/included-modules $(BUILD_JAVA_SMALL) \ $(COMPILECREATESYMBOLS_ADD_EXPORTS) \ -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javac \ @@ -82,7 +86,8 @@ $(SUPPORT_OUTPUTDIR)/symbols/ct.sym: $(COMPILE_CREATE_SYMBOLS) $(SYMBOL_FILES) \ $(SOURCE_DATE_EPOCH) \ $(JDK_SOURCE_TARGET_VERSION) \ "$(VERSION_PRE)" \ - $(JDK_OUTPUTDIR)/modules/ + $(JDK_OUTPUTDIR)/modules/ \ + $(SUPPORT_OUTPUTDIR)/symbols/included-modules $(TOUCH) $@ # Copy ct.sym to the modules libs dir diff --git a/make/modules/jdk.compiler/Java.gmk b/make/modules/jdk.compiler/Java.gmk index 49572b6efb907..7e6793fc6379b 100644 --- a/make/modules/jdk.compiler/Java.gmk +++ b/make/modules/jdk.compiler/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.hotspot.agent/Java.gmk b/make/modules/jdk.hotspot.agent/Java.gmk index 2819813b4f484..52cb0c8d91a65 100644 --- a/make/modules/jdk.hotspot.agent/Java.gmk +++ b/make/modules/jdk.hotspot.agent/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.httpserver/Java.gmk b/make/modules/jdk.httpserver/Java.gmk index c1b5a0d6d0ca9..d7b2b2f70ca21 100644 --- a/make/modules/jdk.httpserver/Java.gmk +++ b/make/modules/jdk.httpserver/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.internal.jvmstat/Java.gmk b/make/modules/jdk.internal.jvmstat/Java.gmk index 697171c156bef..4376b7e348494 100644 --- a/make/modules/jdk.internal.jvmstat/Java.gmk +++ b/make/modules/jdk.internal.jvmstat/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.internal.le/Java.gmk b/make/modules/jdk.internal.le/Java.gmk index 17e7cdf71b4a3..75d99b8d2bb72 100644 --- a/make/modules/jdk.internal.le/Java.gmk +++ b/make/modules/jdk.internal.le/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.internal.le/Lib.gmk b/make/modules/jdk.internal.le/Lib.gmk index 42a2010527abf..75a2446cc5a18 100644 --- a/make/modules/jdk.internal.le/Lib.gmk +++ b/make/modules/jdk.internal.le/Lib.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.internal.opt/Java.gmk b/make/modules/jdk.internal.opt/Java.gmk index 4299496b1fc02..0c65d9ad94ee8 100644 --- a/make/modules/jdk.internal.opt/Java.gmk +++ b/make/modules/jdk.internal.opt/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.internal.vm.ci/Java.gmk b/make/modules/jdk.internal.vm.ci/Java.gmk index 7b846bc1bd9cd..0dd5af1f3ea72 100644 --- a/make/modules/jdk.internal.vm.ci/Java.gmk +++ b/make/modules/jdk.internal.vm.ci/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.jartool/Java.gmk b/make/modules/jdk.jartool/Java.gmk index 1cf56a317e7cb..f9b4538838f3b 100644 --- a/make/modules/jdk.jartool/Java.gmk +++ b/make/modules/jdk.jartool/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.javadoc/Java.gmk b/make/modules/jdk.javadoc/Java.gmk index 92bbec738a036..3035864ecbacb 100644 --- a/make/modules/jdk.javadoc/Java.gmk +++ b/make/modules/jdk.javadoc/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.jcmd/Java.gmk b/make/modules/jdk.jcmd/Java.gmk index 287bcbc6945c7..08209e9353821 100644 --- a/make/modules/jdk.jcmd/Java.gmk +++ b/make/modules/jdk.jcmd/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.jconsole/Java.gmk b/make/modules/jdk.jconsole/Java.gmk index 7688f7f6b5c0b..9166d6a7c1187 100644 --- a/make/modules/jdk.jconsole/Java.gmk +++ b/make/modules/jdk.jconsole/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.jdeps/Gensrc.gmk b/make/modules/jdk.jdeps/Gensrc.gmk index a5a72c543c72f..640143b1b56d7 100644 --- a/make/modules/jdk.jdeps/Gensrc.gmk +++ b/make/modules/jdk.jdeps/Gensrc.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.jdeps/Java.gmk b/make/modules/jdk.jdeps/Java.gmk index 914b0c6658709..69c7ae0433fc7 100644 --- a/make/modules/jdk.jdeps/Java.gmk +++ b/make/modules/jdk.jdeps/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.jdeps/Launcher.gmk b/make/modules/jdk.jdeps/Launcher.gmk index 4a5b5f408d554..9d7d3515fc2a7 100644 --- a/make/modules/jdk.jdeps/Launcher.gmk +++ b/make/modules/jdk.jdeps/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.jdi/Java.gmk b/make/modules/jdk.jdi/Java.gmk index 49e35d9c95105..76d05b06df48b 100644 --- a/make/modules/jdk.jdi/Java.gmk +++ b/make/modules/jdk.jdi/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.jpackage/Java.gmk b/make/modules/jdk.jpackage/Java.gmk index 04cef0d52853b..60fe53475c939 100644 --- a/make/modules/jdk.jpackage/Java.gmk +++ b/make/modules/jdk.jpackage/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.jshell/Java.gmk b/make/modules/jdk.jshell/Java.gmk index a9db351c333ad..744c85d960a94 100644 --- a/make/modules/jdk.jshell/Java.gmk +++ b/make/modules/jdk.jshell/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.localedata/Java.gmk b/make/modules/jdk.localedata/Java.gmk index 9f8ee95addd9b..d794dde2124ea 100644 --- a/make/modules/jdk.localedata/Java.gmk +++ b/make/modules/jdk.localedata/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/modules/jdk.sctp/Java.gmk b/make/modules/jdk.sctp/Java.gmk index 08cd8fca1ce6e..9fc531689ee42 100644 --- a/make/modules/jdk.sctp/Java.gmk +++ b/make/modules/jdk.sctp/Java.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/scripts/compare_exceptions.sh.incl b/make/scripts/compare_exceptions.sh.incl index d5043637145b2..cfbfeeb5be4f9 100644 --- a/make/scripts/compare_exceptions.sh.incl +++ b/make/scripts/compare_exceptions.sh.incl @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/scripts/fixpath.sh b/make/scripts/fixpath.sh index 9c8db7383f2de..3a886fee07c47 100644 --- a/make/scripts/fixpath.sh +++ b/make/scripts/fixpath.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/scripts/hotspot.sh b/make/scripts/hotspot.sh.template similarity index 100% rename from make/scripts/hotspot.sh rename to make/scripts/hotspot.sh.template diff --git a/make/src/classes/build/tools/jfr/GenerateJfrFiles.java b/make/src/classes/build/tools/jfr/GenerateJfrFiles.java index 6b89d02ad2f75..3497d03292d81 100644 --- a/make/src/classes/build/tools/jfr/GenerateJfrFiles.java +++ b/make/src/classes/build/tools/jfr/GenerateJfrFiles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -198,6 +198,7 @@ static class TypeElement { String period = ""; boolean cutoff; boolean throttle; + String level = ""; boolean experimental; boolean internal; long id; @@ -222,6 +223,7 @@ public void persist(DataOutputStream pos) throws IOException { pos.writeUTF(period); pos.writeBoolean(cutoff); pos.writeBoolean(throttle); + pos.writeUTF(level); pos.writeBoolean(experimental); pos.writeBoolean(internal); pos.writeLong(id); @@ -520,6 +522,7 @@ public void startElement(String uri, String localName, String qName, Attributes currentType.startTime = getBoolean(attributes, "startTime", true); currentType.period = getString(attributes, "period"); currentType.cutoff = getBoolean(attributes, "cutoff", false); + currentType.level = getString(attributes, "level"); currentType.throttle = getBoolean(attributes, "throttle", false); currentType.commitState = getString(attributes, "commitState"); currentType.isEvent = "Event".equals(qName); @@ -651,7 +654,7 @@ private static void printJfrEventControlHpp(Metadata metadata, File outputFile) out.write(""); out.write("struct jfrNativeEventSetting {"); out.write(" jlong threshold_ticks;"); - out.write(" jlong cutoff_ticks;"); + out.write(" jlong miscellaneous;"); out.write(" u1 stacktrace;"); out.write(" u1 enabled;"); out.write(" u1 large;"); diff --git a/make/test/BuildFailureHandler.gmk b/make/test/BuildFailureHandler.gmk index ac133dc6a68e6..78eb3692e8a74 100644 --- a/make/test/BuildFailureHandler.gmk +++ b/make/test/BuildFailureHandler.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk index 0785688f09c30..628f385572829 100644 --- a/make/test/BuildMicrobenchmark.gmk +++ b/make/test/BuildMicrobenchmark.gmk @@ -53,11 +53,10 @@ JMH_UNPACKED_DIR := $(MICROBENCHMARK_OUTPUT)/jmh_jars JMH_UNPACKED_JARS_DONE := $(JMH_UNPACKED_DIR)/_unpacked.marker # External dependencies -JMH_COMPILE_JARS := $(JMH_CORE_JAR) $(JMH_GENERATOR_JAR) +WHITEBOX_JAR := $(SUPPORT_OUTPUTDIR)/test/lib/wb.jar +JMH_COMPILE_JARS := $(JMH_CORE_JAR) $(JMH_GENERATOR_JAR) $(WHITEBOX_JAR) JMH_RUNTIME_JARS := $(JMH_CORE_JAR) $(JMH_COMMONS_MATH_JAR) $(JMH_JOPT_SIMPLE_JAR) -MICROBENCHMARK_CLASSPATH := $(call PathList, $(JMH_COMPILE_JARS)) - # Native dependencies MICROBENCHMARK_NATIVE_SRC_DIRS := $(MICROBENCHMARK_SRC) MICROBENCHMARK_NATIVE_OUTPUT := $(MICROBENCHMARK_OUTPUT)/native @@ -92,29 +91,28 @@ $(eval $(call SetupJavaCompilation, BUILD_INDIFY, \ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \ TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \ SMALL_JAVA := false, \ - CLASSPATH := $(MICROBENCHMARK_CLASSPATH), \ - DISABLED_WARNINGS := restricted this-escape processing rawtypes cast serial preview, \ + CLASSPATH := $(JMH_COMPILE_JARS), \ + DISABLED_WARNINGS := restricted this-escape processing rawtypes cast \ + serial preview, \ SRC := $(MICROBENCHMARK_SRC), \ BIN := $(MICROBENCHMARK_CLASSES), \ - JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \ - --add-exports java.base/sun.invoke.util=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.classfile=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.classfile.attribute=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.classfile.instruction=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.classfile.components=ALL-UNNAMED \ + JAVAC_FLAGS := \ --add-exports java.base/jdk.internal.classfile.impl=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.vm=ALL-UNNAMED \ - --add-exports java.base/jdk.internal.misc=ALL-UNNAMED \ --add-exports java.base/jdk.internal.event=ALL-UNNAMED \ --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED \ + --add-exports java.base/jdk.internal.misc=ALL-UNNAMED \ + --add-exports java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED \ + --add-exports java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED \ + --add-exports java.base/jdk.internal.vm=ALL-UNNAMED \ + --add-exports java.base/sun.invoke.util=ALL-UNNAMED \ + --add-exports java.base/sun.security.util=ALL-UNNAMED \ --enable-preview \ -processor org.openjdk.jmh.generators.BenchmarkProcessor, \ - JAVA_FLAGS := --add-modules jdk.unsupported --limit-modules java.management \ + JAVA_FLAGS := \ --add-exports java.base/jdk.internal.vm=ALL-UNNAMED \ - --enable-preview, \ + --add-modules jdk.unsupported \ + --enable-preview \ + --limit-modules java.management, \ )) $(BUILD_JDK_MICROBENCHMARK): $(JMH_COMPILE_JARS) diff --git a/make/test/BuildTestLib.gmk b/make/test/BuildTestLib.gmk index 72f777ec6c1b4..54c4c61642c1d 100644 --- a/make/test/BuildTestLib.gmk +++ b/make/test/BuildTestLib.gmk @@ -23,12 +23,22 @@ # questions. # +################################################################################ +# This file builds the Java components of testlib. +# It also covers the test-image part, where the built files are copied to the +# test image. +################################################################################ + default: all include $(SPEC) include MakeBase.gmk include JavaCompilation.gmk +################################################################################ +# Targets for building the test lib jars +################################################################################ + TARGETS := TEST_LIB_SOURCE_DIR := $(TOPDIR)/test/lib @@ -63,8 +73,21 @@ $(eval $(call SetupJavaCompilation, BUILD_TEST_LIB_JAR, \ TARGETS += $(BUILD_TEST_LIB_JAR) -########################################################################################## +build-test-lib: $(TARGETS) + +################################################################################ +# Targets for building test-image. +################################################################################ + +# Copy the jars to the test image. +$(eval $(call SetupCopyFiles, COPY_LIBTEST_JARS, \ + DEST := $(TEST_IMAGE_DIR)/lib-test, \ + FILES := $(BUILD_WB_JAR_JAR) $(BUILD_TEST_LIB_JAR_JAR), \ +)) +# + +test-image-lib: $(COPY_LIBTEST_JARS) -all: $(TARGETS) +all: build-test-lib -.PHONY: default all +.PHONY: default all build-test-lib test-image-lib diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk index 24fcac2198ebe..98101ee1e86bf 100644 --- a/make/test/JtregNativeHotspot.gmk +++ b/make/test/JtregNativeHotspot.gmk @@ -861,7 +861,7 @@ BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exesigtest := -ljvm ifeq ($(call isTargetOs, windows), true) BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS_exeFPRegs := -MT - BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c libTestPsig.c exeGetCreatedJavaVMs.c + BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c libMonitorWithDeadObjectTest.c libTestPsig.c exeGetCreatedJavaVMs.c BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit := jvm.lib BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libnativeStack := jvm.lib BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exedaemonDestroy := jvm.lib @@ -1503,6 +1503,7 @@ else BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libterminatedThread += -lpthread BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit += -ljvm BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libCompleteExit += -lpthread + BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMonitorWithDeadObjectTest += -lpthread BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libnativeStack += -lpthread BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeGetCreatedJavaVMs := -ljvm -lpthread diff --git a/src/hotspot/cpu/aarch64/aarch64_vector.ad b/src/hotspot/cpu/aarch64/aarch64_vector.ad index ebf587f2121e8..210efa0b760cd 100644 --- a/src/hotspot/cpu/aarch64/aarch64_vector.ad +++ b/src/hotspot/cpu/aarch64/aarch64_vector.ad @@ -3742,6 +3742,68 @@ instruct reinterpret_resize_gt128b(vReg dst, vReg src, pReg ptmp, rFlagsReg cr) ins_pipe(pipe_slow); %} +// ---------------------------- Vector zero extend -------------------------------- + +instruct vzeroExtBtoX(vReg dst, vReg src) %{ + match(Set dst (VectorUCastB2X src)); + format %{ "vzeroExtBtoX $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + assert(bt == T_SHORT || bt == T_INT || bt == T_LONG, "must be"); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + if (VM_Version::use_neon_for_vector(length_in_bytes)) { + // 4B to 4S/4I, 8B to 8S + __ neon_vector_extend($dst$$FloatRegister, bt, length_in_bytes, + $src$$FloatRegister, T_BYTE, /* is_unsigned */ true); + } else { + assert(UseSVE > 0, "must be sve"); + __ sve_vector_extend($dst$$FloatRegister, __ elemType_to_regVariant(bt), + $src$$FloatRegister, __ B, /* is_unsigned */ true); + } + %} + ins_pipe(pipe_slow); +%} + +instruct vzeroExtStoX(vReg dst, vReg src) %{ + match(Set dst (VectorUCastS2X src)); + format %{ "vzeroExtStoX $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + assert(bt == T_INT || bt == T_LONG, "must be"); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + if (VM_Version::use_neon_for_vector(length_in_bytes)) { + // 4S to 4I + __ neon_vector_extend($dst$$FloatRegister, T_INT, length_in_bytes, + $src$$FloatRegister, T_SHORT, /* is_unsigned */ true); + } else { + assert(UseSVE > 0, "must be sve"); + __ sve_vector_extend($dst$$FloatRegister, __ elemType_to_regVariant(bt), + $src$$FloatRegister, __ H, /* is_unsigned */ true); + } + %} + ins_pipe(pipe_slow); +%} + +instruct vzeroExtItoX(vReg dst, vReg src) %{ + match(Set dst (VectorUCastI2X src)); + format %{ "vzeroExtItoX $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + assert(bt == T_LONG, "must be"); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + if (VM_Version::use_neon_for_vector(length_in_bytes)) { + // 2I to 2L + __ neon_vector_extend($dst$$FloatRegister, T_LONG, length_in_bytes, + $src$$FloatRegister, T_INT, /* is_unsigned */ true); + } else { + assert(UseSVE > 0, "must be sve"); + __ sve_vector_extend($dst$$FloatRegister, __ D, + $src$$FloatRegister, __ S, /* is_unsigned */ true); + } + %} + ins_pipe(pipe_slow); +%} + // ------------------------------ Vector cast ---------------------------------- // VectorCastB2X diff --git a/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 b/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 index e27ca993e607c..3f4ed020f55c5 100644 --- a/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 +++ b/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 @@ -2276,6 +2276,33 @@ instruct reinterpret_resize_gt128b(vReg dst, vReg src, pReg ptmp, rFlagsReg cr) ins_pipe(pipe_slow); %} +// ---------------------------- Vector zero extend -------------------------------- +dnl VECTOR_ZERO_EXTEND($1, $2, $3, $4, $5 $6, $7, ) +dnl VECTOR_ZERO_EXTEND(op_name, dst_bt, src_bt, dst_size, src_size, assertion, neon_comment) +define(`VECTOR_ZERO_EXTEND', ` +instruct vzeroExt$1toX(vReg dst, vReg src) %{ + match(Set dst (VectorUCast`$1'2X src)); + format %{ "vzeroExt$1toX $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + assert($6, "must be"); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + if (VM_Version::use_neon_for_vector(length_in_bytes)) { + // $7 + __ neon_vector_extend($dst$$FloatRegister, $2, length_in_bytes, + $src$$FloatRegister, $3, /* is_unsigned */ true); + } else { + assert(UseSVE > 0, "must be sve"); + __ sve_vector_extend($dst$$FloatRegister, __ $4, + $src$$FloatRegister, __ $5, /* is_unsigned */ true); + } + %} + ins_pipe(pipe_slow); +%}')dnl +VECTOR_ZERO_EXTEND(B, bt, T_BYTE, elemType_to_regVariant(bt), B, bt == T_SHORT || bt == T_INT || bt == T_LONG, `4B to 4S/4I, 8B to 8S') +VECTOR_ZERO_EXTEND(S, T_INT, T_SHORT, elemType_to_regVariant(bt), H, bt == T_INT || bt == T_LONG, `4S to 4I') +VECTOR_ZERO_EXTEND(I, T_LONG, T_INT, D, S, bt == T_LONG, `2I to 2L') + // ------------------------------ Vector cast ---------------------------------- // VectorCastB2X diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp index 2899319f3e8e5..187c1209303a3 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp @@ -2196,41 +2196,20 @@ void mvnw(Register Rd, Register Rm, #undef INSN - enum sign_kind { SIGNED, UNSIGNED }; - private: - void _xcvtf_scalar_integer(sign_kind sign, unsigned sz, - FloatRegister Rd, FloatRegister Rn) { - starti; - f(0b01, 31, 30), f(sign == SIGNED ? 0 : 1, 29); - f(0b111100, 27, 23), f((sz >> 1) & 1, 22), f(0b100001110110, 21, 10); - rf(Rn, 5), rf(Rd, 0); - } - -public: -#define INSN(NAME, sign, sz) \ - void NAME(FloatRegister Rd, FloatRegister Rn) { \ - _xcvtf_scalar_integer(sign, sz, Rd, Rn); \ - } - - INSN(scvtfs, SIGNED, 0); - INSN(scvtfd, SIGNED, 1); - -#undef INSN - -private: - void _xcvtf_vector_integer(sign_kind sign, SIMD_Arrangement T, + void _xcvtf_vector_integer(bool is_unsigned, SIMD_Arrangement T, FloatRegister Rd, FloatRegister Rn) { assert(T == T2S || T == T4S || T == T2D, "invalid arrangement"); starti; - f(0, 31), f(T & 1, 30), f(sign == SIGNED ? 0 : 1, 29); + f(0, 31), f(T & 1, 30), f(is_unsigned ? 1 : 0, 29); f(0b011100, 28, 23), f((T >> 1) & 1, 22), f(0b100001110110, 21, 10); rf(Rn, 5), rf(Rd, 0); } public: + void scvtfv(SIMD_Arrangement T, FloatRegister Rd, FloatRegister Rn) { - _xcvtf_vector_integer(SIGNED, T, Rd, Rn); + _xcvtf_vector_integer(/* is_unsigned */ false, T, Rd, Rn); } // Floating-point compare @@ -2991,8 +2970,8 @@ template #undef INSN -private: - void _xshll(sign_kind sign, FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) { +protected: + void _xshll(bool is_unsigned, FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) { starti; /* The encodings for the immh:immb fields (bits 22:16) are * 0001 xxx 8H, 8B/16B shift = xxx @@ -3002,7 +2981,7 @@ template */ assert((Tb >> 1) + 1 == (Ta >> 1), "Incompatible arrangement"); assert((1 << ((Tb>>1)+3)) > shift, "Invalid shift value"); - f(0, 31), f(Tb & 1, 30), f(sign == SIGNED ? 0 : 1, 29), f(0b011110, 28, 23); + f(0, 31), f(Tb & 1, 30), f(is_unsigned ? 1 : 0, 29), f(0b011110, 28, 23); f((1 << ((Tb>>1)+3))|shift, 22, 16); f(0b101001, 15, 10), rf(Vn, 5), rf(Vd, 0); } @@ -3010,12 +2989,12 @@ template public: void ushll(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) { assert(Tb == T8B || Tb == T4H || Tb == T2S, "invalid arrangement"); - _xshll(UNSIGNED, Vd, Ta, Vn, Tb, shift); + _xshll(/* is_unsigned */ true, Vd, Ta, Vn, Tb, shift); } void ushll2(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) { assert(Tb == T16B || Tb == T8H || Tb == T4S, "invalid arrangement"); - _xshll(UNSIGNED, Vd, Ta, Vn, Tb, shift); + _xshll(/* is_unsigned */ true, Vd, Ta, Vn, Tb, shift); } void uxtl(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb) { @@ -3024,12 +3003,12 @@ template void sshll(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) { assert(Tb == T8B || Tb == T4H || Tb == T2S, "invalid arrangement"); - _xshll(SIGNED, Vd, Ta, Vn, Tb, shift); + _xshll(/* is_unsigned */ false, Vd, Ta, Vn, Tb, shift); } void sshll2(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb, int shift) { assert(Tb == T16B || Tb == T8H || Tb == T4S, "invalid arrangement"); - _xshll(SIGNED, Vd, Ta, Vn, Tb, shift); + _xshll(/* is_unsigned */ false, Vd, Ta, Vn, Tb, shift); } void sxtl(FloatRegister Vd, SIMD_Arrangement Ta, FloatRegister Vn, SIMD_Arrangement Tb) { @@ -3862,18 +3841,25 @@ template } // SVE unpack vector elements -#define INSN(NAME, op) \ - void NAME(FloatRegister Zd, SIMD_RegVariant T, FloatRegister Zn) { \ - starti; \ - assert(T != B && T != Q, "invalid size"); \ - f(0b00000101, 31, 24), f(T, 23, 22), f(0b1100, 21, 18); \ - f(op, 17, 16), f(0b001110, 15, 10), rf(Zn, 5), rf(Zd, 0); \ +protected: + void _sve_xunpk(bool is_unsigned, bool is_high, FloatRegister Zd, SIMD_RegVariant T, FloatRegister Zn) { + starti; + assert(T != B && T != Q, "invalid size"); + f(0b00000101, 31, 24), f(T, 23, 22), f(0b1100, 21, 18); + f(is_unsigned ? 1 : 0, 17), f(is_high ? 1 : 0, 16), + f(0b001110, 15, 10), rf(Zn, 5), rf(Zd, 0); + } + +public: +#define INSN(NAME, is_unsigned, is_high) \ + void NAME(FloatRegister Zd, SIMD_RegVariant T, FloatRegister Zn) { \ + _sve_xunpk(is_unsigned, is_high, Zd, T, Zn); \ } - INSN(sve_uunpkhi, 0b11); // Signed unpack and extend half of vector - high half - INSN(sve_uunpklo, 0b10); // Signed unpack and extend half of vector - low half - INSN(sve_sunpkhi, 0b01); // Unsigned unpack and extend half of vector - high half - INSN(sve_sunpklo, 0b00); // Unsigned unpack and extend half of vector - low half + INSN(sve_uunpkhi, true, true ); // Unsigned unpack and extend half of vector - high half + INSN(sve_uunpklo, true, false); // Unsigned unpack and extend half of vector - low half + INSN(sve_sunpkhi, false, true ); // Signed unpack and extend half of vector - high half + INSN(sve_sunpklo, false, false); // Signed unpack and extend half of vector - low half #undef INSN // SVE unpack predicate elements diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp index 5338eff0134f8..7b9784ec47a24 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp @@ -1340,26 +1340,25 @@ void C2_MacroAssembler::sve_vmask_lasttrue(Register dst, BasicType bt, PRegister // Extend integer vector src to dst with the same lane count // but larger element size, e.g. 4B -> 4I void C2_MacroAssembler::neon_vector_extend(FloatRegister dst, BasicType dst_bt, unsigned dst_vlen_in_bytes, - FloatRegister src, BasicType src_bt) { + FloatRegister src, BasicType src_bt, bool is_unsigned) { if (src_bt == T_BYTE) { if (dst_bt == T_SHORT) { // 4B/8B to 4S/8S - assert(dst_vlen_in_bytes == 8 || dst_vlen_in_bytes == 16, "unsupported"); - sxtl(dst, T8H, src, T8B); + _xshll(is_unsigned, dst, T8H, src, T8B, 0); } else { // 4B to 4I assert(dst_vlen_in_bytes == 16 && dst_bt == T_INT, "unsupported"); - sxtl(dst, T8H, src, T8B); - sxtl(dst, T4S, dst, T4H); + _xshll(is_unsigned, dst, T8H, src, T8B, 0); + _xshll(is_unsigned, dst, T4S, dst, T4H, 0); } } else if (src_bt == T_SHORT) { // 4S to 4I assert(dst_vlen_in_bytes == 16 && dst_bt == T_INT, "unsupported"); - sxtl(dst, T4S, src, T4H); + _xshll(is_unsigned, dst, T4S, src, T4H, 0); } else if (src_bt == T_INT) { // 2I to 2L assert(dst_vlen_in_bytes == 16 && dst_bt == T_LONG, "unsupported"); - sxtl(dst, T2D, src, T2S); + _xshll(is_unsigned, dst, T2D, src, T2S, 0); } else { ShouldNotReachHere(); } @@ -1393,34 +1392,36 @@ void C2_MacroAssembler::neon_vector_narrow(FloatRegister dst, BasicType dst_bt, } void C2_MacroAssembler::sve_vector_extend(FloatRegister dst, SIMD_RegVariant dst_size, - FloatRegister src, SIMD_RegVariant src_size) { + FloatRegister src, SIMD_RegVariant src_size, + bool is_unsigned) { assert(dst_size > src_size && dst_size <= D && src_size <= S, "invalid element size"); + if (src_size == B) { switch (dst_size) { case H: - sve_sunpklo(dst, H, src); + _sve_xunpk(is_unsigned, /* is_high */ false, dst, H, src); break; case S: - sve_sunpklo(dst, H, src); - sve_sunpklo(dst, S, dst); + _sve_xunpk(is_unsigned, /* is_high */ false, dst, H, src); + _sve_xunpk(is_unsigned, /* is_high */ false, dst, S, dst); break; case D: - sve_sunpklo(dst, H, src); - sve_sunpklo(dst, S, dst); - sve_sunpklo(dst, D, dst); + _sve_xunpk(is_unsigned, /* is_high */ false, dst, H, src); + _sve_xunpk(is_unsigned, /* is_high */ false, dst, S, dst); + _sve_xunpk(is_unsigned, /* is_high */ false, dst, D, dst); break; default: ShouldNotReachHere(); } } else if (src_size == H) { if (dst_size == S) { - sve_sunpklo(dst, S, src); + _sve_xunpk(is_unsigned, /* is_high */ false, dst, S, src); } else { // D - sve_sunpklo(dst, S, src); - sve_sunpklo(dst, D, dst); + _sve_xunpk(is_unsigned, /* is_high */ false, dst, S, src); + _sve_xunpk(is_unsigned, /* is_high */ false, dst, D, dst); } } else if (src_size == S) { - sve_sunpklo(dst, D, src); + _sve_xunpk(is_unsigned, /* is_high */ false, dst, D, src); } } diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp index f342ca3c977b9..dfa7d88cb93fe 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp @@ -94,13 +94,13 @@ // Vector cast void neon_vector_extend(FloatRegister dst, BasicType dst_bt, unsigned dst_vlen_in_bytes, - FloatRegister src, BasicType src_bt); + FloatRegister src, BasicType src_bt, bool is_unsigned = false); void neon_vector_narrow(FloatRegister dst, BasicType dst_bt, FloatRegister src, BasicType src_bt, unsigned src_vlen_in_bytes); void sve_vector_extend(FloatRegister dst, SIMD_RegVariant dst_size, - FloatRegister src, SIMD_RegVariant src_size); + FloatRegister src, SIMD_RegVariant src_size, bool is_unsigned = false); void sve_vector_narrow(FloatRegister dst, SIMD_RegVariant dst_size, FloatRegister src, SIMD_RegVariant src_size, FloatRegister tmp); diff --git a/src/hotspot/cpu/aarch64/compressedKlass_aarch64.cpp b/src/hotspot/cpu/aarch64/compressedKlass_aarch64.cpp new file mode 100644 index 0000000000000..d035ab21093da --- /dev/null +++ b/src/hotspot/cpu/aarch64/compressedKlass_aarch64.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2023, Red Hat, Inc. All rights reserved. + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "asm/assembler.hpp" +#include "logging/log.hpp" +#include "oops/compressedKlass.hpp" +#include "memory/metaspace.hpp" +#include "runtime/os.hpp" +#include "utilities/globalDefinitions.hpp" + +// Helper function; reserve at an address that is compatible with EOR +static char* reserve_at_eor_compatible_address(size_t size, bool aslr) { + char* result = nullptr; + + log_debug(metaspace, map)("Trying to reserve at an EOR-compatible address"); + + // We need immediates that are 32-bit aligned, since they should not intersect nKlass + // bits. They should not be larger than the addressable space either, but we still + // lack a good abstraction for that (see JDK-8320584), therefore we assume and hard-code + // 2^48 as a reasonable higher ceiling. + static const uint16_t immediates[] = { + 0x0001, 0x0002, 0x0003, 0x0004, 0x0006, 0x0007, 0x0008, 0x000c, 0x000e, + 0x000f, 0x0010, 0x0018, 0x001c, 0x001e, 0x001f, 0x0020, 0x0030, 0x0038, + 0x003c, 0x003e, 0x003f, 0x0040, 0x0060, 0x0070, 0x0078, 0x007c, 0x007e, + 0x007f, 0x0080, 0x00c0, 0x00e0, 0x00f0, 0x00f8, 0x00fc, 0x00fe, 0x00ff, + 0x0100, 0x0180, 0x01c0, 0x01e0, 0x01f0, 0x01f8, 0x01fc, 0x01fe, 0x01ff, + 0x0200, 0x0300, 0x0380, 0x03c0, 0x03e0, 0x03f0, 0x03f8, 0x03fc, 0x03fe, + 0x03ff, 0x0400, 0x0600, 0x0700, 0x0780, 0x07c0, 0x07e0, 0x07f0, 0x07f8, + 0x07fc, 0x07fe, 0x07ff, 0x0800, 0x0c00, 0x0e00, 0x0f00, 0x0f80, 0x0fc0, + 0x0fe0, 0x0ff0, 0x0ff8, 0x0ffc, 0x0ffe, 0x0fff, 0x1000, 0x1800, 0x1c00, + 0x1e00, 0x1f00, 0x1f80, 0x1fc0, 0x1fe0, 0x1ff0, 0x1ff8, 0x1ffc, 0x1ffe, + 0x1fff, 0x2000, 0x3000, 0x3800, 0x3c00, 0x3e00, 0x3f00, 0x3f80, 0x3fc0, + 0x3fe0, 0x3ff0, 0x3ff8, 0x3ffc, 0x3ffe, 0x3fff, 0x4000, 0x6000, 0x7000, + 0x7800, 0x7c00, 0x7e00, 0x7f00, 0x7f80, 0x7fc0, 0x7fe0, 0x7ff0, 0x7ff8, + 0x7ffc, 0x7ffe, 0x7fff + }; + static constexpr int num_immediates = sizeof(immediates) / sizeof(immediates[0]); + const int start_index = aslr ? os::random() : 0; + constexpr int max_tries = 64; + for (int ntry = 0; result == nullptr && ntry < max_tries; ntry ++) { + // As in os::attempt_reserve_memory_between, we alternate between higher and lower + // addresses; this maximizes the chance of early success if part of the address space + // is not accessible (e.g. 39-bit address space). + const int alt_index = (ntry & 1) ? 0 : num_immediates / 2; + const int index = (start_index + ntry + alt_index) % num_immediates; + const uint64_t immediate = ((uint64_t)immediates[index]) << 32; + assert(immediate > 0 && Assembler::operand_valid_for_logical_immediate(/*is32*/false, immediate), + "Invalid immediate %d " UINT64_FORMAT, index, immediate); + result = os::attempt_reserve_memory_at((char*)immediate, size, false); + if (result == nullptr) { + log_trace(metaspace, map)("Failed to attach at " UINT64_FORMAT_X, immediate); + } + } + if (result == nullptr) { + log_debug(metaspace, map)("Failed to reserve at any EOR-compatible address"); + } + return result; +} +char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size_t size, bool aslr, bool optimize_for_zero_base) { + + char* result = nullptr; + + // Optimize for base=0 shift=0 + if (optimize_for_zero_base) { + result = reserve_address_space_for_unscaled_encoding(size, aslr); + } + + // If this fails, we don't bother aiming for zero-based encoding (base=0 shift>0), since it has no + // advantages over EOR or movk mode. + + // EOR-compatible reservation + if (result == nullptr) { + result = reserve_at_eor_compatible_address(size, aslr); + } + + // Movk-compatible reservation via probing. + if (result == nullptr) { + result = reserve_address_space_for_16bit_move(size, aslr); + } + + // Movk-compatible reservation via overallocation. + // If that failed, attempt to allocate at any 4G-aligned address. Let the system decide where. For ASLR, + // we now rely on the system. + // Compared with the probing done above, this has two disadvantages: + // - on a kernel with 52-bit address space we may get an address that has bits set between [48, 52). + // In that case, we may need two movk moves (not yet implemented). + // - this technique leads to temporary over-reservation of address space; it will spike the vsize of + // the process. Therefore it may fail if a vsize limit is in place (e.g. ulimit -v). + if (result == nullptr) { + constexpr size_t alignment = nth_bit(32); + log_debug(metaspace, map)("Trying to reserve at a 32-bit-aligned address"); + result = os::reserve_memory_aligned(size, alignment, false); + } + + return result; +} + +void CompressedKlassPointers::initialize(address addr, size_t len) { + constexpr uintptr_t unscaled_max = nth_bit(32); + assert(len <= unscaled_max, "Klass range larger than 32 bits?"); + + // Shift is always 0 on aarch64. + _shift = 0; + + // On aarch64, we don't bother with zero-based encoding (base=0 shift>0). + address const end = addr + len; + _base = (end <= (address)unscaled_max) ? nullptr : addr; + + _range = end - _base; +} diff --git a/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp b/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp index c5bcc38b5f651..4322eb1c4fcb6 100644 --- a/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp @@ -51,6 +51,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg); int locs_size = 1; // must be non-zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); + if (code.blob() == nullptr) { + return nullptr; + } StubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer, captured_state_mask, @@ -58,12 +61,19 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, g.generate(); code.log_section_sizes("nep_invoker_blob"); + bool caller_must_gc_arguments = false; + bool alloc_fail_is_fatal = false; RuntimeStub* stub = RuntimeStub::new_runtime_stub("nep_invoker_blob", &code, g.frame_complete(), g.framesize(), - g.oop_maps(), false); + g.oop_maps(), + caller_must_gc_arguments, + alloc_fail_is_fatal); + if (stub == nullptr) { + return nullptr; + } #ifndef PRODUCT LogTarget(Trace, foreign, downcall) lt; @@ -268,6 +278,9 @@ void DowncallLinker::StubGenerator::generate() { Label L_reguard; Label L_after_reguard; if (_needs_transition) { + // Restore cpu control state after JNI call + __ restore_cpu_control_state_after_jni(rscratch1, tmp1); + __ mov(tmp1, _thread_in_native_trans); __ strw(tmp1, Address(rthread, JavaThread::thread_state_offset())); diff --git a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp index f204b8d9cfac5..2293d70c8dacd 100644 --- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp @@ -42,6 +42,8 @@ const bool CCallingConventionRequiresIntsAsLongs = false; // and Operational Models for ARMv8" #define CPU_MULTI_COPY_ATOMIC +#define DEFAULT_CACHE_LINE_SIZE 64 + // According to the ARMv8 ARM, "Concurrent modification and execution // of instructions can lead to the resulting instruction performing // any behavior that can be achieved by executing any sequence of diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 82316d5152a48..a3c560b28d3cf 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -4428,6 +4428,23 @@ void MacroAssembler::load_klass(Register dst, Register src) { } } +void MacroAssembler::restore_cpu_control_state_after_jni(Register tmp1, Register tmp2) { + if (RestoreMXCSROnJNICalls) { + Label OK; + get_fpcr(tmp1); + mov(tmp2, tmp1); + // Set FPCR to the state we need. We do want Round to Nearest. We + // don't want non-IEEE rounding modes or floating-point traps. + bfi(tmp1, zr, 22, 4); // Clear DN, FZ, and Rmode + bfi(tmp1, zr, 8, 5); // Clear exception-control bits (8-12) + bfi(tmp1, zr, 0, 2); // Clear AH:FIZ + eor(tmp2, tmp1, tmp2); + cbz(tmp2, OK); // Only reset FPCR if it's wrong + set_fpcr(tmp1); + bind(OK); + } +} + // ((OopHandle)result).resolve(); void MacroAssembler::resolve_oop_handle(Register result, Register tmp1, Register tmp2) { // OopHandle::resolve is an indirection. @@ -5651,7 +5668,7 @@ void MacroAssembler::fill_words(Register base, Register cnt, Register value) // - sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray // return the number of characters copied. // - java/lang/StringUTF16.compress -// return zero (0) if copy fails, otherwise 'len'. +// return index of non-latin1 character if copy fails, otherwise 'len'. // // This version always returns the number of characters copied, and does not // clobber the 'len' register. A successful copy will complete with the post- @@ -5868,15 +5885,15 @@ address MacroAssembler::byte_array_inflate(Register src, Register dst, Register } // Compress char[] array to byte[]. +// Intrinsic for java.lang.StringUTF16.compress(char[] src, int srcOff, byte[] dst, int dstOff, int len) +// Return the array length if every element in array can be encoded, +// otherwise, the index of first non-latin1 (> 0xff) character. void MacroAssembler::char_array_compress(Register src, Register dst, Register len, Register res, FloatRegister tmp0, FloatRegister tmp1, FloatRegister tmp2, FloatRegister tmp3, FloatRegister tmp4, FloatRegister tmp5) { encode_iso_array(src, dst, len, res, false, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5); - // Adjust result: res == len ? len : 0 - cmp(len, res); - csel(res, res, zr, EQ); } // java.math.round(double a) diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index 3bd22ee25fb81..84931c409cfe9 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -1047,8 +1047,8 @@ class MacroAssembler: public Assembler { #define verify_method_ptr(reg) _verify_method_ptr(reg, "broken method " #reg, __FILE__, __LINE__) #define verify_klass_ptr(reg) _verify_klass_ptr(reg, "broken klass " #reg, __FILE__, __LINE__) - // only if +VerifyFPU - void verify_FPU(int stack_depth, const char* s = "illegal FPU state"); + // Restore cpu control state after JNI call + void restore_cpu_control_state_after_jni(Register tmp1, Register tmp2); // prints msg, dumps registers and stops execution void stop(const char* msg); diff --git a/src/hotspot/cpu/aarch64/matcher_aarch64.hpp b/src/hotspot/cpu/aarch64/matcher_aarch64.hpp index aa22459d21734..08bff22d7d0a2 100644 --- a/src/hotspot/cpu/aarch64/matcher_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/matcher_aarch64.hpp @@ -193,4 +193,9 @@ } } + // Is SIMD sort supported for this CPU? + static bool supports_simd_sort(BasicType bt) { + return false; + } + #endif // CPU_AARCH64_MATCHER_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index fa2faddd714d3..c7b45ff0dde17 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -1838,6 +1838,9 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, intptr_t return_pc = (intptr_t) __ pc(); oop_maps->add_gc_map(return_pc - start, map); + // Verify or restore cpu control state after JNI call + __ restore_cpu_control_state_after_jni(rscratch1, rscratch2); + // Unpack native results. switch (ret_type) { case T_BOOLEAN: __ c2bool(r0); break; diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index c21a56972e433..89f5fbd281b79 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -1383,6 +1383,9 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { __ get_method(rmethod); // result potentially in r0 or v0 + // Restore cpu control state after JNI call + __ restore_cpu_control_state_after_jni(rscratch1, rscratch2); + // make room for the pushes we're about to do __ sub(rscratch1, esp, 4 * wordSize); __ andr(sp, rscratch1, -16); diff --git a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp index 03aa1cd6cd7ec..14e9764457508 100644 --- a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp @@ -127,6 +127,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); int code_size = upcall_stub_code_base_size + (total_out_args * upcall_stub_size_per_arg); CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 1); + if (buffer.blob() == nullptr) { + return nullptr; + } GrowableArray unfiltered_out_regs; int out_arg_bytes = ForeignGlobals::java_calling_convention(out_sig_bt, total_out_args, unfiltered_out_regs); @@ -324,6 +327,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, &buffer, receiver, in_ByteSize(frame_data_offset)); + if (blob == nullptr) { + return nullptr; + } #ifndef PRODUCT if (lt.is_enabled()) { diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index df28ca284c5cf..f7fe2f7dec81a 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -204,8 +204,13 @@ void VM_Version::initialize() { } } - // Neoverse N1, N2 and V1 - if (_cpu == CPU_ARM && (model_is(0xd0c) || model_is(0xd49) || model_is(0xd40))) { + // Neoverse + // N1: 0xd0c + // N2: 0xd49 + // V1: 0xd40 + // V2: 0xd4f + if (_cpu == CPU_ARM && (model_is(0xd0c) || model_is(0xd49) || + model_is(0xd40) || model_is(0xd4f))) { if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) { FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true); } @@ -234,8 +239,10 @@ void VM_Version::initialize() { FLAG_SET_DEFAULT(UseCRC32, false); } - // Neoverse V1 - if (_cpu == CPU_ARM && model_is(0xd40)) { + // Neoverse + // V1: 0xd40 + // V2: 0xd4f + if (_cpu == CPU_ARM && (model_is(0xd40) || model_is(0xd4f))) { if (FLAG_IS_DEFAULT(UseCryptoPmullForCRC32)) { FLAG_SET_DEFAULT(UseCryptoPmullForCRC32, true); } diff --git a/src/hotspot/cpu/arm/globalDefinitions_arm.hpp b/src/hotspot/cpu/arm/globalDefinitions_arm.hpp index 5832b5451e92c..2041cf9e17ead 100644 --- a/src/hotspot/cpu/arm/globalDefinitions_arm.hpp +++ b/src/hotspot/cpu/arm/globalDefinitions_arm.hpp @@ -49,6 +49,8 @@ const bool HaveVFP = true; // arm32 is not specified as multi-copy-atomic // So we must not #define CPU_MULTI_COPY_ATOMIC +#define DEFAULT_CACHE_LINE_SIZE 64 + #define STUBROUTINES_MD_HPP "stubRoutines_arm.hpp" #define INTERP_MASM_MD_HPP "interp_masm_arm.hpp" #define TEMPLATETABLE_MD_HPP "templateTable_arm.hpp" diff --git a/src/hotspot/cpu/arm/interp_masm_arm.cpp b/src/hotspot/cpu/arm/interp_masm_arm.cpp index 481c3d09e584e..635acd781f9f1 100644 --- a/src/hotspot/cpu/arm/interp_masm_arm.cpp +++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp @@ -303,15 +303,19 @@ void InterpreterMacroAssembler::load_field_entry(Register cache, Register index, } void InterpreterMacroAssembler::load_method_entry(Register cache, Register index, int bcp_offset) { + assert_different_registers(cache, index); + // Get index out of bytecode pointer get_index_at_bcp(index, bcp_offset, cache /* as tmp */, sizeof(u2)); + + // sizeof(ResolvedMethodEntry) is not a power of 2 on Arm, so can't use shift mov(cache, sizeof(ResolvedMethodEntry)); mul(index, index, cache); // Scale the index to be the entry index * sizeof(ResolvedMethodEntry) // load constant pool cache pointer ldr(cache, Address(FP, frame::interpreter_frame_cache_offset * wordSize)); // Get address of method entries array - ldr(cache, Address(cache, ConstantPoolCache::method_entries_offset())); + ldr(cache, Address(cache, in_bytes(ConstantPoolCache::method_entries_offset()))); add(cache, cache, Array::base_offset_in_bytes()); add(cache, cache, index); } diff --git a/src/hotspot/cpu/arm/matcher_arm.hpp b/src/hotspot/cpu/arm/matcher_arm.hpp index 1e8f7683e7615..eb26cbcbd7ada 100644 --- a/src/hotspot/cpu/arm/matcher_arm.hpp +++ b/src/hotspot/cpu/arm/matcher_arm.hpp @@ -186,4 +186,9 @@ } } + // Is SIMD sort supported for this CPU? + static bool supports_simd_sort(BasicType bt) { + return false; + } + #endif // CPU_ARM_MATCHER_ARM_HPP diff --git a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp index ba9a3fd7a9b2a..efaf78ee568c5 100644 --- a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp @@ -370,17 +370,16 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, if (index_size == sizeof(u4)) { __ load_resolved_indy_entry(Rcache, Rindex); __ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedIndyEntry::num_parameters_offset()))); - __ check_stack_top(); - __ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize)); } else { // Pop N words from the stack assert(index_size == sizeof(u2), "Can only be u2"); __ load_method_entry(Rcache, Rindex); - __ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedIndyEntry::num_parameters_offset()))); - __ check_stack_top(); - __ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize)); + __ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedMethodEntry::num_parameters_offset()))); } + __ check_stack_top(); + __ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize)); + __ convert_retval_to_tos(state); __ check_and_handle_popframe(); diff --git a/src/hotspot/cpu/arm/templateTable_arm.cpp b/src/hotspot/cpu/arm/templateTable_arm.cpp index e478f08c977b6..55a0120e7c77c 100644 --- a/src/hotspot/cpu/arm/templateTable_arm.cpp +++ b/src/hotspot/cpu/arm/templateTable_arm.cpp @@ -3666,15 +3666,15 @@ void TemplateTable::prepare_invoke(Register Rcache, Register recv) { // load receiver if needed (after extra argument is pushed so parameter size is correct) if (load_receiver) { __ ldrh(recv, Address(Rcache, in_bytes(ResolvedMethodEntry::num_parameters_offset()))); - Address recv_addr = __ receiver_argument_address(Rstack_top, Rtemp, recv); - __ ldr(recv, recv_addr); + __ add(recv, Rstack_top, AsmOperand(recv, lsl, Interpreter::logStackElementSize)); + __ ldr(recv, Address(recv, -Interpreter::stackElementSize)); __ verify_oop(recv); } // load return address { const address table = (address) Interpreter::invoke_return_entry_table_for(code); - __ mov_slow(Rtemp, table); - __ ldr(LR, Address::indexed_ptr(Rtemp, ret_type)); + __ mov_slow(LR, table); + __ ldr(LR, Address::indexed_ptr(LR, ret_type)); } } @@ -3744,10 +3744,13 @@ void TemplateTable::invokevirtual(int byte_no) { void TemplateTable::invokespecial(int byte_no) { transition(vtos, vtos); assert(byte_no == f1_byte, "use this argument"); + const Register Rrecv = R2_tmp; - load_resolved_method_entry_special_or_static(R2_tmp, // ResolvedMethodEntry* + const Register Rflags = R3_tmp; + + load_resolved_method_entry_special_or_static(Rrecv, // ResolvedMethodEntry* Rmethod, // Method* - R3_tmp); // Flags + Rflags); // Flags prepare_invoke(Rrecv, Rrecv); __ verify_oop(Rrecv); __ null_check(Rrecv, Rtemp); @@ -3760,12 +3763,16 @@ void TemplateTable::invokespecial(int byte_no) { void TemplateTable::invokestatic(int byte_no) { transition(vtos, vtos); assert(byte_no == f1_byte, "use this argument"); - load_resolved_method_entry_special_or_static(R2_tmp, // ResolvedMethodEntry* + + const Register Rrecv = R2_tmp; + const Register Rflags = R3_tmp; + + load_resolved_method_entry_special_or_static(Rrecv, // ResolvedMethodEntry* Rmethod, // Method* - R3_tmp); // Flags - prepare_invoke(R2_tmp, R2_tmp); + Rflags); // Flags + prepare_invoke(Rrecv, Rrecv); // do the call - __ profile_call(R2_tmp); + __ profile_call(Rrecv); __ jump_from_interpreted(Rmethod); } @@ -3788,10 +3795,10 @@ void TemplateTable::invokeinterface(int byte_no) { const Register Rflags = R3_tmp; const Register Rklass = R2_tmp; // Note! Same register with Rrecv - load_resolved_method_entry_interface(R2_tmp, // ResolvedMethodEntry* - R1_tmp, // Klass* + load_resolved_method_entry_interface(Rrecv, // ResolvedMethodEntry* + Rinterf, // Klass* Rmethod, // Method* or itable/vtable index - R3_tmp); // Flags + Rflags); // Flags prepare_invoke(Rrecv, Rrecv); // First check for Object case, then private interface method, diff --git a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp index 738511c6f5099..9913a589683a4 100644 --- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp @@ -2600,6 +2600,13 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { Unimplemented(); } + // There might be a volatile load before this Unsafe CAS. + if (support_IRIW_for_not_multiple_copy_atomic_cpu) { + __ sync(); + } else { + __ lwsync(); + } + if (is_64bit) { __ cmpxchgd(BOOL_RESULT, /*current_value=*/R0, cmp_value, new_value, addr, MacroAssembler::MemBarNone, @@ -2961,9 +2968,24 @@ void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr assert(addr->disp() == 0 && addr->index()->is_illegal(), "use leal!"); const Register Rptr = addr->base()->as_pointer_register(), Rtmp = tmp->as_register(); - Register Rco = noreg; - if (UseCompressedOops && data->is_oop()) { - Rco = __ encode_heap_oop(Rtmp, data->as_register()); + Register Robj = noreg; + if (data->is_oop()) { + if (UseCompressedOops) { + Robj = __ encode_heap_oop(Rtmp, data->as_register()); + } else { + Robj = data->as_register(); + if (Robj == dest->as_register()) { // May happen with ZGC. + __ mr(Rtmp, Robj); + Robj = Rtmp; + } + } + } + + // There might be a volatile load before this Unsafe OP. + if (support_IRIW_for_not_multiple_copy_atomic_cpu) { + __ sync(); + } else { + __ lwsync(); } Label Lretry; @@ -2983,18 +3005,11 @@ void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr } else if (data->is_oop()) { assert(code == lir_xchg, "xadd for oops"); const Register Rold = dest->as_register(); + assert_different_registers(Rptr, Rold, Robj); if (UseCompressedOops) { - assert_different_registers(Rptr, Rold, Rco); __ lwarx(Rold, Rptr, MacroAssembler::cmpxchgx_hint_atomic_update()); - __ stwcx_(Rco, Rptr); + __ stwcx_(Robj, Rptr); } else { - Register Robj = data->as_register(); - assert_different_registers(Rptr, Rold, Rtmp); - assert_different_registers(Rptr, Robj, Rtmp); - if (Robj == Rold) { // May happen with ZGC. - __ mr(Rtmp, Robj); - Robj = Rtmp; - } __ ldarx(Rold, Rptr, MacroAssembler::cmpxchgx_hint_atomic_update()); __ stdcx_(Robj, Rptr); } @@ -3022,6 +3037,12 @@ void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr if (UseCompressedOops && data->is_oop()) { __ decode_heap_oop(dest->as_register()); } + + if (support_IRIW_for_not_multiple_copy_atomic_cpu) { + __ isync(); + } else { + __ sync(); + } } diff --git a/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp index ecc40d6fde7c1..32aab91c7d374 100644 --- a/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp @@ -639,13 +639,6 @@ LIR_Opr LIRGenerator::atomic_cmpxchg(BasicType type, LIR_Opr addr, LIRItem& cmp_ cmp_value.load_item(); new_value.load_item(); - // Volatile load may be followed by Unsafe CAS. - if (support_IRIW_for_not_multiple_copy_atomic_cpu) { - __ membar(); - } else { - __ membar_release(); - } - if (is_reference_type(type)) { if (UseCompressedOops) { t1 = new_register(T_OBJECT); @@ -670,21 +663,7 @@ LIR_Opr LIRGenerator::atomic_xchg(BasicType type, LIR_Opr addr, LIRItem& value) LIR_Opr tmp = FrameMap::R0_opr; value.load_item(); - - // Volatile load may be followed by Unsafe CAS. - if (support_IRIW_for_not_multiple_copy_atomic_cpu) { - __ membar(); - } else { - __ membar_release(); - } - __ xchg(addr, value.result(), result, tmp); - - if (support_IRIW_for_not_multiple_copy_atomic_cpu) { - __ membar_acquire(); - } else { - __ membar(); - } return result; } @@ -694,21 +673,7 @@ LIR_Opr LIRGenerator::atomic_add(BasicType type, LIR_Opr addr, LIRItem& value) { LIR_Opr tmp = FrameMap::R0_opr; value.load_item(); - - // Volatile load may be followed by Unsafe CAS. - if (support_IRIW_for_not_multiple_copy_atomic_cpu) { - __ membar(); // To be safe. Unsafe semantics are unclear. - } else { - __ membar_release(); - } - __ xadd(addr, value.result(), result, tmp); - - if (support_IRIW_for_not_multiple_copy_atomic_cpu) { - __ membar_acquire(); - } else { - __ membar(); - } return result; } diff --git a/src/hotspot/cpu/ppc/compressedKlass_ppc.cpp b/src/hotspot/cpu/ppc/compressedKlass_ppc.cpp new file mode 100644 index 0000000000000..51012eef86594 --- /dev/null +++ b/src/hotspot/cpu/ppc/compressedKlass_ppc.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023, Red Hat, Inc. All rights reserved. + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "oops/compressedKlass.hpp" +#include "utilities/globalDefinitions.hpp" + +char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size_t size, bool aslr, bool optimize_for_zero_base) { + + char* result = nullptr; + + // Optimize for base=0 shift=0; failing that, for base=0 shift>0 + if (optimize_for_zero_base) { + result = reserve_address_space_for_unscaled_encoding(size, aslr); + if (result == nullptr) { + result = reserve_address_space_for_zerobased_encoding(size, aslr); + } + } + + // Optimize for a single 16-bit move: a base that has only bits set in its third quadrant [32..48). + if (result == nullptr) { + result = reserve_address_space_for_16bit_move(size, aslr); + } + + return result; +} diff --git a/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp b/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp index 5fb9509926f9c..7175f727437af 100644 --- a/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp +++ b/src/hotspot/cpu/ppc/downcallLinker_ppc.cpp @@ -51,6 +51,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg); int locs_size = 1; // must be non-zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); + if (code.blob() == nullptr) { + return nullptr; + } StubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer, captured_state_mask, @@ -58,12 +61,19 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, g.generate(); code.log_section_sizes("nep_invoker_blob"); + bool caller_must_gc_arguments = false; + bool alloc_fail_is_fatal = false; RuntimeStub* stub = RuntimeStub::new_runtime_stub("nep_invoker_blob", &code, g.frame_complete(), g.framesize(), - g.oop_maps(), false); + g.oop_maps(), + caller_must_gc_arguments, + alloc_fail_is_fatal); + if (stub == nullptr) { + return nullptr; + } #ifndef PRODUCT LogTarget(Trace, foreign, downcall) lt; diff --git a/src/hotspot/cpu/ppc/gc/shenandoah/c1/shenandoahBarrierSetC1_ppc.cpp b/src/hotspot/cpu/ppc/gc/shenandoah/c1/shenandoahBarrierSetC1_ppc.cpp index fc06e1b71e0b8..6d9a1db1ed4b8 100644 --- a/src/hotspot/cpu/ppc/gc/shenandoah/c1/shenandoahBarrierSetC1_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shenandoah/c1/shenandoahBarrierSetC1_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2018, 2021, Red Hat, Inc. All rights reserved. - * Copyright (c) 2012, 2021 SAP SE. All rights reserved. + * Copyright (c) 2018, 2023, Red Hat, Inc. All rights reserved. + * Copyright (c) 2012, 2023 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,8 +53,13 @@ void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler *masm) { __ encode_heap_oop(new_val, new_val); } - // Due to the memory barriers emitted in ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved, - // there is no need to specify stronger memory semantics. + // There might be a volatile load before this Unsafe CAS. + if (support_IRIW_for_not_multiple_copy_atomic_cpu) { + __ sync(); + } else { + __ lwsync(); + } + ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), addr, cmp_val, new_val, tmp1, tmp2, false, result); @@ -63,6 +68,12 @@ void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler *masm) { __ decode_heap_oop(new_val); } + if (support_IRIW_for_not_multiple_copy_atomic_cpu) { + __ isync(); + } else { + __ sync(); + } + __ block_comment("} LIR_OpShenandoahCompareAndSwap (shenandaohgc)"); } @@ -80,14 +91,6 @@ LIR_Opr ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess &access, LI if (access.is_oop()) { LIRGenerator* gen = access.gen(); - if (ShenandoahCASBarrier) { - if (support_IRIW_for_not_multiple_copy_atomic_cpu) { - __ membar(); - } else { - __ membar_release(); - } - } - if (ShenandoahSATBBarrier) { pre_barrier(gen, access.access_emit_info(), access.decorators(), access.resolved_addr(), LIR_OprFact::illegalOpr); @@ -104,12 +107,6 @@ LIR_Opr ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess &access, LI __ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), t1, t2, result)); - if (support_IRIW_for_not_multiple_copy_atomic_cpu) { - __ membar_acquire(); - } else { - __ membar(); - } - return result; } } @@ -125,12 +122,6 @@ LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess &access, LIRIt value.load_item(); LIR_Opr value_opr = value.result(); - if (support_IRIW_for_not_multiple_copy_atomic_cpu) { - __ membar(); - } else { - __ membar_release(); - } - if (access.is_oop()) { value_opr = iu_barrier(access.gen(), value_opr, access.access_emit_info(), access.decorators()); } @@ -152,11 +143,5 @@ LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess &access, LIRIt } } - if (support_IRIW_for_not_multiple_copy_atomic_cpu) { - __ membar_acquire(); - } else { - __ membar(); - } - return result; } diff --git a/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp index 1d07c6d573a17..9ed47b688ff26 100644 --- a/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/z/zBarrierSetAssembler_ppc.cpp @@ -340,11 +340,12 @@ void ZBarrierSetAssembler::store_barrier_medium(MacroAssembler* masm, } __ ld(R0, in_bytes(ZThreadLocalData::store_good_mask_offset()), R16_thread); __ cmpxchgd(CCR0, tmp, (intptr_t)0, R0, ref_base, - MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update()); + MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(), + noreg, need_restore ? nullptr : &slow_path); if (need_restore) { __ subf(ref_base, ind_or_offs, ref_base); + __ bne(CCR0, slow_path); } - __ bne(CCR0, slow_path); } else { // A non-atomic relocatable object won't get to the medium fast path due to a // raw null in the young generation. We only get here because the field is bad. diff --git a/src/hotspot/cpu/ppc/matcher_ppc.hpp b/src/hotspot/cpu/ppc/matcher_ppc.hpp index 44d1a3cd30511..b195ba4eeb202 100644 --- a/src/hotspot/cpu/ppc/matcher_ppc.hpp +++ b/src/hotspot/cpu/ppc/matcher_ppc.hpp @@ -195,4 +195,9 @@ } } + // Is SIMD sort supported for this CPU? + static bool supports_simd_sort(BasicType bt) { + return false; + } + #endif // CPU_PPC_MATCHER_PPC_HPP diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index fb857182265d6..be37ff1785b64 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -12727,16 +12727,8 @@ instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst re ins_cost(300); format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %} ins_encode %{ - Label Lskip, Ldone; - __ li($result$$Register, 0); - __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, - $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Ldone); - __ rldicl_($tmp1$$Register, $len$$Register, 0, 64-3); // Remaining characters. - __ beq(CCR0, Lskip); - __ string_compress($src$$Register, $dst$$Register, $tmp1$$Register, $tmp2$$Register, Ldone); - __ bind(Lskip); - __ mr($result$$Register, $len$$Register); - __ bind(Ldone); + __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register, $tmp2$$Register, + $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, $result$$Register, false); %} ins_pipe(pipe_class_default); %} diff --git a/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp b/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp index 727ebe2b568e1..a1c8f46ce2d57 100644 --- a/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp +++ b/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp @@ -128,6 +128,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); int code_size = upcall_stub_code_base_size + (total_out_args * upcall_stub_size_per_arg); CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 1); + if (buffer.blob() == nullptr) { + return nullptr; + } Register callerSP = R2, // C/C++ uses R2 as TOC, but we can reuse it here tmp = R11_scratch1, // same as shuffle_reg @@ -332,6 +335,10 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, &buffer, receiver, in_ByteSize(frame_data_offset)); + if (blob == nullptr) { + return nullptr; + } + #ifndef ABI_ELFv2 // Need to patch the FunctionDescriptor after relocating. address fd_addr = blob->code_begin(); diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index 553db1256baec..c1b13d1b16a40 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -1418,6 +1418,7 @@ enum VectorMask { INSN(vmfeq_vv, 0b1010111, 0b001, 0b011000); // Vector Floating-Point Sign-Injection Instructions + INSN(vfsgnj_vv, 0b1010111, 0b001, 0b001000); INSN(vfsgnjx_vv, 0b1010111, 0b001, 0b001010); INSN(vfsgnjn_vv, 0b1010111, 0b001, 0b001001); diff --git a/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp b/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp index 530b99dd06b7f..1a24f78ad12a6 100644 --- a/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_CodeStubs_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ void C1SafepointPollStub::emit_code(LIR_Assembler* ce) { InternalAddress safepoint_pc(__ pc() - __ offset() + safepoint_offset()); __ relocate(safepoint_pc.rspec(), [&] { int32_t offset; - __ la_patchable(t0, safepoint_pc.target(), offset); + __ la(t0, safepoint_pc.target(), offset); __ addi(t0, t0, offset); }); __ sd(t0, Address(xthread, JavaThread::saved_exception_pc_offset())); @@ -92,12 +92,9 @@ void RangeCheckStub::emit_code(LIR_Assembler* ce) { __ mv(t1, _array->as_pointer_register()); stub_id = Runtime1::throw_range_check_failed_id; } - RuntimeAddress target(Runtime1::entry_for(stub_id)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(ra, target, offset); - __ jalr(ra, ra, offset); - }); + // t0 and t1 are used as args in generate_exception_throw, + // so use ra as the tmp register for rt_call. + __ rt_call(Runtime1::entry_for(stub_id), ra); ce->add_call_info_here(_info); ce->verify_oop_map(_info); debug_only(__ should_not_reach_here()); diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp index afdf25c58d234..0bbf3771a04bc 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp @@ -1425,7 +1425,7 @@ void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmit InternalAddress pc_for_athrow(__ pc()); __ relocate(pc_for_athrow.rspec(), [&] { int32_t offset; - __ la_patchable(exceptionPC->as_register(), pc_for_athrow, offset); + __ la(exceptionPC->as_register(), pc_for_athrow.target(), offset); __ addi(exceptionPC->as_register(), exceptionPC->as_register(), offset); }); add_call_info(pc_for_athrow_offset, info); // for exception handler @@ -1868,7 +1868,7 @@ void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* arg RuntimeAddress target(dest); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ movptr(t0, target.target(), offset); __ jalr(x1, t0, offset); }); } diff --git a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp index ea086d46bdac2..b76163a30841d 100644 --- a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,12 +67,7 @@ int StubAssembler::call_RT(Register oop_result, Register metadata_result, addres set_last_Java_frame(sp, fp, retaddr, t0); // do the call - RuntimeAddress target(entry); - relocate(target.rspec(), [&] { - int32_t offset; - la_patchable(t0, target, offset); - jalr(x1, t0, offset); - }); + rt_call(entry); bind(retaddr); int call_offset = offset(); // verify callee-saved register @@ -578,12 +573,7 @@ OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { Label retaddr; __ set_last_Java_frame(sp, fp, retaddr, t0); // do the call - RuntimeAddress addr(target); - __ relocate(addr.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, addr, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(target); __ bind(retaddr); OopMapSet* oop_maps = new OopMapSet(); assert_cond(oop_maps != nullptr); diff --git a/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp b/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp index d1c66ce1da76a..7995750aba96b 100644 --- a/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_CodeStubs_riscv.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ void C2SafepointPollStub::emit(C2_MacroAssembler& masm) { InternalAddress safepoint_pc(__ pc() - __ offset() + _safepoint_offset); __ relocate(safepoint_pc.rspec(), [&] { int32_t offset; - __ la_patchable(t0, safepoint_pc.target(), offset); + __ la(t0, safepoint_pc.target(), offset); __ addi(t0, t0, offset); }); __ sd(t0, Address(xthread, JavaThread::saved_exception_pc_offset())); @@ -60,12 +60,7 @@ int C2EntryBarrierStub::max_size() const { void C2EntryBarrierStub::emit(C2_MacroAssembler& masm) { __ bind(entry()); - RuntimeAddress target(StubRoutines::method_entry_barrier()); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(ra, t0, offset); - }); + __ rt_call(StubRoutines::method_entry_barrier()); __ j(continuation()); diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 5daeff511922c..711eb2100912b 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -1459,6 +1459,112 @@ void C2_MacroAssembler::string_equals(Register a1, Register a2, BLOCK_COMMENT("} string_equals"); } +// jdk.internal.util.ArraysSupport.vectorizedHashCode +void C2_MacroAssembler::arrays_hashcode(Register ary, Register cnt, Register result, + Register tmp1, Register tmp2, Register tmp3, + Register tmp4, Register tmp5, Register tmp6, + BasicType eltype) +{ + assert_different_registers(ary, cnt, result, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, t0, t1); + + const int elsize = arrays_hashcode_elsize(eltype); + const int chunks_end_shift = exact_log2(elsize); + + switch (eltype) { + case T_BOOLEAN: BLOCK_COMMENT("arrays_hashcode(unsigned byte) {"); break; + case T_CHAR: BLOCK_COMMENT("arrays_hashcode(char) {"); break; + case T_BYTE: BLOCK_COMMENT("arrays_hashcode(byte) {"); break; + case T_SHORT: BLOCK_COMMENT("arrays_hashcode(short) {"); break; + case T_INT: BLOCK_COMMENT("arrays_hashcode(int) {"); break; + default: + ShouldNotReachHere(); + } + + const int stride = 4; + const Register pow31_4 = tmp1; + const Register pow31_3 = tmp2; + const Register pow31_2 = tmp3; + const Register chunks = tmp4; + const Register chunks_end = chunks; + + Label DONE, TAIL, TAIL_LOOP, WIDE_LOOP; + + // result has a value initially + + beqz(cnt, DONE); + + andi(chunks, cnt, ~(stride-1)); + beqz(chunks, TAIL); + + mv(pow31_4, 923521); // [31^^4] + mv(pow31_3, 29791); // [31^^3] + mv(pow31_2, 961); // [31^^2] + + slli(chunks_end, chunks, chunks_end_shift); + add(chunks_end, ary, chunks_end); + andi(cnt, cnt, stride-1); // don't forget about tail! + + bind(WIDE_LOOP); + mulw(result, result, pow31_4); // 31^^4 * h + arrays_hashcode_elload(t0, Address(ary, 0 * elsize), eltype); + arrays_hashcode_elload(t1, Address(ary, 1 * elsize), eltype); + arrays_hashcode_elload(tmp5, Address(ary, 2 * elsize), eltype); + arrays_hashcode_elload(tmp6, Address(ary, 3 * elsize), eltype); + mulw(t0, t0, pow31_3); // 31^^3 * ary[i+0] + addw(result, result, t0); + mulw(t1, t1, pow31_2); // 31^^2 * ary[i+1] + addw(result, result, t1); + slli(t0, tmp5, 5); // optimize 31^^1 * ary[i+2] + subw(tmp5, t0, tmp5); // with ary[i+2]<<5 - ary[i+2] + addw(result, result, tmp5); + addw(result, result, tmp6); // 31^^4 * h + 31^^3 * ary[i+0] + 31^^2 * ary[i+1] + // + 31^^1 * ary[i+2] + 31^^0 * ary[i+3] + addi(ary, ary, elsize * stride); + bne(ary, chunks_end, WIDE_LOOP); + beqz(cnt, DONE); + + bind(TAIL); + slli(chunks_end, cnt, chunks_end_shift); + add(chunks_end, ary, chunks_end); + + bind(TAIL_LOOP); + arrays_hashcode_elload(t0, Address(ary), eltype); + slli(t1, result, 5); // optimize 31 * result + subw(result, t1, result); // with result<<5 - result + addw(result, result, t0); + addi(ary, ary, elsize); + bne(ary, chunks_end, TAIL_LOOP); + + bind(DONE); + BLOCK_COMMENT("} // arrays_hashcode"); +} + +int C2_MacroAssembler::arrays_hashcode_elsize(BasicType eltype) { + switch (eltype) { + case T_BOOLEAN: return sizeof(jboolean); + case T_BYTE: return sizeof(jbyte); + case T_SHORT: return sizeof(jshort); + case T_CHAR: return sizeof(jchar); + case T_INT: return sizeof(jint); + default: + ShouldNotReachHere(); + return -1; + } +} + +void C2_MacroAssembler::arrays_hashcode_elload(Register dst, Address src, BasicType eltype) { + switch (eltype) { + // T_BOOLEAN used as surrogate for unsigned byte + case T_BOOLEAN: lbu(dst, src); break; + case T_BYTE: lb(dst, src); break; + case T_SHORT: lh(dst, src); break; + case T_CHAR: lhu(dst, src); break; + case T_INT: lw(dst, src); break; + default: + ShouldNotReachHere(); + } +} + typedef void (Assembler::*conditional_branch_insn)(Register op1, Register op2, Label& label, bool is_far); typedef void (MacroAssembler::*float_conditional_branch_insn)(FloatRegister op1, FloatRegister op2, Label& label, bool is_far, bool is_unordered); @@ -1677,6 +1783,19 @@ void C2_MacroAssembler::signum_fp(FloatRegister dst, FloatRegister one, bool is_ bind(done); } +void C2_MacroAssembler::signum_fp_v(VectorRegister dst, VectorRegister one, BasicType bt, int vlen) { + vsetvli_helper(bt, vlen); + + // check if input is -0, +0, signaling NaN or quiet NaN + vfclass_v(v0, dst); + mv(t0, fclass_mask::zero | fclass_mask::nan); + vand_vx(v0, v0, t0); + vmseq_vi(v0, v0, 0); + + // use floating-point 1.0 with a sign of input + vfsgnj_vv(dst, one, dst, v0_t); +} + void C2_MacroAssembler::compress_bits_v(Register dst, Register src, Register mask, bool is_long) { Assembler::SEW sew = is_long ? Assembler::e64 : Assembler::e32; // intrinsic is enabled when MaxVectorSize >= 16 @@ -1933,14 +2052,12 @@ void C2_MacroAssembler::byte_array_inflate_v(Register src, Register dst, Registe } // Compress char[] array to byte[]. -// result: the array length if every element in array can be encoded; 0, otherwise. +// Intrinsic for java.lang.StringUTF16.compress(char[] src, int srcOff, byte[] dst, int dstOff, int len) +// result: the array length if every element in array can be encoded, +// otherwise, the index of first non-latin1 (> 0xff) character. void C2_MacroAssembler::char_array_compress_v(Register src, Register dst, Register len, Register result, Register tmp) { - Label done; encode_iso_array_v(src, dst, len, result, tmp, false); - beqz(len, done); - mv(result, zr); - bind(done); } // Intrinsic for @@ -1948,7 +2065,7 @@ void C2_MacroAssembler::char_array_compress_v(Register src, Register dst, Regist // - sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray // return the number of characters copied. // - java/lang/StringUTF16.compress -// return zero (0) if copy fails, otherwise 'len'. +// return index of non-latin1 character if copy fails, otherwise 'len'. // // This version always returns the number of characters copied. A successful // copy will complete with the post-condition: 'res' == 'len', while an diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp index f36615809c0ee..4940ce5fe9e94 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp @@ -82,6 +82,15 @@ Register result, Register cnt1, int elem_size); + void arrays_hashcode(Register ary, Register cnt, Register result, + Register tmp1, Register tmp2, + Register tmp3, Register tmp4, + Register tmp5, Register tmp6, + BasicType eltype); + // helper function for arrays_hashcode + int arrays_hashcode_elsize(BasicType eltype); + void arrays_hashcode_elload(Register dst, Address src, BasicType eltype); + void string_equals(Register r1, Register r2, Register result, Register cnt1, int elem_size); @@ -163,6 +172,8 @@ void signum_fp(FloatRegister dst, FloatRegister one, bool is_double); + void signum_fp_v(VectorRegister dst, VectorRegister one, BasicType bt, int vlen); + // intrinsic methods implemented by rvv instructions // compress bits, i.e. j.l.Integer/Long::compress. diff --git a/src/hotspot/cpu/riscv/compressedKlass_riscv.cpp b/src/hotspot/cpu/riscv/compressedKlass_riscv.cpp new file mode 100644 index 0000000000000..cffadb4189b1c --- /dev/null +++ b/src/hotspot/cpu/riscv/compressedKlass_riscv.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023, Red Hat, Inc. All rights reserved. + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "oops/compressedKlass.hpp" +#include "utilities/globalDefinitions.hpp" + +char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size_t size, bool aslr, bool optimize_for_zero_base) { + + char* result = nullptr; + + // RiscV loads a 64-bit immediate in up to four separate steps, splitting it into four different sections + // (two 32-bit sections, each split into two subsections of 20/12 bits). + // + // 63 ....... 44 43 ... 32 31 ....... 12 11 ... 0 + // D C B A + // + // A "good" base is, in this order: + // 1) only bits in A; this would be an address < 4KB, which is unrealistic on normal Linux boxes since + // the typical default for vm.mmap_min_address is 64KB. We ignore that. + // 2) only bits in B: a 12-bit-aligned address below 4GB. 12 bit = 4KB, but since mmap reserves at + // page boundaries, we can ignore the alignment. + // 3) only bits in C: a 4GB-aligned address that is lower than 16TB. + // 4) only bits in D: a 16TB-aligned address. + + // First, attempt to allocate < 4GB. We do this unconditionally: + // - if can_optimize_for_zero_base, a <4GB mapping start would allow us to run unscaled (base = 0, shift = 0) + // - if !can_optimize_for_zero_base, a <4GB mapping start is still good, the resulting immediate can be encoded + // with one instruction (2) + result = reserve_address_space_for_unscaled_encoding(size, aslr); + + // Failing that, attempt to reserve for base=zero shift>0 + if (result == nullptr && optimize_for_zero_base) { + result = reserve_address_space_for_zerobased_encoding(size, aslr); + } + + // Failing that, optimize for case (3) - a base with only bits set between [33-44) + if (result == nullptr) { + const uintptr_t from = nth_bit(32 + (optimize_for_zero_base ? LogKlassAlignmentInBytes : 0)); + constexpr uintptr_t to = nth_bit(44); + constexpr size_t alignment = nth_bit(32); + result = reserve_address_space_X(from, to, size, alignment, aslr); + } + + // Failing that, optimize for case (4) - a base with only bits set between [44-64) + if (result == nullptr) { + constexpr uintptr_t from = nth_bit(44); + constexpr uintptr_t to = UINT64_MAX; + constexpr size_t alignment = nth_bit(44); + result = reserve_address_space_X(from, to, size, alignment, aslr); + } + + return result; +} diff --git a/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp b/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp index fefb40f4b1e1c..9c4ea56d0c8ba 100644 --- a/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp +++ b/src/hotspot/cpu/riscv/downcallLinker_riscv.cpp @@ -52,6 +52,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg); int locs_size = 1; // must be non-zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); + if (code.blob() == nullptr) { + return nullptr; + } StubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer, captured_state_mask, @@ -59,12 +62,19 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, g.generate(); code.log_section_sizes("nep_invoker_blob"); + bool caller_must_gc_arguments = false; + bool alloc_fail_is_fatal = false; RuntimeStub* stub = RuntimeStub::new_runtime_stub("nep_invoker_blob", &code, g.frame_complete(), g.framesize(), - g.oop_maps(), false); + g.oop_maps(), + caller_must_gc_arguments, + alloc_fail_is_fatal); + if (stub == nullptr) { + return nullptr; + } #ifndef PRODUCT LogTarget(Trace, foreign, downcall) lt; diff --git a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp index 27130dbc3d968..5d0b0fb472934 100644 --- a/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/g1/g1BarrierSetAssembler_riscv.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -187,7 +187,6 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, BarrierSet* bs = BarrierSet::barrier_set(); CardTableBarrierSet* ctbs = barrier_set_cast(bs); - CardTable* ct = ctbs->card_table(); Label done; Label runtime; @@ -204,7 +203,6 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, // storing region crossing non-null, is card already dirty? - ExternalAddress cardtable((address) ct->byte_map_base()); const Register card_addr = tmp1; __ srli(card_addr, store_addr, CardTable::card_shift()); @@ -410,7 +408,6 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler* BarrierSet* bs = BarrierSet::barrier_set(); CardTableBarrierSet* ctbs = barrier_set_cast(bs); - CardTable* ct = ctbs->card_table(); Label done; Label runtime; diff --git a/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp index a4440890b0961..1ac1fc18f1ee0 100644 --- a/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp @@ -308,12 +308,7 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Label* slo Label skip_barrier; __ beq(t0, t1, skip_barrier); - RuntimeAddress target(StubRoutines::method_entry_barrier()); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(ra, t0, offset); - }); + __ rt_call(StubRoutines::method_entry_barrier()); __ j(skip_barrier); diff --git a/src/hotspot/cpu/riscv/gc/x/xBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/x/xBarrierSetAssembler_riscv.cpp index c48eac944c129..7306492970b81 100644 --- a/src/hotspot/cpu/riscv/gc/x/xBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/x/xBarrierSetAssembler_riscv.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -339,12 +339,8 @@ void XBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, X XSaveLiveRegisters save_live_registers(masm, stub); XSetupArguments setup_arguments(masm, stub); - Address target(stub->slow_path()); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ mv(t0, stub->slow_path()); + __ jalr(t0); } // Stub exit diff --git a/src/hotspot/cpu/riscv/icBuffer_riscv.cpp b/src/hotspot/cpu/riscv/icBuffer_riscv.cpp index 997611df4a3ab..ab904817816fc 100644 --- a/src/hotspot/cpu/riscv/icBuffer_riscv.cpp +++ b/src/hotspot/cpu/riscv/icBuffer_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,8 +36,7 @@ int InlineCacheBuffer::ic_stub_code_size() { // 6: auipc + ld + auipc + jalr + address(2 * instruction_size) - // 5: auipc + ld + j + address(2 * instruction_size) - return (MacroAssembler::far_branches() ? 6 : 5) * NativeInstruction::instruction_size; + return 6 * NativeInstruction::instruction_size; } #define __ masm-> diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index f9a23af41b09b..030a6f0fe96dd 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -194,7 +194,7 @@ void InterpreterMacroAssembler::get_dispatch() { ExternalAddress target((address)Interpreter::dispatch_table()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(xdispatch, target, offset); + la(xdispatch, target.target(), offset); addi(xdispatch, xdispatch, offset); }); } diff --git a/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp b/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp index 87890d359ee91..fd1701c8188b8 100644 --- a/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp +++ b/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { Address target(SafepointSynchronize::safepoint_counter_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(rcounter_addr, target, offset); + __ la(rcounter_addr, target.target(), offset); __ addi(rcounter_addr, rcounter_addr, offset); }); @@ -96,7 +96,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { ExternalAddress target((address) JvmtiExport::get_field_access_count_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(result, target, offset); + __ la(result, target.target(), offset); __ lwu(result, Address(result, offset)); }); __ bnez(result, slow); @@ -176,7 +176,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { ExternalAddress target(slow_case_addr); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ la(t0, target.target(), offset); __ jalr(x1, t0, offset); }); __ leave(); diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 82a4df29326cb..3acc010ff85a3 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -340,7 +340,7 @@ void MacroAssembler::call_VM_base(Register oop_result, RuntimeAddress target(StubRoutines::forward_exception_entry()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(t0, target, offset); + la(t0, target.target(), offset); jalr(x0, t0, offset); }); bind(ok); @@ -421,7 +421,7 @@ void MacroAssembler::_verify_oop(Register reg, const char* s, const char* file, ExternalAddress target(StubRoutines::verify_oop_subroutine_entry_address()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(t1, target, offset); + la(t1, target.target(), offset); ld(t1, Address(t1, offset)); }); jalr(t1); @@ -466,7 +466,7 @@ void MacroAssembler::_verify_oop_addr(Address addr, const char* s, const char* f ExternalAddress target(StubRoutines::verify_oop_subroutine_entry_address()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(t1, target, offset); + la(t1, target.target(), offset); ld(t1, Address(t1, offset)); }); jalr(t1); @@ -717,13 +717,35 @@ void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Reg MacroAssembler::call_VM_leaf_base(entry_point, 4); } -void MacroAssembler::la(Register Rd, const address dest) { - int64_t offset = dest - pc(); +void MacroAssembler::la(Register Rd, const address addr) { + int64_t offset = addr - pc(); if (is_simm32(offset)) { auipc(Rd, (int32_t)offset + 0x800); //0x800, Note:the 11th sign bit addi(Rd, Rd, ((int64_t)offset << 52) >> 52); } else { - movptr(Rd, dest); + movptr(Rd, addr); + } +} + +void MacroAssembler::la(Register Rd, const address addr, int32_t &offset) { + assert((uintptr_t)addr < (1ull << 48), "bad address"); + + unsigned long target_address = (uintptr_t)addr; + unsigned long low_address = (uintptr_t)CodeCache::low_bound(); + unsigned long high_address = (uintptr_t)CodeCache::high_bound(); + long offset_low = target_address - low_address; + long offset_high = target_address - high_address; + + // RISC-V doesn't compute a page-aligned address, in order to partially + // compensate for the use of *signed* offsets in its base+disp12 + // addressing mode (RISC-V's PC-relative reach remains asymmetric + // [-(2G + 2K), 2G - 2K). + if (offset_high >= -((1L << 31) + (1L << 11)) && offset_low < (1L << 31) - (1L << 11)) { + int64_t distance = addr - pc(); + auipc(Rd, (int32_t)distance + 0x800); + offset = ((int32_t)distance << 20) >> 20; + } else { + movptr(Rd, addr, offset); } } @@ -1564,7 +1586,7 @@ void MacroAssembler::reinit_heapbase() { ExternalAddress target(CompressedOops::ptrs_base_addr()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(xheapbase, target, offset); + la(xheapbase, target.target(), offset); ld(xheapbase, Address(xheapbase, offset)); }); } @@ -2119,7 +2141,7 @@ SkipIfEqual::SkipIfEqual(MacroAssembler* masm, const bool* flag_addr, bool value ExternalAddress target((address)flag_addr); _masm->relocate(target.rspec(), [&] { int32_t offset; - _masm->la_patchable(t0, target, offset); + _masm->la(t0, target.target(), offset); _masm->lbu(t0, Address(t0, offset)); }); if (value) { @@ -2996,46 +3018,36 @@ ATOMIC_XCHGU(xchgalwu, xchgalw) #undef ATOMIC_XCHGU -void MacroAssembler::far_jump(Address entry, Register tmp) { +void MacroAssembler::far_jump(const Address &entry, Register tmp) { assert(ReservedCodeCacheSize < 4*G, "branch out of range"); assert(CodeCache::find_blob(entry.target()) != nullptr, "destination of far call not found in code cache"); assert(entry.rspec().type() == relocInfo::external_word_type || entry.rspec().type() == relocInfo::runtime_call_type || entry.rspec().type() == relocInfo::none, "wrong entry relocInfo type"); - IncompressibleRegion ir(this); // Fixed length: see MacroAssembler::far_branch_size() - if (far_branches()) { - // We can use auipc + jalr here because we know that the total size of - // the code cache cannot exceed 2Gb. - relocate(entry.rspec(), [&] { - int32_t offset; - la_patchable(tmp, entry, offset); - jalr(x0, tmp, offset); - }); - } else { - j(entry); - } + // Fixed length: see MacroAssembler::far_branch_size() + relocate(entry.rspec(), [&] { + int32_t offset; + la(tmp, entry.target(), offset); + jalr(x0, tmp, offset); + }); } -void MacroAssembler::far_call(Address entry, Register tmp) { +void MacroAssembler::far_call(const Address &entry, Register tmp) { assert(ReservedCodeCacheSize < 4*G, "branch out of range"); assert(CodeCache::find_blob(entry.target()) != nullptr, "destination of far call not found in code cache"); assert(entry.rspec().type() == relocInfo::external_word_type || entry.rspec().type() == relocInfo::runtime_call_type || entry.rspec().type() == relocInfo::none, "wrong entry relocInfo type"); - IncompressibleRegion ir(this); // Fixed length: see MacroAssembler::far_branch_size() - if (far_branches()) { - // We can use auipc + jalr here because we know that the total size of - // the code cache cannot exceed 2Gb. - relocate(entry.rspec(), [&] { - int32_t offset; - la_patchable(tmp, entry, offset); - jalr(x1, tmp, offset); // link - }); - } else { - jal(entry); // link - } + // Fixed length: see MacroAssembler::far_branch_size() + // We can use auipc + jalr here because we know that the total size of + // the code cache cannot exceed 2Gb. + relocate(entry.rspec(), [&] { + int32_t offset; + la(tmp, entry.target(), offset); + jalr(x1, tmp, offset); // link + }); } void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass, @@ -3258,29 +3270,6 @@ void MacroAssembler::load_byte_map_base(Register reg) { mv(reg, (uint64_t)byte_map_base); } -void MacroAssembler::la_patchable(Register reg1, const Address &dest, int32_t &offset) { - unsigned long low_address = (uintptr_t)CodeCache::low_bound(); - unsigned long high_address = (uintptr_t)CodeCache::high_bound(); - unsigned long dest_address = (uintptr_t)dest.target(); - long offset_low = dest_address - low_address; - long offset_high = dest_address - high_address; - - assert(dest.getMode() == Address::literal, "la_patchable must be applied to a literal address"); - assert((uintptr_t)dest.target() < (1ull << 48), "bad address"); - - // RISC-V doesn't compute a page-aligned address, in order to partially - // compensate for the use of *signed* offsets in its base+disp12 - // addressing mode (RISC-V's PC-relative reach remains asymmetric - // [-(2G + 2K), 2G - 2K). - if (offset_high >= -((1L << 31) + (1L << 11)) && offset_low < (1L << 31) - (1L << 11)) { - int64_t distance = dest.target() - pc(); - auipc(reg1, (int32_t)distance + 0x800); - offset = ((int32_t)distance << 20) >> 20; - } else { - movptr(reg1, dest.target(), offset); - } -} - void MacroAssembler::build_frame(int framesize) { assert(framesize >= 2, "framesize must include space for FP/RA"); assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment"); @@ -3307,21 +3296,16 @@ void MacroAssembler::reserved_stack_check() { enter(); // RA and FP are live. mv(c_rarg0, xthread); - RuntimeAddress target(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone)); - relocate(target.rspec(), [&] { - int32_t offset; - la_patchable(t0, target, offset); - jalr(x1, t0, offset); - }); + rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone)); leave(); // We have already removed our own frame. // throw_delayed_StackOverflowError will think that it's been // called by our caller. - target = RuntimeAddress(StubRoutines::throw_delayed_StackOverflowError_entry()); + RuntimeAddress target(StubRoutines::throw_delayed_StackOverflowError_entry()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(t0, target, offset); + movptr(t0, target.target(), offset); jalr(x0, t0, offset); }); should_not_reach_here(); @@ -3383,21 +3367,19 @@ address MacroAssembler::trampoline_call(Address entry) { address target = entry.target(); // We need a trampoline if branches are far. - if (far_branches()) { - if (!in_scratch_emit_size()) { - if (entry.rspec().type() == relocInfo::runtime_call_type) { - assert(CodeBuffer::supports_shared_stubs(), "must support shared stubs"); - code()->share_trampoline_for(entry.target(), offset()); - } else { - address stub = emit_trampoline_stub(offset(), target); - if (stub == nullptr) { - postcond(pc() == badAddress); - return nullptr; // CodeCache is full - } + if (!in_scratch_emit_size()) { + if (entry.rspec().type() == relocInfo::runtime_call_type) { + assert(CodeBuffer::supports_shared_stubs(), "must support shared stubs"); + code()->share_trampoline_for(entry.target(), offset()); + } else { + address stub = emit_trampoline_stub(offset(), target); + if (stub == nullptr) { + postcond(pc() == badAddress); + return nullptr; // CodeCache is full } } - target = pc(); } + target = pc(); address call_pc = pc(); #ifdef ASSERT @@ -3545,7 +3527,7 @@ void MacroAssembler::cmpptr(Register src1, Address src2, Label& equal) { assert_different_registers(src1, t0); relocate(src2.rspec(), [&] { int32_t offset; - la_patchable(t0, src2, offset); + la(t0, src2.target(), offset); ld(t0, Address(t0, offset)); }); beq(src1, t0, equal); @@ -4193,7 +4175,7 @@ address MacroAssembler::zero_words(Register ptr, Register cnt) { Label around, done, done16; bltu(cnt, t0, around); { - RuntimeAddress zero_blocks = RuntimeAddress(StubRoutines::riscv::zero_blocks()); + RuntimeAddress zero_blocks(StubRoutines::riscv::zero_blocks()); assert(zero_blocks.target() != nullptr, "zero_blocks stub has not been generated"); if (StubRoutines::riscv::complete()) { address tpc = trampoline_call(zero_blocks); @@ -4788,11 +4770,11 @@ void MacroAssembler::rt_call(address dest, Register tmp) { CodeBlob *cb = CodeCache::find_blob(dest); RuntimeAddress target(dest); if (cb) { - far_call(target); + far_call(target, tmp); } else { relocate(target.rspec(), [&] { int32_t offset; - la_patchable(tmp, target, offset); + movptr(tmp, target.target(), offset); jalr(x1, tmp, offset); }); } diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index e4f36d261571c..c00b63169be16 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -718,7 +718,8 @@ class MacroAssembler: public Assembler { compare_and_branch_label_insn neg_insn, bool is_far = false); void la(Register Rd, Label &label); - void la(Register Rd, const address dest); + void la(Register Rd, const address addr); + void la(Register Rd, const address addr, int32_t &offset); void la(Register Rd, const Address &adr); void li16u(Register Rd, uint16_t imm); @@ -1062,28 +1063,18 @@ class MacroAssembler: public Assembler { void atomic_xchgwu(Register prev, Register newv, Register addr); void atomic_xchgalwu(Register prev, Register newv, Register addr); - static bool far_branches() { - return ReservedCodeCacheSize > branch_range; - } - - // Emit a direct call/jump if the entry address will always be in range, - // otherwise a far call/jump. + // Emit a far call/jump. Only invalidates the tmp register which + // is used to keep the entry address for jalr. // The address must be inside the code cache. // Supported entry.rspec(): // - relocInfo::external_word_type // - relocInfo::runtime_call_type // - relocInfo::none - // In the case of a far call/jump, the entry address is put in the tmp register. - // The tmp register is invalidated. - void far_call(Address entry, Register tmp = t0); - void far_jump(Address entry, Register tmp = t0); + void far_call(const Address &entry, Register tmp = t0); + void far_jump(const Address &entry, Register tmp = t0); static int far_branch_size() { - if (far_branches()) { return 2 * 4; // auipc + jalr, see far_call() & far_jump() - } else { - return 4; - } } void load_byte_map_base(Register reg); @@ -1095,8 +1086,6 @@ class MacroAssembler: public Assembler { sd(zr, Address(t0)); } - void la_patchable(Register reg1, const Address &dest, int32_t &offset); - virtual void _call_Unimplemented(address call_site) { mv(t1, call_site); } @@ -1442,6 +1431,8 @@ class MacroAssembler: public Assembler { VMRegPair dst, bool is_receiver, int* receiver_offset); + // Emit a runtime call. Only invalidates the tmp register which + // is used to keep the entry address for jalr/movptr. void rt_call(address dest, Register tmp = t0); void call(const address dest, Register temp = t0) { @@ -1481,7 +1472,7 @@ class MacroAssembler: public Assembler { InternalAddress target(const_addr.target()); relocate(target.rspec(), [&] { int32_t offset; - la_patchable(dest, target, offset); + la(dest, target.target(), offset); ld(dest, Address(dest, offset)); }); } diff --git a/src/hotspot/cpu/riscv/matcher_riscv.hpp b/src/hotspot/cpu/riscv/matcher_riscv.hpp index 1da8f0031228b..08914d4d83431 100644 --- a/src/hotspot/cpu/riscv/matcher_riscv.hpp +++ b/src/hotspot/cpu/riscv/matcher_riscv.hpp @@ -192,4 +192,9 @@ } } + // Is SIMD sort supported for this CPU? + static bool supports_simd_sort(BasicType bt) { + return false; + } + #endif // CPU_RISCV_MATCHER_RISCV_HPP diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index 87f240873a85b..5af25b26a16ad 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -1848,10 +1848,8 @@ uint MachUEPNode::size(PhaseRegAlloc* ra_) const // Emit exception handler code. int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) { - // la_patchable t0, #exception_blob_entry_point + // auipc t0, #exception_blob_entry_point // jr (offset)t0 - // or - // j #exception_blob_entry_point // Note that the code buffer's insts_mark is always relative to insts. // That's why we must use the macroassembler to generate a handler. C2_MacroAssembler _masm(&cbuf); @@ -2378,6 +2376,11 @@ encode %{ ciEnv::current()->record_failure("CodeCache is full"); return; } + } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { + // The NOP here is purely to ensure that eliding a call to + // JVM_EnsureMaterializedForStackWalk doesn't change the code size. + __ nop(); + __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); } else { int method_index = resolved_method_index(cbuf); RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) @@ -10368,6 +10371,26 @@ instruct array_equalsC(iRegP_R11 ary1, iRegP_R12 ary2, iRegI_R10 result, ins_pipe(pipe_class_memory); %} +// fast ArraysSupport.vectorizedHashCode +instruct arrays_hashcode(iRegP_R11 ary, iRegI_R12 cnt, iRegI_R10 result, immI basic_type, + iRegLNoSp tmp1, iRegLNoSp tmp2, + iRegLNoSp tmp3, iRegLNoSp tmp4, + iRegLNoSp tmp5, iRegLNoSp tmp6, rFlagsReg cr) +%{ + match(Set result (VectorizedHashCode (Binary ary cnt) (Binary result basic_type))); + effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, + USE_KILL ary, USE_KILL cnt, USE basic_type, KILL cr); + + format %{ "Array HashCode array[] $ary,$cnt,$result,$basic_type -> $result // KILL all" %} + ins_encode %{ + __ arrays_hashcode($ary$$Register, $cnt$$Register, $result$$Register, + $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, + $tmp4$$Register, $tmp5$$Register, $tmp6$$Register, + (BasicType)$basic_type$$constant); + %} + ins_pipe(pipe_class_memory); +%} + // ============================================================================ // Safepoint Instructions diff --git a/src/hotspot/cpu/riscv/riscv_v.ad b/src/hotspot/cpu/riscv/riscv_v.ad index f4d406002d067..c163325fc815f 100644 --- a/src/hotspot/cpu/riscv/riscv_v.ad +++ b/src/hotspot/cpu/riscv/riscv_v.ad @@ -3660,6 +3660,23 @@ instruct vexpand(vReg dst, vReg src, vRegMask_V0 v0, vReg tmp) %{ ins_pipe(pipe_slow); %} +// ------------------------------ Vector signum -------------------------------- + +// Vector Math.signum + +instruct vsignum_reg(vReg dst, vReg zero, vReg one, vRegMask_V0 v0) %{ + match(Set dst (SignumVF dst (Binary zero one))); + match(Set dst (SignumVD dst (Binary zero one))); + effect(TEMP_DEF dst, TEMP v0); + format %{ "vsignum $dst, $dst\t" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ signum_fp_v(as_VectorRegister($dst$$reg), as_VectorRegister($one$$reg), + bt, Matcher::vector_length(this)); + %} + ins_pipe(pipe_slow); +%} + // ------------------------------ Vector Load Gather --------------------------- instruct gather_load(vReg dst, indirect mem, vReg idx) %{ diff --git a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp index fa718e5b08e86..36430e126f973 100644 --- a/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp +++ b/src/hotspot/cpu/riscv/sharedRuntime_riscv.cpp @@ -344,12 +344,7 @@ static void patch_callers_callsite(MacroAssembler *masm) { __ mv(c_rarg0, xmethod); __ mv(c_rarg1, ra); - RuntimeAddress target(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite)); __ pop_CPU_state(); // restore sp @@ -1622,7 +1617,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, ExternalAddress target((address)&DTraceMethodProbes); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ la(t0, target.target(), offset); __ lbu(t0, Address(t0, offset)); }); __ bnez(t0, dtrace_method_entry); @@ -1846,7 +1841,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, ExternalAddress target((address)&DTraceMethodProbes); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ la(t0, target.target(), offset); __ lbu(t0, Address(t0, offset)); }); __ bnez(t0, dtrace_method_exit); @@ -1979,12 +1974,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, #ifndef PRODUCT assert(frame::arg_reg_save_area_bytes == 0, "not expecting frame reg save area"); #endif - RuntimeAddress target(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)); // Restore any method result value restore_native_result(masm, ret_type, stack_slots); @@ -2156,12 +2146,7 @@ void SharedRuntime::generate_deopt_blob() { __ mv(xcpool, Deoptimization::Unpack_reexecute); __ mv(c_rarg0, xthread); __ orrw(c_rarg2, zr, xcpool); // exec mode - RuntimeAddress target(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)); __ bind(retaddr); oop_maps->add_gc_map( __ pc()-start, map->deep_copy()); @@ -2253,12 +2238,7 @@ void SharedRuntime::generate_deopt_blob() { #endif // ASSERT __ mv(c_rarg0, xthread); __ mv(c_rarg1, xcpool); - RuntimeAddress target(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)); __ bind(retaddr); // Need to have an oopmap that tells fetch_unroll_info where to @@ -2400,12 +2380,7 @@ void SharedRuntime::generate_deopt_blob() { __ mv(c_rarg0, xthread); __ mv(c_rarg1, xcpool); // second arg: exec_mode - target = RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)); // Set an oopmap for the call site // Use the same PC we used for the last java frame @@ -2495,12 +2470,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { __ mv(c_rarg0, xthread); __ mv(c_rarg2, Deoptimization::Unpack_uncommon_trap); - RuntimeAddress target(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)); __ bind(retaddr); // Set an oopmap for the call site @@ -2622,12 +2592,7 @@ void SharedRuntime::generate_uncommon_trap_blob() { // sp should already be aligned __ mv(c_rarg0, xthread); __ mv(c_rarg1, Deoptimization::Unpack_uncommon_trap); - target = RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)); // Set an oopmap for the call site // Use the same PC we used for the last java frame @@ -2696,12 +2661,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t // Do the call __ mv(c_rarg0, xthread); - RuntimeAddress target(call_ptr); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(call_ptr); __ bind(retaddr); // Set an oopmap for the call site. This oopmap will map all @@ -2809,12 +2769,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha __ set_last_Java_frame(sp, noreg, retaddr, t0); __ mv(c_rarg0, xthread); - RuntimeAddress target(destination); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); + __ rt_call(destination); __ bind(retaddr); } @@ -2943,13 +2898,7 @@ void OptoRuntime::generate_exception_blob() { address the_pc = __ pc(); __ set_last_Java_frame(sp, noreg, the_pc, t0); __ mv(c_rarg0, xthread); - RuntimeAddress target(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C)); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la_patchable(t0, target, offset); - __ jalr(x1, t0, offset); - }); - + __ rt_call(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C)); // handle_exception_C is a special VM call which does not require an explicit // instruction sync afterwards. diff --git a/src/hotspot/cpu/riscv/templateTable_riscv.cpp b/src/hotspot/cpu/riscv/templateTable_riscv.cpp index ecc4520164d52..73b4d1e28ccef 100644 --- a/src/hotspot/cpu/riscv/templateTable_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateTable_riscv.cpp @@ -1,7 +1,7 @@ /* * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -2471,7 +2471,7 @@ void TemplateTable::jvmti_post_field_access(Register cache, Register index, ExternalAddress target((address) JvmtiExport::get_field_access_count_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ la(t0, target.target(), offset); __ lwu(x10, Address(t0, offset)); }); @@ -2682,7 +2682,7 @@ void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is ExternalAddress target((address)JvmtiExport::get_field_modification_count_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ la(t0, target.target(), offset); __ lwu(x10, Address(t0, offset)); }); __ beqz(x10, L1); @@ -2975,7 +2975,7 @@ void TemplateTable::jvmti_post_fast_field_mod() { ExternalAddress target((address)JvmtiExport::get_field_modification_count_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ la(t0, target.target(), offset); __ lwu(c_rarg3, Address(t0, offset)); }); __ beqz(c_rarg3, L2); @@ -3111,7 +3111,7 @@ void TemplateTable::fast_accessfield(TosState state) { ExternalAddress target((address)JvmtiExport::get_field_access_count_addr()); __ relocate(target.rspec(), [&] { int32_t offset; - __ la_patchable(t0, target, offset); + __ la(t0, target.target(), offset); __ lwu(x12, Address(t0, offset)); }); __ beqz(x12, L1); diff --git a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp index abfea10fd0217..142d9d636938d 100644 --- a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp +++ b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp @@ -128,6 +128,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); int code_size = upcall_stub_code_base_size + (total_out_args * upcall_stub_size_per_arg); CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 1); + if (buffer.blob() == nullptr) { + return nullptr; + } GrowableArray unfiltered_out_regs; int out_arg_bytes = ForeignGlobals::java_calling_convention(out_sig_bt, total_out_args, unfiltered_out_regs); @@ -344,6 +347,10 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, &buffer, receiver, in_ByteSize(frame_data_offset)); + if (blob == nullptr) { + return nullptr; + } + #ifndef PRODUCT if (lt.is_enabled()) { ResourceMark rm; diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index 2b7af4f52bcf3..223d5d8c519aa 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -336,6 +336,10 @@ void VM_Version::c2_initialize() { } } + if (FLAG_IS_DEFAULT(UseVectorizedHashCodeIntrinsic)) { + FLAG_SET_DEFAULT(UseVectorizedHashCodeIntrinsic, true); + } + if (!UseZicbop) { if (!FLAG_IS_DEFAULT(AllocatePrefetchStyle)) { warning("Zicbop is not available on this CPU"); diff --git a/src/hotspot/cpu/s390/compressedKlass_s390.cpp b/src/hotspot/cpu/s390/compressedKlass_s390.cpp new file mode 100644 index 0000000000000..868df0f02d7cb --- /dev/null +++ b/src/hotspot/cpu/s390/compressedKlass_s390.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023, Red Hat, Inc. All rights reserved. + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "oops/compressedKlass.hpp" +#include "utilities/globalDefinitions.hpp" + +char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size_t size, bool aslr, bool optimize_for_zero_base) { + + char* result = nullptr; + + uintptr_t tried_below = 0; + + // First, attempt to allocate < 4GB. We do this unconditionally: + // - if optimize_for_zero_base, a <4GB mapping start allows us to use base=0 shift=0 + // - if !optimize_for_zero_base, a <4GB mapping start allows us to use algfi + result = reserve_address_space_for_unscaled_encoding(size, aslr); + + // Failing that, try optimized for base=0 shift>0 + if (result == nullptr && optimize_for_zero_base) { + result = reserve_address_space_for_zerobased_encoding(size, aslr); + } + + // Failing that, aim for a base that is 4G-aligned; such a base can be set with aih. + if (result == nullptr) { + result = reserve_address_space_for_16bit_move(size, aslr); + } + + return result; +} diff --git a/src/hotspot/cpu/s390/downcallLinker_s390.cpp b/src/hotspot/cpu/s390/downcallLinker_s390.cpp index d3e11104e4800..22bd644e2b8a4 100644 --- a/src/hotspot/cpu/s390/downcallLinker_s390.cpp +++ b/src/hotspot/cpu/s390/downcallLinker_s390.cpp @@ -52,6 +52,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_args); int locs_size = 1; //must be non zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); + if (code.blob() == nullptr) { + return nullptr; + } StubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, @@ -60,12 +63,19 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, g.generate(); code.log_section_sizes("nep_invoker_blob"); + bool caller_must_gc_arguments = false; + bool alloc_fail_is_fatal = false; RuntimeStub* stub = RuntimeStub::new_runtime_stub("nep_invoker_blob", &code, g.frame_complete(), g.framesize(), - g.oop_maps(), false); + g.oop_maps(), + caller_must_gc_arguments, + alloc_fail_is_fatal); + if (stub == nullptr) { + return nullptr; + } #ifndef PRODUCT LogTarget(Trace, foreign, downcall) lt; diff --git a/src/hotspot/cpu/s390/matcher_s390.hpp b/src/hotspot/cpu/s390/matcher_s390.hpp index e68dca34c3b1a..450ea35a6cb18 100644 --- a/src/hotspot/cpu/s390/matcher_s390.hpp +++ b/src/hotspot/cpu/s390/matcher_s390.hpp @@ -184,4 +184,9 @@ } } + // Is SIMD sort supported for this CPU? + static bool supports_simd_sort(BasicType bt) { + return false; + } + #endif // CPU_S390_MATCHER_S390_HPP diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index e1d7104c6d608..9f4e182a9e4b7 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -10190,7 +10190,7 @@ instruct string_compress(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI tm format %{ "String Compress $src->$dst($len) -> $result" %} ins_encode %{ __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register, - $tmp$$Register, false, false); + $tmp$$Register, true, false); %} ins_pipe(pipe_class_dummy); %} diff --git a/src/hotspot/cpu/s390/upcallLinker_s390.cpp b/src/hotspot/cpu/s390/upcallLinker_s390.cpp index 10be41d6c287a..20c9b35db626a 100644 --- a/src/hotspot/cpu/s390/upcallLinker_s390.cpp +++ b/src/hotspot/cpu/s390/upcallLinker_s390.cpp @@ -126,6 +126,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); int code_size = upcall_stub_code_base_size + (total_out_args * upcall_stub_size_per_arg); CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 0); + if (buffer.blob() == nullptr) { + return nullptr; + } Register call_target_address = Z_R1_scratch; @@ -283,6 +286,10 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, &buffer, receiver, in_ByteSize(frame_data_offset)); + if (blob == nullptr) { + return nullptr; + } + #ifndef PRODUCT if (lt.is_enabled()) { ResourceMark rm; diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index cedddaed97588..8a2b3aa043609 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -920,6 +920,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { case 0x11: // movups case 0x12: // movlps case 0x28: // movaps + case 0x29: // movaps case 0x2E: // ucomiss case 0x2F: // comiss case 0x54: // andps @@ -969,7 +970,7 @@ address Assembler::locate_operand(address inst, WhichOperand which) { assert(which == call32_operand, "jcc has no disp32 or imm"); return ip; default: - ShouldNotReachHere(); + fatal("not handled: 0x0F%2X", 0xFF & *(ip-1)); } break; diff --git a/src/hotspot/cpu/x86/assembler_x86.hpp b/src/hotspot/cpu/x86/assembler_x86.hpp index 3bcfee90b3537..ecb1f2d587c1c 100644 --- a/src/hotspot/cpu/x86/assembler_x86.hpp +++ b/src/hotspot/cpu/x86/assembler_x86.hpp @@ -316,7 +316,7 @@ class Address { } bool xmmindex_needs_rex() const { - return _xmmindex->is_valid() && _xmmindex->encoding() >= 8; + return _xmmindex->is_valid() && ((_xmmindex->encoding() & 8) == 8); } relocInfo::relocType reloc() const { return _rspec.type(); } diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp index 29413e5457c57..54e5f55fa2b00 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp @@ -1094,32 +1094,78 @@ void C2_MacroAssembler::vminmax_fp(int opcode, BasicType elem_bt, bool is_min = (opcode == Op_MinV || opcode == Op_MinReductionV); bool is_double_word = is_double_word_type(elem_bt); + /* Note on 'non-obvious' assembly sequence: + * + * While there are vminps/vmaxps instructions, there are two important differences between hardware + * and Java on how they handle floats: + * a. -0.0 and +0.0 are considered equal (vminps/vmaxps will return second parameter when inputs are equal) + * b. NaN is not necesarily propagated (vminps/vmaxps will return second parameter when either input is NaN) + * + * It is still more efficient to use vminps/vmaxps, but with some pre/post-processing: + * a. -0.0/+0.0: Bias negative (positive) numbers to second parameter before vminps (vmaxps) + * (only useful when signs differ, noop otherwise) + * b. NaN: Check if it was the first parameter that had the NaN (with vcmp[UNORD_Q]) + + * Following pseudo code describes the algorithm for max[FD] (Min algorithm is on similar lines): + * btmp = (b < +0.0) ? a : b + * atmp = (b < +0.0) ? b : a + * Tmp = Max_Float(atmp , btmp) + * Res = (atmp == NaN) ? atmp : Tmp + */ + + void (MacroAssembler::*vblend)(XMMRegister, XMMRegister, XMMRegister, XMMRegister, int, bool, XMMRegister); + void (MacroAssembler::*vmaxmin)(XMMRegister, XMMRegister, XMMRegister, int); + void (MacroAssembler::*vcmp)(XMMRegister, XMMRegister, XMMRegister, int, int); + XMMRegister mask; + if (!is_double_word && is_min) { - vblendvps(atmp, a, b, a, vlen_enc); - vblendvps(btmp, b, a, a, vlen_enc); - vminps(tmp, atmp, btmp, vlen_enc); - vcmpps(btmp, atmp, atmp, Assembler::UNORD_Q, vlen_enc); - vblendvps(dst, tmp, atmp, btmp, vlen_enc); + mask = a; + vblend = &MacroAssembler::vblendvps; + vmaxmin = &MacroAssembler::vminps; + vcmp = &MacroAssembler::vcmpps; } else if (!is_double_word && !is_min) { - vblendvps(btmp, b, a, b, vlen_enc); - vblendvps(atmp, a, b, b, vlen_enc); - vmaxps(tmp, atmp, btmp, vlen_enc); - vcmpps(btmp, atmp, atmp, Assembler::UNORD_Q, vlen_enc); - vblendvps(dst, tmp, atmp, btmp, vlen_enc); + mask = b; + vblend = &MacroAssembler::vblendvps; + vmaxmin = &MacroAssembler::vmaxps; + vcmp = &MacroAssembler::vcmpps; } else if (is_double_word && is_min) { - vblendvpd(atmp, a, b, a, vlen_enc); - vblendvpd(btmp, b, a, a, vlen_enc); - vminpd(tmp, atmp, btmp, vlen_enc); - vcmppd(btmp, atmp, atmp, Assembler::UNORD_Q, vlen_enc); - vblendvpd(dst, tmp, atmp, btmp, vlen_enc); + mask = a; + vblend = &MacroAssembler::vblendvpd; + vmaxmin = &MacroAssembler::vminpd; + vcmp = &MacroAssembler::vcmppd; } else { assert(is_double_word && !is_min, "sanity"); - vblendvpd(btmp, b, a, b, vlen_enc); - vblendvpd(atmp, a, b, b, vlen_enc); - vmaxpd(tmp, atmp, btmp, vlen_enc); - vcmppd(btmp, atmp, atmp, Assembler::UNORD_Q, vlen_enc); - vblendvpd(dst, tmp, atmp, btmp, vlen_enc); + mask = b; + vblend = &MacroAssembler::vblendvpd; + vmaxmin = &MacroAssembler::vmaxpd; + vcmp = &MacroAssembler::vcmppd; } + + // Make sure EnableX86ECoreOpts isn't disabled on register overlaps + XMMRegister maxmin, scratch; + if (dst == btmp) { + maxmin = btmp; + scratch = tmp; + } else { + maxmin = tmp; + scratch = btmp; + } + + bool precompute_mask = EnableX86ECoreOpts && UseAVX>1; + if (precompute_mask && !is_double_word) { + vpsrad(tmp, mask, 32, vlen_enc); + mask = tmp; + } else if (precompute_mask && is_double_word) { + vpxor(tmp, tmp, tmp, vlen_enc); + vpcmpgtq(tmp, tmp, mask, vlen_enc); + mask = tmp; + } + + (this->*vblend)(atmp, a, b, mask, vlen_enc, !precompute_mask, btmp); + (this->*vblend)(btmp, b, a, mask, vlen_enc, !precompute_mask, tmp); + (this->*vmaxmin)(maxmin, atmp, btmp, vlen_enc); + (this->*vcmp)(scratch, atmp, atmp, Assembler::UNORD_Q, vlen_enc); + (this->*vblend)(dst, maxmin, atmp, scratch, vlen_enc, false, scratch); } void C2_MacroAssembler::evminmax_fp(int opcode, BasicType elem_bt, @@ -5318,18 +5364,18 @@ void C2_MacroAssembler::vector_signum_avx(int opcode, XMMRegister dst, XMMRegist if (opcode == Op_SignumVD) { vsubpd(dst, zero, one, vec_enc); // if src < 0 ? -1 : 1 - vblendvpd(dst, one, dst, src, vec_enc); + vblendvpd(dst, one, dst, src, vec_enc, true, xtmp1); // if src == NaN, -0.0 or 0.0 return src. vcmppd(xtmp1, src, zero, Assembler::EQ_UQ, vec_enc); - vblendvpd(dst, dst, src, xtmp1, vec_enc); + vblendvpd(dst, dst, src, xtmp1, vec_enc, false, xtmp1); } else { assert(opcode == Op_SignumVF, ""); vsubps(dst, zero, one, vec_enc); // if src < 0 ? -1 : 1 - vblendvps(dst, one, dst, src, vec_enc); + vblendvps(dst, one, dst, src, vec_enc, true, xtmp1); // if src == NaN, -0.0 or 0.0 return src. vcmpps(xtmp1, src, zero, Assembler::EQ_UQ, vec_enc); - vblendvps(dst, dst, src, xtmp1, vec_enc); + vblendvps(dst, dst, src, xtmp1, vec_enc, false, xtmp1); } } diff --git a/src/hotspot/cpu/x86/compressedKlass_x86.cpp b/src/hotspot/cpu/x86/compressedKlass_x86.cpp new file mode 100644 index 0000000000000..5b5a405bcef86 --- /dev/null +++ b/src/hotspot/cpu/x86/compressedKlass_x86.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023, Red Hat, Inc. All rights reserved. + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#ifdef _LP64 + +#include "oops/compressedKlass.hpp" +#include "utilities/globalDefinitions.hpp" + +char* CompressedKlassPointers::reserve_address_space_for_compressed_classes(size_t size, bool aslr, bool optimize_for_zero_base) { + + char* result = nullptr; + + // Optimize for unscaled encoding; failing that, for zero-based encoding: + if (optimize_for_zero_base) { + result = reserve_address_space_for_unscaled_encoding(size, aslr); + if (result == nullptr) { + result = reserve_address_space_for_zerobased_encoding(size, aslr); + } + } // end: low-address reservation + + // Nothing more to optimize for on x64. If base != 0, we will always emit the full 64-bit immediate. + return result; +} + +#endif // _LP64 diff --git a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp index 1a40429b7bdba..41039e0cfd835 100644 --- a/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/downcallLinker_x86_64.cpp @@ -49,6 +49,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg); int locs_size = 1; // can not be zero CodeBuffer code("nep_invoker_blob", code_size, locs_size); + if (code.blob() == nullptr) { + return nullptr; + } StubGenerator g(&code, signature, num_args, ret_bt, abi, input_registers, output_registers, needs_return_buffer, captured_state_mask, @@ -56,12 +59,19 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, g.generate(); code.log_section_sizes("nep_invoker_blob"); + bool caller_must_gc_arguments = false; + bool alloc_fail_is_fatal = false; RuntimeStub* stub = RuntimeStub::new_runtime_stub("nep_invoker_blob", &code, g.frame_complete(), g.framesize(), - g.oop_maps(), false); + g.oop_maps(), + caller_must_gc_arguments, + alloc_fail_is_fatal); + if (stub == nullptr) { + return nullptr; + } #ifndef PRODUCT LogTarget(Trace, foreign, downcall) lt; diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index ed8a23771d34c..aec1f3c9105a9 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -3566,6 +3566,56 @@ void MacroAssembler::vbroadcastss(XMMRegister dst, AddressLiteral src, int vecto } } +// Vector float blend +// vblendvps(XMMRegister dst, XMMRegister nds, XMMRegister src, XMMRegister mask, int vector_len, bool compute_mask = true, XMMRegister scratch = xnoreg) +void MacroAssembler::vblendvps(XMMRegister dst, XMMRegister src1, XMMRegister src2, XMMRegister mask, int vector_len, bool compute_mask, XMMRegister scratch) { + // WARN: Allow dst == (src1|src2), mask == scratch + bool blend_emulation = EnableX86ECoreOpts && UseAVX > 1; + bool scratch_available = scratch != xnoreg && scratch != src1 && scratch != src2 && scratch != dst; + bool dst_available = dst != mask && (dst != src1 || dst != src2); + if (blend_emulation && scratch_available && dst_available) { + if (compute_mask) { + vpsrad(scratch, mask, 32, vector_len); + mask = scratch; + } + if (dst == src1) { + vpandn(dst, mask, src1, vector_len); // if mask == 0, src1 + vpand (scratch, mask, src2, vector_len); // if mask == 1, src2 + } else { + vpand (dst, mask, src2, vector_len); // if mask == 1, src2 + vpandn(scratch, mask, src1, vector_len); // if mask == 0, src1 + } + vpor(dst, dst, scratch, vector_len); + } else { + Assembler::vblendvps(dst, src1, src2, mask, vector_len); + } +} + +// vblendvpd(XMMRegister dst, XMMRegister nds, XMMRegister src, XMMRegister mask, int vector_len, bool compute_mask = true, XMMRegister scratch = xnoreg) +void MacroAssembler::vblendvpd(XMMRegister dst, XMMRegister src1, XMMRegister src2, XMMRegister mask, int vector_len, bool compute_mask, XMMRegister scratch) { + // WARN: Allow dst == (src1|src2), mask == scratch + bool blend_emulation = EnableX86ECoreOpts && UseAVX > 1; + bool scratch_available = scratch != xnoreg && scratch != src1 && scratch != src2 && scratch != dst && (!compute_mask || scratch != mask); + bool dst_available = dst != mask && (dst != src1 || dst != src2); + if (blend_emulation && scratch_available && dst_available) { + if (compute_mask) { + vpxor(scratch, scratch, scratch, vector_len); + vpcmpgtq(scratch, scratch, mask, vector_len); + mask = scratch; + } + if (dst == src1) { + vpandn(dst, mask, src1, vector_len); // if mask == 0, src + vpand (scratch, mask, src2, vector_len); // if mask == 1, src2 + } else { + vpand (dst, mask, src2, vector_len); // if mask == 1, src2 + vpandn(scratch, mask, src1, vector_len); // if mask == 0, src + } + vpor(dst, dst, scratch, vector_len); + } else { + Assembler::vblendvpd(dst, src1, src2, mask, vector_len); + } +} + void MacroAssembler::vpcmpeqb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { assert(((dst->encoding() < 16 && src->encoding() < 16 && nds->encoding() < 16) || VM_Version::supports_avx512vlbw()),"XMM register should be 0-15"); Assembler::vpcmpeqb(dst, nds, src, vector_len); @@ -8578,15 +8628,19 @@ void MacroAssembler::crc32c_ipl_alg2_alt2(Register in_out, Register in1, Registe #undef BLOCK_COMMENT // Compress char[] array to byte[]. -// ..\jdk\src\java.base\share\classes\java\lang\StringUTF16.java +// Intrinsic for java.lang.StringUTF16.compress(char[] src, int srcOff, byte[] dst, int dstOff, int len) +// Return the array length if every element in array can be encoded, +// otherwise, the index of first non-latin1 (> 0xff) character. // @IntrinsicCandidate -// private static int compress(char[] src, int srcOff, byte[] dst, int dstOff, int len) { +// public static int compress(char[] src, int srcOff, byte[] dst, int dstOff, int len) { // for (int i = 0; i < len; i++) { -// int c = src[srcOff++]; -// if (c >>> 8 != 0) { -// return 0; +// char c = src[srcOff]; +// if (c > 0xff) { +// return i; // return index of non-latin1 char // } -// dst[dstOff++] = (byte)c; +// dst[dstOff] = (byte)c; +// srcOff++; +// dstOff++; // } // return len; // } @@ -8594,7 +8648,7 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le XMMRegister tmp1Reg, XMMRegister tmp2Reg, XMMRegister tmp3Reg, XMMRegister tmp4Reg, Register tmp5, Register result, KRegister mask1, KRegister mask2) { - Label copy_chars_loop, return_length, return_zero, done; + Label copy_chars_loop, done, reset_sp, copy_tail; // rsi: src // rdi: dst @@ -8609,28 +8663,28 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le assert(len != result, ""); // save length for return - push(len); + movl(result, len); if ((AVX3Threshold == 0) && (UseAVX > 2) && // AVX512 VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()) { - Label copy_32_loop, copy_loop_tail, below_threshold; + Label copy_32_loop, copy_loop_tail, below_threshold, reset_for_copy_tail; // alignment Label post_alignment; - // if length of the string is less than 16, handle it in an old fashioned way + // if length of the string is less than 32, handle it the old fashioned way testl(len, -32); jcc(Assembler::zero, below_threshold); // First check whether a character is compressible ( <= 0xFF). // Create mask to test for Unicode chars inside zmm vector - movl(result, 0x00FF); - evpbroadcastw(tmp2Reg, result, Assembler::AVX_512bit); + movl(tmp5, 0x00FF); + evpbroadcastw(tmp2Reg, tmp5, Assembler::AVX_512bit); testl(len, -64); - jcc(Assembler::zero, post_alignment); + jccb(Assembler::zero, post_alignment); movl(tmp5, dst); andl(tmp5, (32 - 1)); @@ -8639,18 +8693,19 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le // bail out when there is nothing to be done testl(tmp5, 0xFFFFFFFF); - jcc(Assembler::zero, post_alignment); + jccb(Assembler::zero, post_alignment); // ~(~0 << len), where len is the # of remaining elements to process - movl(result, 0xFFFFFFFF); - shlxl(result, result, tmp5); - notl(result); - kmovdl(mask2, result); + movl(len, 0xFFFFFFFF); + shlxl(len, len, tmp5); + notl(len); + kmovdl(mask2, len); + movl(len, result); evmovdquw(tmp1Reg, mask2, Address(src, 0), /*merge*/ false, Assembler::AVX_512bit); evpcmpw(mask1, mask2, tmp1Reg, tmp2Reg, Assembler::le, /*signed*/ false, Assembler::AVX_512bit); ktestd(mask1, mask2); - jcc(Assembler::carryClear, return_zero); + jcc(Assembler::carryClear, copy_tail); evpmovwb(Address(dst, 0), mask2, tmp1Reg, Assembler::AVX_512bit); @@ -8665,7 +8720,7 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le movl(tmp5, len); andl(tmp5, (32 - 1)); // tail count (in chars) andl(len, ~(32 - 1)); // vector count (in chars) - jcc(Assembler::zero, copy_loop_tail); + jccb(Assembler::zero, copy_loop_tail); lea(src, Address(src, len, Address::times_2)); lea(dst, Address(dst, len, Address::times_1)); @@ -8675,55 +8730,60 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le evmovdquw(tmp1Reg, Address(src, len, Address::times_2), Assembler::AVX_512bit); evpcmpuw(mask1, tmp1Reg, tmp2Reg, Assembler::le, Assembler::AVX_512bit); kortestdl(mask1, mask1); - jcc(Assembler::carryClear, return_zero); + jccb(Assembler::carryClear, reset_for_copy_tail); // All elements in current processed chunk are valid candidates for // compression. Write a truncated byte elements to the memory. evpmovwb(Address(dst, len, Address::times_1), tmp1Reg, Assembler::AVX_512bit); addptr(len, 32); - jcc(Assembler::notZero, copy_32_loop); + jccb(Assembler::notZero, copy_32_loop); bind(copy_loop_tail); // bail out when there is nothing to be done testl(tmp5, 0xFFFFFFFF); - jcc(Assembler::zero, return_length); + jcc(Assembler::zero, done); movl(len, tmp5); // ~(~0 << len), where len is the # of remaining elements to process - movl(result, 0xFFFFFFFF); - shlxl(result, result, len); - notl(result); + movl(tmp5, 0xFFFFFFFF); + shlxl(tmp5, tmp5, len); + notl(tmp5); - kmovdl(mask2, result); + kmovdl(mask2, tmp5); evmovdquw(tmp1Reg, mask2, Address(src, 0), /*merge*/ false, Assembler::AVX_512bit); evpcmpw(mask1, mask2, tmp1Reg, tmp2Reg, Assembler::le, /*signed*/ false, Assembler::AVX_512bit); ktestd(mask1, mask2); - jcc(Assembler::carryClear, return_zero); + jcc(Assembler::carryClear, copy_tail); evpmovwb(Address(dst, 0), mask2, tmp1Reg, Assembler::AVX_512bit); - jmp(return_length); + jmp(done); + + bind(reset_for_copy_tail); + lea(src, Address(src, tmp5, Address::times_2)); + lea(dst, Address(dst, tmp5, Address::times_1)); + subptr(len, tmp5); + jmp(copy_chars_loop); bind(below_threshold); } if (UseSSE42Intrinsics) { - Label copy_32_loop, copy_16, copy_tail; + Label copy_32_loop, copy_16, copy_tail_sse, reset_for_copy_tail; - movl(result, len); + // vectored compression + testl(len, 0xfffffff8); + jcc(Assembler::zero, copy_tail); movl(tmp5, 0xff00ff00); // create mask to test for Unicode chars in vectors + movdl(tmp1Reg, tmp5); + pshufd(tmp1Reg, tmp1Reg, 0); // store Unicode mask in tmp1Reg - // vectored compression - andl(len, 0xfffffff0); // vector count (in chars) - andl(result, 0x0000000f); // tail count (in chars) - testl(len, len); - jcc(Assembler::zero, copy_16); + andl(len, 0xfffffff0); + jccb(Assembler::zero, copy_16); // compress 16 chars per iter - movdl(tmp1Reg, tmp5); - pshufd(tmp1Reg, tmp1Reg, 0); // store Unicode mask in tmp1Reg pxor(tmp4Reg, tmp4Reg); lea(src, Address(src, len, Address::times_2)); @@ -8736,59 +8796,60 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le movdqu(tmp3Reg, Address(src, len, Address::times_2, 16)); // load next 8 characters por(tmp4Reg, tmp3Reg); ptest(tmp4Reg, tmp1Reg); // check for Unicode chars in next vector - jcc(Assembler::notZero, return_zero); + jccb(Assembler::notZero, reset_for_copy_tail); packuswb(tmp2Reg, tmp3Reg); // only ASCII chars; compress each to 1 byte movdqu(Address(dst, len, Address::times_1), tmp2Reg); addptr(len, 16); - jcc(Assembler::notZero, copy_32_loop); + jccb(Assembler::notZero, copy_32_loop); // compress next vector of 8 chars (if any) bind(copy_16); - movl(len, result); - andl(len, 0xfffffff8); // vector count (in chars) - andl(result, 0x00000007); // tail count (in chars) - testl(len, len); - jccb(Assembler::zero, copy_tail); + // len = 0 + testl(result, 0x00000008); // check if there's a block of 8 chars to compress + jccb(Assembler::zero, copy_tail_sse); - movdl(tmp1Reg, tmp5); - pshufd(tmp1Reg, tmp1Reg, 0); // store Unicode mask in tmp1Reg pxor(tmp3Reg, tmp3Reg); movdqu(tmp2Reg, Address(src, 0)); ptest(tmp2Reg, tmp1Reg); // check for Unicode chars in vector - jccb(Assembler::notZero, return_zero); + jccb(Assembler::notZero, reset_for_copy_tail); packuswb(tmp2Reg, tmp3Reg); // only LATIN1 chars; compress each to 1 byte movq(Address(dst, 0), tmp2Reg); addptr(src, 16); addptr(dst, 8); + jmpb(copy_tail_sse); - bind(copy_tail); + bind(reset_for_copy_tail); + movl(tmp5, result); + andl(tmp5, 0x0000000f); + lea(src, Address(src, tmp5, Address::times_2)); + lea(dst, Address(dst, tmp5, Address::times_1)); + subptr(len, tmp5); + jmpb(copy_chars_loop); + + bind(copy_tail_sse); movl(len, result); + andl(len, 0x00000007); // tail count (in chars) } // compress 1 char per iter + bind(copy_tail); testl(len, len); - jccb(Assembler::zero, return_length); + jccb(Assembler::zero, done); lea(src, Address(src, len, Address::times_2)); lea(dst, Address(dst, len, Address::times_1)); negptr(len); bind(copy_chars_loop); - load_unsigned_short(result, Address(src, len, Address::times_2)); - testl(result, 0xff00); // check if Unicode char - jccb(Assembler::notZero, return_zero); - movb(Address(dst, len, Address::times_1), result); // ASCII char; compress to 1 byte + load_unsigned_short(tmp5, Address(src, len, Address::times_2)); + testl(tmp5, 0xff00); // check if Unicode char + jccb(Assembler::notZero, reset_sp); + movb(Address(dst, len, Address::times_1), tmp5); // ASCII char; compress to 1 byte increment(len); - jcc(Assembler::notZero, copy_chars_loop); - - // if compression succeeded, return length - bind(return_length); - pop(result); - jmpb(done); + jccb(Assembler::notZero, copy_chars_loop); - // if compression failed, return 0 - bind(return_zero); - xorl(result, result); - addptr(rsp, wordSize); + // add len then return (len will be zero if compress succeeded, otherwise negative) + bind(reset_sp); + addl(result, len); bind(done); } diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp index 47943576dcec9..ea6a37d16edba 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp @@ -1130,6 +1130,10 @@ class MacroAssembler: public Assembler { using Assembler::vbroadcastss; void vbroadcastss(XMMRegister dst, AddressLiteral src, int vector_len, Register rscratch = noreg); + // Vector float blend + void vblendvps(XMMRegister dst, XMMRegister nds, XMMRegister src, XMMRegister mask, int vector_len, bool compute_mask = true, XMMRegister scratch = xnoreg); + void vblendvpd(XMMRegister dst, XMMRegister nds, XMMRegister src, XMMRegister mask, int vector_len, bool compute_mask = true, XMMRegister scratch = xnoreg); + void divsd(XMMRegister dst, XMMRegister src) { Assembler::divsd(dst, src); } void divsd(XMMRegister dst, Address src) { Assembler::divsd(dst, src); } void divsd(XMMRegister dst, AddressLiteral src, Register rscratch = noreg); diff --git a/src/hotspot/cpu/x86/matcher_x86.hpp b/src/hotspot/cpu/x86/matcher_x86.hpp index bc249c0f33aaf..de844c4be9f3a 100644 --- a/src/hotspot/cpu/x86/matcher_x86.hpp +++ b/src/hotspot/cpu/x86/matcher_x86.hpp @@ -248,4 +248,17 @@ } } + // Is SIMD sort supported for this CPU? + static bool supports_simd_sort(BasicType bt) { + if (VM_Version::supports_avx512dq()) { + return true; + } + else if (VM_Version::supports_avx2() && !is_double_word_type(bt)) { + return true; + } + else { + return false; + } + } + #endif // CPU_X86_MATCHER_X86_HPP diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp index c73e0759b57f7..85f3bbf61094c 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp @@ -4193,22 +4193,23 @@ void StubGenerator::generate_compiler_stubs() { = CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_square); } - // Load x86_64_sort library on supported hardware to enable avx512 sort and partition intrinsics - if (VM_Version::is_intel() && VM_Version::supports_avx512dq()) { + // Load x86_64_sort library on supported hardware to enable SIMD sort and partition intrinsics + + if (VM_Version::is_intel() && (VM_Version::supports_avx512dq() || VM_Version::supports_avx2())) { void *libsimdsort = nullptr; char ebuf_[1024]; char dll_name_simd_sort[JVM_MAXPATHLEN]; if (os::dll_locate_lib(dll_name_simd_sort, sizeof(dll_name_simd_sort), Arguments::get_dll_dir(), "simdsort")) { libsimdsort = os::dll_load(dll_name_simd_sort, ebuf_, sizeof ebuf_); } - // Get addresses for avx512 sort and partition routines + // Get addresses for SIMD sort and partition routines if (libsimdsort != nullptr) { log_info(library)("Loaded library %s, handle " INTPTR_FORMAT, JNI_LIB_PREFIX "simdsort" JNI_LIB_SUFFIX, p2i(libsimdsort)); - snprintf(ebuf_, sizeof(ebuf_), "avx512_sort"); + snprintf(ebuf_, sizeof(ebuf_), VM_Version::supports_avx512dq() ? "avx512_sort" : "avx2_sort"); StubRoutines::_array_sort = (address)os::dll_lookup(libsimdsort, ebuf_); - snprintf(ebuf_, sizeof(ebuf_), "avx512_partition"); + snprintf(ebuf_, sizeof(ebuf_), VM_Version::supports_avx512dq() ? "avx512_partition" : "avx2_partition"); StubRoutines::_array_partition = (address)os::dll_lookup(libsimdsort, ebuf_); } } diff --git a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp index ca170c5013e26..89e7a466264b9 100644 --- a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp @@ -177,6 +177,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); int code_size = upcall_stub_code_base_size + (total_out_args * upcall_stub_size_per_arg); CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 1); + if (buffer.blob() == nullptr) { + return nullptr; + } GrowableArray unfiltered_out_regs; int out_arg_bytes = ForeignGlobals::java_calling_convention(out_sig_bt, total_out_args, unfiltered_out_regs); @@ -379,6 +382,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, &buffer, receiver, in_ByteSize(frame_data_offset)); + if (blob == nullptr) { + return nullptr; + } #ifndef PRODUCT if (lt.is_enabled()) { diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp index 1517e456e8230..ac937bef04e7c 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -858,7 +858,7 @@ void VM_Version::get_processor_features() { // Check if processor has Intel Ecore if (FLAG_IS_DEFAULT(EnableX86ECoreOpts) && is_intel() && cpu_family() == 6 && - (_model == 0x97 || _model == 0xAC || _model == 0xAF)) { + (_model == 0x97 || _model == 0xAA || _model == 0xAC || _model == 0xAF)) { FLAG_SET_DEFAULT(EnableX86ECoreOpts, true); } @@ -1130,6 +1130,7 @@ void VM_Version::get_processor_features() { FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); } +#ifdef _LP64 // ChaCha20 Intrinsics // As long as the system supports AVX as a baseline we can do a // SIMD-enabled block function. StubGenerator makes the determination @@ -1145,6 +1146,13 @@ void VM_Version::get_processor_features() { } FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false); } +#else + // No support currently for ChaCha20 intrinsics on 32-bit platforms + if (UseChaCha20Intrinsics) { + warning("ChaCha20 intrinsics are not available on this CPU."); + FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false); + } +#endif // _LP64 // Base64 Intrinsics (Check the condition for which the intrinsic will be active) if (UseAVX >= 2) { diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 681abd7199fee..694ec2ddbd6aa 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -7801,7 +7801,7 @@ instruct blendvp(vec dst, vec src, vec mask, rxmm0 tmp) %{ %} instruct vblendvpI(legVec dst, legVec src1, legVec src2, legVec mask) %{ - predicate(UseAVX > 0 && + predicate(UseAVX > 0 && !EnableX86ECoreOpts && n->in(2)->bottom_type()->isa_vectmask() == NULL && Matcher::vector_length_in_bytes(n) <= 32 && is_integral_type(Matcher::vector_element_basic_type(n))); @@ -7815,7 +7815,7 @@ instruct vblendvpI(legVec dst, legVec src1, legVec src2, legVec mask) %{ %} instruct vblendvpFD(legVec dst, legVec src1, legVec src2, legVec mask) %{ - predicate(UseAVX > 0 && + predicate(UseAVX > 0 && !EnableX86ECoreOpts && n->in(2)->bottom_type()->isa_vectmask() == NULL && Matcher::vector_length_in_bytes(n) <= 32 && !is_integral_type(Matcher::vector_element_basic_type(n))); @@ -7828,6 +7828,22 @@ instruct vblendvpFD(legVec dst, legVec src1, legVec src2, legVec mask) %{ ins_pipe( pipe_slow ); %} +instruct vblendvp(legVec dst, legVec src1, legVec src2, legVec mask, legVec vtmp) %{ + predicate(UseAVX > 0 && EnableX86ECoreOpts && + n->in(2)->bottom_type()->isa_vectmask() == NULL && + Matcher::vector_length_in_bytes(n) <= 32); + match(Set dst (VectorBlend (Binary src1 src2) mask)); + format %{ "vector_blend $dst,$src1,$src2,$mask\t! using $vtmp as TEMP" %} + effect(TEMP vtmp, TEMP dst); + ins_encode %{ + int vlen_enc = vector_length_encoding(this); + __ vpandn($vtmp$$XMMRegister, $mask$$XMMRegister, $src1$$XMMRegister, vlen_enc); + __ vpand ($dst$$XMMRegister, $mask$$XMMRegister, $src2$$XMMRegister, vlen_enc); + __ vpor ($dst$$XMMRegister, $dst$$XMMRegister, $vtmp$$XMMRegister, vlen_enc); + %} + ins_pipe( pipe_slow ); +%} + instruct evblendvp64(vec dst, vec src1, vec src2, vec mask, kReg ktmp) %{ predicate(Matcher::vector_length_in_bytes(n) == 64 && n->in(2)->bottom_type()->isa_vectmask() == NULL); diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 94844cd4e7f9d..759dd8a1d485b 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -4478,34 +4478,15 @@ instruct loadD(regD dst, memory mem) ins_pipe(pipe_slow); // XXX %} - -// Following pseudo code describes the algorithm for max[FD]: -// Min algorithm is on similar lines -// btmp = (b < +0.0) ? a : b -// atmp = (b < +0.0) ? b : a -// Tmp = Max_Float(atmp , btmp) -// Res = (atmp == NaN) ? atmp : Tmp - // max = java.lang.Math.max(float a, float b) instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ predicate(UseAVX > 0 && !SuperWord::is_reduction(n)); match(Set dst (MaxF a b)); effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); - format %{ - "vblendvps $btmp,$b,$a,$b \n\t" - "vblendvps $atmp,$a,$b,$b \n\t" - "vmaxss $tmp,$atmp,$btmp \n\t" - "vcmpps.unordered $btmp,$atmp,$atmp \n\t" - "vblendvps $dst,$tmp,$atmp,$btmp \n\t" - %} - ins_encode %{ - int vector_len = Assembler::AVX_128bit; - __ vblendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); - __ vblendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); - __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); - __ vcmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); - __ vblendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); - %} + format %{ "maxF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} + ins_encode %{ + __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); + %} ins_pipe( pipe_slow ); %} @@ -4527,20 +4508,9 @@ instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, predicate(UseAVX > 0 && !SuperWord::is_reduction(n)); match(Set dst (MaxD a b)); effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); - format %{ - "vblendvpd $btmp,$b,$a,$b \n\t" - "vblendvpd $atmp,$a,$b,$b \n\t" - "vmaxsd $tmp,$atmp,$btmp \n\t" - "vcmppd.unordered $btmp,$atmp,$atmp \n\t" - "vblendvpd $dst,$tmp,$atmp,$btmp \n\t" - %} + format %{ "maxD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} ins_encode %{ - int vector_len = Assembler::AVX_128bit; - __ vblendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); - __ vblendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); - __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); - __ vcmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); - __ vblendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); + __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); %} ins_pipe( pipe_slow ); %} @@ -4563,20 +4533,9 @@ instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, predicate(UseAVX > 0 && !SuperWord::is_reduction(n)); match(Set dst (MinF a b)); effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); - format %{ - "vblendvps $atmp,$a,$b,$a \n\t" - "vblendvps $btmp,$b,$a,$a \n\t" - "vminss $tmp,$atmp,$btmp \n\t" - "vcmpps.unordered $btmp,$atmp,$atmp \n\t" - "vblendvps $dst,$tmp,$atmp,$btmp \n\t" - %} + format %{ "minF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} ins_encode %{ - int vector_len = Assembler::AVX_128bit; - __ vblendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); - __ vblendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); - __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); - __ vcmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); - __ vblendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); + __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); %} ins_pipe( pipe_slow ); %} @@ -4599,20 +4558,9 @@ instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, predicate(UseAVX > 0 && !SuperWord::is_reduction(n)); match(Set dst (MinD a b)); effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); - format %{ - "vblendvpd $atmp,$a,$b,$a \n\t" - "vblendvpd $btmp,$b,$a,$a \n\t" - "vminsd $tmp,$atmp,$btmp \n\t" - "vcmppd.unordered $btmp,$atmp,$atmp \n\t" - "vblendvpd $dst,$tmp,$atmp,$btmp \n\t" - %} - ins_encode %{ - int vector_len = Assembler::AVX_128bit; - __ vblendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); - __ vblendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); - __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); - __ vcmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); - __ vblendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); + format %{ "minD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} + ins_encode %{ + __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); %} ins_pipe( pipe_slow ); %} diff --git a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp index 138a22d512431..810f7de3cb3f6 100644 --- a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp +++ b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp @@ -30,6 +30,8 @@ #define SUPPORTS_NATIVE_CX8 #endif +#define DEFAULT_CACHE_LINE_SIZE 64 + #define SUPPORT_MONITOR_COUNT #include diff --git a/src/hotspot/os/aix/libodm_aix.cpp b/src/hotspot/os/aix/libodm_aix.cpp index d62a94939a46b..9fe0fb7abd842 100644 --- a/src/hotspot/os/aix/libodm_aix.cpp +++ b/src/hotspot/os/aix/libodm_aix.cpp @@ -35,7 +35,7 @@ dynamicOdm::dynamicOdm() { const char* libodmname = "/usr/lib/libodm.a(shr_64.o)"; char ebuf[512]; - void* _libhandle = os::dll_load(libodmname, ebuf, sizeof(ebuf)); + _libhandle = os::dll_load(libodmname, ebuf, sizeof(ebuf)); if (!_libhandle) { trcVerbose("Cannot load %s (error %s)", libodmname, ebuf); @@ -48,14 +48,14 @@ dynamicOdm::dynamicOdm() { _odm_terminate = (fun_odm_terminate )dlsym(_libhandle, "odm_terminate" ); if (!_odm_initialize || !_odm_set_path || !_odm_mount_class || !_odm_get_obj || !_odm_terminate) { trcVerbose("Couldn't find all required odm symbols from %s", libodmname); - dlclose(_libhandle); + os::dll_unload(_libhandle); _libhandle = nullptr; return; } } dynamicOdm::~dynamicOdm() { - if (_libhandle) { dlclose(_libhandle); } + if (_libhandle) { os::dll_unload(_libhandle); } } diff --git a/src/hotspot/os/aix/libperfstat_aix.cpp b/src/hotspot/os/aix/libperfstat_aix.cpp index 69f6224536528..f547b4c78e77c 100644 --- a/src/hotspot/os/aix/libperfstat_aix.cpp +++ b/src/hotspot/os/aix/libperfstat_aix.cpp @@ -114,7 +114,7 @@ bool libperfstat::init() { void libperfstat::cleanup() { if (g_libhandle) { - dlclose(g_libhandle); + os::dll_unload(g_libhandle); g_libhandle = nullptr; } diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index fc8e0da1a69de..18f3cd2b38d49 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -2540,7 +2540,9 @@ void os::jfr_report_memory_info() { // Send the RSS JFR event EventResidentSetSize event; event.set_size(info.resident_size); - event.set_peak(info.resident_size_max); + // We've seen that resident_size_max sometimes trails resident_size with one page. + // Make sure we always report size <= peak + event.set_peak(MAX2(info.resident_size_max, info.resident_size)); event.commit(); } else { // Log a warning diff --git a/src/hotspot/os/linux/gc/z/zLargePages_linux.cpp b/src/hotspot/os/linux/gc/z/zLargePages_linux.cpp index caf70224599e1..a00572f08e769 100644 --- a/src/hotspot/os/linux/gc/z/zLargePages_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zLargePages_linux.cpp @@ -23,16 +23,24 @@ #include "precompiled.hpp" #include "gc/z/zLargePages.hpp" +#include "hugepages.hpp" +#include "os_linux.hpp" #include "runtime/globals.hpp" void ZLargePages::pd_initialize() { + if (os::Linux::thp_requested()) { + // Check if the OS config turned off transparent huge pages for shmem. + _os_enforced_transparent_mode = HugePages::shmem_thp_info().is_disabled(); + _state = _os_enforced_transparent_mode ? Disabled : Transparent; + return; + } + if (UseLargePages) { - if (UseTransparentHugePages) { - _state = Transparent; - } else { - _state = Explicit; - } - } else { - _state = Disabled; + _state = Explicit; + return; } + + // Check if the OS config turned on transparent huge pages for shmem. + _os_enforced_transparent_mode = HugePages::shmem_thp_info().is_forced(); + _state = _os_enforced_transparent_mode ? Transparent : Disabled; } diff --git a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp index fb01e05ff7852..ff891509365a0 100644 --- a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp @@ -32,6 +32,7 @@ #include "gc/z/zNUMA.inline.hpp" #include "gc/z/zPhysicalMemoryBacking_linux.hpp" #include "gc/z/zSyscall_linux.hpp" +#include "hugepages.hpp" #include "logging/log.hpp" #include "os_linux.hpp" #include "runtime/init.hpp" @@ -446,8 +447,10 @@ ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_tmpfs(zoffset offset, size_ return errno; } - // Advise mapping to use transparent huge pages - os::realign_memory((char*)addr, length, ZGranuleSize); + // Maybe madvise the mapping to use transparent huge pages + if (os::Linux::should_madvise_shmem_thps()) { + os::Linux::madvise_transparent_huge_pages(addr, length); + } // Touch the mapping (safely) to make sure it's backed by memory const bool backed = safe_touch_mapping(addr, length, _block_size); diff --git a/src/hotspot/os/linux/hugepages.cpp b/src/hotspot/os/linux/hugepages.cpp index f9f9dd497c7b6..67645b91aa566 100644 --- a/src/hotspot/os/linux/hugepages.cpp +++ b/src/hotspot/os/linux/hugepages.cpp @@ -28,6 +28,7 @@ #include "logging/log.hpp" #include "logging/logStream.hpp" +#include "runtime/globals_extension.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" @@ -227,15 +228,97 @@ void THPSupport::print_on(outputStream* os) { } } +ShmemTHPSupport::ShmemTHPSupport() : + _initialized(false), _mode(ShmemTHPMode::unknown) {} + +ShmemTHPMode ShmemTHPSupport::mode() const { + assert(_initialized, "Not initialized"); + return _mode; +} + +bool ShmemTHPSupport::is_forced() const { + return _mode == ShmemTHPMode::always || _mode == ShmemTHPMode::force || _mode == ShmemTHPMode::within_size; +} + +bool ShmemTHPSupport::is_enabled() const { + return is_forced() || _mode == ShmemTHPMode::advise; +} + +bool ShmemTHPSupport::is_disabled() const { + return _mode == ShmemTHPMode::never || _mode == ShmemTHPMode::deny || _mode == ShmemTHPMode::unknown; +} + +void ShmemTHPSupport::scan_os() { + // Scan /sys/kernel/mm/transparent_hugepage/shmem_enabled + // see mm/huge_memory.c + _mode = ShmemTHPMode::unknown; + const char* filename = "/sys/kernel/mm/transparent_hugepage/shmem_enabled"; + FILE* f = ::fopen(filename, "r"); + if (f != nullptr) { + char buf[64]; + char* s = fgets(buf, sizeof(buf), f); + assert(s == buf, "Should have worked"); + if (::strstr(buf, "[always]") != nullptr) { + _mode = ShmemTHPMode::always; + } else if (::strstr(buf, "[within_size]") != nullptr) { + _mode = ShmemTHPMode::within_size; + } else if (::strstr(buf, "[advise]") != nullptr) { + _mode = ShmemTHPMode::advise; + } else if (::strstr(buf, "[never]") != nullptr) { + _mode = ShmemTHPMode::never; + } else if (::strstr(buf, "[deny]") != nullptr) { + _mode = ShmemTHPMode::deny; + } else if (::strstr(buf, "[force]") != nullptr) { + _mode = ShmemTHPMode::force; + } else { + assert(false, "Weird content of %s: %s", filename, buf); + } + fclose(f); + } + + _initialized = true; + + LogTarget(Info, pagesize) lt; + if (lt.is_enabled()) { + LogStream ls(lt); + print_on(&ls); + } +} + +const char* ShmemTHPSupport::mode_to_string(ShmemTHPMode mode) { + switch (mode) { + case ShmemTHPMode::always: return "always"; + case ShmemTHPMode::advise: return "advise"; + case ShmemTHPMode::within_size: return "within_size"; + case ShmemTHPMode::never: return "never"; + case ShmemTHPMode::deny: return "deny"; + case ShmemTHPMode::force: return "force"; + case ShmemTHPMode::unknown: // Fallthrough + default: return "unknown"; + }; +} + +void ShmemTHPSupport::print_on(outputStream* os) { + if (_initialized) { + os->print_cr("Shared memory transparent hugepage (THP) support:"); + os->print_cr(" Shared memory THP mode: %s", mode_to_string(_mode)); + } else { + os->print_cr(" unknown."); + } +} + StaticHugePageSupport HugePages::_static_hugepage_support; THPSupport HugePages::_thp_support; +ShmemTHPSupport HugePages::_shmem_thp_support; void HugePages::initialize() { _static_hugepage_support.scan_os(); _thp_support.scan_os(); + _shmem_thp_support.scan_os(); } void HugePages::print_on(outputStream* os) { _static_hugepage_support.print_on(os); _thp_support.print_on(os); + _shmem_thp_support.print_on(os); } diff --git a/src/hotspot/os/linux/hugepages.hpp b/src/hotspot/os/linux/hugepages.hpp index cb7c992d78950..ce9ab36edccf8 100644 --- a/src/hotspot/os/linux/hugepages.hpp +++ b/src/hotspot/os/linux/hugepages.hpp @@ -91,23 +91,58 @@ class THPSupport { void print_on(outputStream* os); }; +enum class ShmemTHPMode { always, within_size, advise, never, deny, force, unknown }; + +// for transparent shmem hugepages +class ShmemTHPSupport { + bool _initialized; + + // See /sys/kernel/mm/transparent_hugepage/shmem_enabled + ShmemTHPMode _mode; + + static const char* mode_to_string(ShmemTHPMode mode); + +public: + + ShmemTHPSupport(); + + // Queries the OS, fills in object + void scan_os(); + + ShmemTHPMode mode() const; + + bool is_forced() const; + bool is_enabled() const; + bool is_disabled() const; + + // Printing + void print_on(outputStream* os); +}; + // Umbrella static interface class HugePages : public AllStatic { static StaticHugePageSupport _static_hugepage_support; static THPSupport _thp_support; + static ShmemTHPSupport _shmem_thp_support; public: static const StaticHugePageSupport& static_info() { return _static_hugepage_support; } static const THPSupport& thp_info() { return _thp_support; } + static const ShmemTHPSupport& shmem_thp_info() { return _shmem_thp_support; } static size_t default_static_hugepage_size() { return _static_hugepage_support.default_hugepage_size(); } static bool supports_static_hugepages() { return default_static_hugepage_size() > 0 && !_static_hugepage_support.inconsistent(); } - static THPMode thp_mode() { return _thp_support.mode(); } + static bool supports_thp() { return thp_mode() == THPMode::madvise || thp_mode() == THPMode::always; } + static THPMode thp_mode() { return _thp_support.mode(); } static size_t thp_pagesize() { return _thp_support.pagesize(); } + static bool supports_shmem_thp() { return _shmem_thp_support.is_enabled(); } + static ShmemTHPMode shmem_thp_mode() { return _shmem_thp_support.mode(); } + static bool forced_shmem_thp() { return _shmem_thp_support.is_forced(); } + static void initialize(); static void print_on(outputStream* os); }; diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 7bde97de9077f..3fc025e510085 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -176,6 +176,8 @@ bool os::Linux::_supports_fast_thread_cpu_time = false; const char * os::Linux::_libc_version = nullptr; const char * os::Linux::_libpthread_version = nullptr; +bool os::Linux::_thp_requested{false}; + #ifdef __GLIBC__ // We want to be buildable and runnable on older and newer glibcs, so resolve both // mallinfo and mallinfo2 dynamically. @@ -2213,6 +2215,8 @@ void os::Linux::print_system_memory_info(outputStream* st) { // https://www.kernel.org/doc/Documentation/vm/transhuge.txt _print_ascii_file_h("/sys/kernel/mm/transparent_hugepage/enabled", "/sys/kernel/mm/transparent_hugepage/enabled", st); + _print_ascii_file_h("/sys/kernel/mm/transparent_hugepage/shmem_enabled", + "/sys/kernel/mm/transparent_hugepage/shmem_enabled", st); _print_ascii_file_h("/sys/kernel/mm/transparent_hugepage/defrag (defrag/compaction efforts parameter)", "/sys/kernel/mm/transparent_hugepage/defrag", st); } @@ -2909,11 +2913,15 @@ void os::pd_commit_memory_or_exit(char* addr, size_t size, } } +void os::Linux::madvise_transparent_huge_pages(void* addr, size_t bytes) { + // We don't check the return value: madvise(MADV_HUGEPAGE) may not + // be supported or the memory may already be backed by huge pages. + ::madvise(addr, bytes, MADV_HUGEPAGE); +} + void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { - if (UseTransparentHugePages && alignment_hint > vm_page_size()) { - // We don't check the return value: madvise(MADV_HUGEPAGE) may not - // be supported or the memory may already be backed by huge pages. - ::madvise(addr, bytes, MADV_HUGEPAGE); + if (Linux::should_madvise_anonymous_thps() && alignment_hint > vm_page_size()) { + Linux::madvise_transparent_huge_pages(addr, bytes); } } @@ -3730,7 +3738,7 @@ static void set_coredump_filter(CoredumpFilterBit bit) { static size_t _large_page_size = 0; -void warn_no_large_pages_configured() { +static void warn_no_large_pages_configured() { if (!FLAG_IS_DEFAULT(UseLargePages)) { log_warning(pagesize)("UseLargePages disabled, no large pages configured and available on the system."); } @@ -3747,15 +3755,56 @@ struct LargePageInitializationLoggerMark { os::page_sizes().print_on(&ls); ls.print_cr(". Default large page size: " EXACTFMT ".", EXACTFMTARGS(os::large_page_size())); } else { - ls.print("Large page support disabled."); + ls.print("Large page support %sdisabled.", uses_zgc_shmem_thp() ? "partially " : ""); } } } + + static bool uses_zgc_shmem_thp() { + return UseZGC && + // If user requested THP + ((os::Linux::thp_requested() && HugePages::supports_shmem_thp()) || + // If OS forced THP + HugePages::forced_shmem_thp()); + } }; +static bool validate_thps_configured() { + assert(UseTransparentHugePages, "Sanity"); + assert(os::Linux::thp_requested(), "Sanity"); + + if (UseZGC) { + if (!HugePages::supports_shmem_thp()) { + log_warning(pagesize)("Shared memory transparent huge pages are not enabled in the OS. " + "Set /sys/kernel/mm/transparent_hugepage/shmem_enabled to 'advise' to enable them."); + // UseTransparentHugePages has historically been tightly coupled with + // anonymous THPs. Fall through here and let the validity be determined + // by the OS configuration for anonymous THPs. ZGC doesn't use the flag + // but instead checks os::Linux::thp_requested(). + } + } + + if (!HugePages::supports_thp()) { + log_warning(pagesize)("Anonymous transparent huge pages are not enabled in the OS. " + "Set /sys/kernel/mm/transparent_hugepage/enabled to 'madvise' to enable them."); + log_warning(pagesize)("UseTransparentHugePages disabled, transparent huge pages are not supported by the operating system."); + return false; + } + + return true; +} + void os::large_page_init() { + Linux::large_page_init(); +} + +void os::Linux::large_page_init() { LargePageInitializationLoggerMark logger; + // Decide if the user asked for THPs before we update UseTransparentHugePages. + const bool large_pages_turned_off = !FLAG_IS_DEFAULT(UseLargePages) && !UseLargePages; + _thp_requested = UseTransparentHugePages && !large_pages_turned_off; + // Query OS information first. HugePages::initialize(); @@ -3774,7 +3823,7 @@ void os::large_page_init() { FLAG_SET_ERGO(THPStackMitigation, false); // Mitigation not needed } - // 1) Handle the case where we do not want to use huge pages + // Handle the case where we do not want to use huge pages if (!UseLargePages && !UseTransparentHugePages) { // Not using large pages. @@ -3787,17 +3836,16 @@ void os::large_page_init() { return; } - // 2) check if the OS supports THPs resp. static hugepages. - if (UseTransparentHugePages && !HugePages::supports_thp()) { - if (!FLAG_IS_DEFAULT(UseTransparentHugePages)) { - log_warning(pagesize)("UseTransparentHugePages disabled, transparent huge pages are not supported by the operating system."); - } + // Check if the OS supports THPs + if (UseTransparentHugePages && !validate_thps_configured()) { UseLargePages = UseTransparentHugePages = false; return; } + + // Check if the OS supports static hugepages. if (!UseTransparentHugePages && !HugePages::supports_static_hugepages()) { warn_no_large_pages_configured(); - UseLargePages = UseTransparentHugePages = false; + UseLargePages = false; return; } @@ -3805,7 +3853,7 @@ void os::large_page_init() { // In THP mode: // - os::large_page_size() is the *THP page size* // - os::pagesizes() has two members, the THP page size and the system page size - assert(HugePages::supports_thp() && HugePages::thp_pagesize() > 0, "Missing OS info"); + assert(HugePages::thp_pagesize() > 0, "Missing OS info"); _large_page_size = HugePages::thp_pagesize(); _page_sizes.add(_large_page_size); _page_sizes.add(os::vm_page_size()); @@ -3830,12 +3878,12 @@ void os::large_page_init() { // doesn't match an available page size set _large_page_size to default_large_page_size // and use it as the maximum. if (FLAG_IS_DEFAULT(LargePageSizeInBytes) || - LargePageSizeInBytes == 0 || - LargePageSizeInBytes == default_large_page_size) { - large_page_size = default_large_page_size; - log_info(pagesize)("Using the default large page size: " SIZE_FORMAT "%s", - byte_size_in_exact_unit(large_page_size), - exact_unit_for_byte_size(large_page_size)); + LargePageSizeInBytes == 0 || + LargePageSizeInBytes == default_large_page_size) { + large_page_size = default_large_page_size; + log_info(pagesize)("Using the default large page size: " SIZE_FORMAT "%s", + byte_size_in_exact_unit(large_page_size), + exact_unit_for_byte_size(large_page_size)); } else { if (all_large_pages.contains(LargePageSizeInBytes)) { large_page_size = LargePageSizeInBytes; @@ -3860,7 +3908,6 @@ void os::large_page_init() { if (!hugetlbfs_sanity_check(large_page_size)) { warn_no_large_pages_configured(); UseLargePages = false; - UseTransparentHugePages = false; return; } @@ -3877,6 +3924,18 @@ void os::large_page_init() { set_coredump_filter(LARGEPAGES_BIT); } +bool os::Linux::thp_requested() { + return _thp_requested; +} + +bool os::Linux::should_madvise_anonymous_thps() { + return _thp_requested && HugePages::thp_mode() == THPMode::madvise; +} + +bool os::Linux::should_madvise_shmem_thps() { + return _thp_requested && HugePages::shmem_thp_mode() == ShmemTHPMode::advise; +} + static void log_on_commit_special_failure(char* req_addr, size_t bytes, size_t page_size, int error) { assert(error == ENOMEM, "Only expect to fail if no memory is available"); @@ -3891,7 +3950,8 @@ static bool commit_memory_special(size_t bytes, size_t page_size, char* req_addr, bool exec) { - assert(UseLargePages && !UseTransparentHugePages, "Should only get here for static hugepage mode (+UseLargePages)"); + assert(UseLargePages, "Should only get here for huge pages"); + assert(!UseTransparentHugePages, "Should only get here for static hugepage mode"); assert(is_aligned(bytes, page_size), "Unaligned size"); assert(is_aligned(req_addr, page_size), "Unaligned address"); assert(req_addr != nullptr, "Must have a requested address for special mappings"); diff --git a/src/hotspot/os/linux/os_linux.hpp b/src/hotspot/os/linux/os_linux.hpp index e8f6f486489d7..4b2ccf8e370db 100644 --- a/src/hotspot/os/linux/os_linux.hpp +++ b/src/hotspot/os/linux/os_linux.hpp @@ -175,6 +175,17 @@ class os::Linux { // fields will contain -1. static bool query_process_memory_info(meminfo_t* info); + // Tells if the user asked for transparent huge pages. + static bool _thp_requested; + + static void large_page_init(); + + static bool thp_requested(); + static bool should_madvise_anonymous_thps(); + static bool should_madvise_shmem_thps(); + + static void madvise_transparent_huge_pages(void* addr, size_t bytes); + // Stack repair handling // none present diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 1b75693b138a9..960fb465590cc 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -343,9 +343,10 @@ char* os::replace_existing_mapping_with_file_mapping(char* base, size_t size, in } static size_t calculate_aligned_extra_size(size_t size, size_t alignment) { - assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, + assert(is_aligned(alignment, os::vm_allocation_granularity()), "Alignment must be a multiple of allocation granularity (page size)"); - assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); + assert(is_aligned(size, os::vm_allocation_granularity()), + "Size must be a multiple of allocation granularity (page size)"); size_t extra_size = size + alignment; assert(extra_size >= size, "overflow, size is too large to allow alignment"); diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 56301fe2e8792..223bc0bd13514 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -3331,9 +3331,10 @@ char* os::replace_existing_mapping_with_file_mapping(char* base, size_t size, in // virtual space to get requested alignment, like posix-like os's. // Windows prevents multiple thread from remapping over each other so this loop is thread-safe. static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int file_desc) { - assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, - "Alignment must be a multiple of allocation granularity (page size)"); - assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); + assert(is_aligned(alignment, os::vm_allocation_granularity()), + "Alignment must be a multiple of allocation granularity (page size)"); + assert(is_aligned(size, os::vm_allocation_granularity()), + "Size must be a multiple of allocation granularity (page size)"); size_t extra_size = size + alignment; assert(extra_size >= size, "overflow, size is too large to allow alignment"); diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp index 82c48ab171f04..edf6f29478c4d 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp @@ -2517,6 +2517,8 @@ XHandlers* GraphBuilder::handle_exception(Instruction* instruction) { // xhandler start with an empty expression stack if (cur_state->stack_size() != 0) { + // locals are preserved + // stack will be truncated cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci()); } if (instruction->exception_state() == nullptr) { @@ -2566,15 +2568,19 @@ XHandlers* GraphBuilder::handle_exception(Instruction* instruction) { // This scope and all callees do not handle exceptions, so the local // variables of this scope are not needed. However, the scope itself is // required for a correct exception stack trace -> clear out the locals. - if (_compilation->env()->should_retain_local_variables()) { - cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci()); - } else { - cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci()); - } + // Stack and locals are invalidated but not truncated in caller state. if (prev_state != nullptr) { + assert(instruction->exception_state() != nullptr, "missed set?"); + ValueStack::Kind exc_kind = ValueStack::empty_exception_kind(true /* caller */); + cur_state = cur_state->copy(exc_kind, cur_state->bci()); + // reset caller exception state prev_state->set_caller_state(cur_state); - } - if (instruction->exception_state() == nullptr) { + } else { + assert(instruction->exception_state() == nullptr, "already set"); + // set instruction exception state + // truncate stack + ValueStack::Kind exc_kind = ValueStack::empty_exception_kind(); + cur_state = cur_state->copy(exc_kind, cur_state->bci()); instruction->set_exception_state(cur_state); } } @@ -3487,11 +3493,9 @@ ValueStack* GraphBuilder::copy_state_exhandling_with_bci(int bci) { ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) { ValueStack* s = copy_state_exhandling_with_bci(bci); if (s == nullptr) { - if (_compilation->env()->should_retain_local_variables()) { - s = state()->copy(ValueStack::ExceptionState, bci); - } else { - s = state()->copy(ValueStack::EmptyExceptionState, bci); - } + // no handler, no need to retain locals + ValueStack::Kind exc_kind = ValueStack::empty_exception_kind(); + s = state()->copy(exc_kind, bci); } return s; } diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index afa36bde3d3a8..b17bed7e3f200 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp @@ -403,8 +403,20 @@ CodeEmitInfo* LIRGenerator::state_for(Instruction* x, ValueStack* state, bool ig ValueStack* s = state; for_each_state(s) { - if (s->kind() == ValueStack::EmptyExceptionState) { - assert(s->stack_size() == 0 && s->locals_size() == 0 && (s->locks_size() == 0 || s->locks_size() == 1), "state must be empty"); + if (s->kind() == ValueStack::EmptyExceptionState || + s->kind() == ValueStack::CallerEmptyExceptionState) + { +#ifdef ASSERT + int index; + Value value; + for_each_stack_value(s, index, value) { + fatal("state must be empty"); + } + for_each_local_value(s, index, value) { + fatal("state must be empty"); + } +#endif + assert(s->locks_size() == 0 || s->locks_size() == 1, "state must be empty"); continue; } diff --git a/src/hotspot/share/c1/c1_LinearScan.cpp b/src/hotspot/share/c1/c1_LinearScan.cpp index 0634d970c26f7..7e46f9d56034b 100644 --- a/src/hotspot/share/c1/c1_LinearScan.cpp +++ b/src/hotspot/share/c1/c1_LinearScan.cpp @@ -2921,16 +2921,10 @@ IRScopeDebugInfo* LinearScan::compute_debug_info_for_scope(int op_id, IRScope* c assert(locals->length() == pos, "must match"); } - assert(locals->length() == cur_scope->method()->max_locals(), "wrong number of locals"); - assert(locals->length() == cur_state->locals_size(), "wrong number of locals"); - } else if (cur_scope->method()->max_locals() > 0) { - assert(cur_state->kind() == ValueStack::EmptyExceptionState, "should be"); - nof_locals = cur_scope->method()->max_locals(); - locals = new GrowableArray(nof_locals); - for(int i = 0; i < nof_locals; i++) { - locals->append(_illegal_value); - } + assert(locals->length() == nof_locals, "wrong number of locals"); } + assert(nof_locals == cur_scope->method()->max_locals(), "wrong number of locals"); + assert(nof_locals == cur_state->locals_size(), "wrong number of locals"); // describe expression stack int nof_stack = cur_state->stack_size(); @@ -2939,8 +2933,8 @@ IRScopeDebugInfo* LinearScan::compute_debug_info_for_scope(int op_id, IRScope* c int pos = 0; while (pos < nof_stack) { - Value expression = cur_state->stack_at_inc(pos); - append_scope_value(op_id, expression, expressions); + Value expression = cur_state->stack_at(pos); + pos += append_scope_value(op_id, expression, expressions); assert(expressions->length() == pos, "must match"); } diff --git a/src/hotspot/share/c1/c1_ValueStack.cpp b/src/hotspot/share/c1/c1_ValueStack.cpp index 58dc947764a79..e7bf714a3674d 100644 --- a/src/hotspot/share/c1/c1_ValueStack.cpp +++ b/src/hotspot/share/c1/c1_ValueStack.cpp @@ -51,12 +51,32 @@ ValueStack::ValueStack(ValueStack* copy_from, Kind kind, int bci) , _stack(copy_from->stack_size_for_copy(kind)) , _locks(copy_from->locks_size() == 0 ? nullptr : new Values(copy_from->locks_size())) { - assert(kind != EmptyExceptionState || !Compilation::current()->env()->should_retain_local_variables(), "need locals"); - if (kind != EmptyExceptionState) { + switch (kind) { + case EmptyExceptionState: + case CallerEmptyExceptionState: + assert(!Compilation::current()->env()->should_retain_local_variables(), "need locals"); + // set to all nulls, like clear_locals() + for (int i = 0; i < copy_from->locals_size(); ++i) { + _locals.append(nullptr); + } + break; + default: _locals.appendAll(©_from->_locals); } - if (kind != ExceptionState && kind != EmptyExceptionState) { + switch (kind) { + case ExceptionState: + case EmptyExceptionState: + assert(stack_size() == 0, "fix stack_size_for_copy"); + break; + case CallerExceptionState: + case CallerEmptyExceptionState: + // set to all nulls + for (int i = 0; i < copy_from->stack_size(); ++i) { + _stack.append(nullptr); + } + break; + default: _stack.appendAll(©_from->_stack); } @@ -68,10 +88,7 @@ ValueStack::ValueStack(ValueStack* copy_from, Kind kind, int bci) } int ValueStack::locals_size_for_copy(Kind kind) const { - if (kind != EmptyExceptionState) { - return locals_size(); - } - return 0; + return locals_size(); } int ValueStack::stack_size_for_copy(Kind kind) const { @@ -221,10 +238,15 @@ void ValueStack::print() { } else { InstructionPrinter ip; for (int i = 0; i < stack_size();) { + tty->print("stack %d ", i); Value t = stack_at_inc(i); - tty->print("%2d ", i); - tty->print("%c%d ", t->type()->tchar(), t->id()); - ip.print_instr(t); + if (t == nullptr) { + tty->print("null"); + } else { + tty->print("%2d ", i); + tty->print("%c%d ", t->type()->tchar(), t->id()); + ip.print_instr(t); + } tty->cr(); } } @@ -284,7 +306,9 @@ void ValueStack::verify() { int i; for (i = 0; i < stack_size(); i++) { Value v = _stack.at(i); - if (v == nullptr) { + if (kind() == empty_exception_kind(true /* caller */)) { + assert(v == nullptr, "should be empty"); + } else if (v == nullptr) { assert(_stack.at(i - 1)->type()->is_double_word(), "only hi-words are null on stack"); } else if (v->type()->is_double_word()) { assert(_stack.at(i + 1) == nullptr, "hi-word must be null"); @@ -293,7 +317,9 @@ void ValueStack::verify() { for (i = 0; i < locals_size(); i++) { Value v = _locals.at(i); - if (v != nullptr && v->type()->is_double_word()) { + if (kind() == EmptyExceptionState) { + assert(v == nullptr, "should be empty"); + } else if (v != nullptr && v->type()->is_double_word()) { assert(_locals.at(i + 1) == nullptr, "hi-word must be null"); } } diff --git a/src/hotspot/share/c1/c1_ValueStack.hpp b/src/hotspot/share/c1/c1_ValueStack.hpp index b1622b79622b8..74d5c2e3f3c65 100644 --- a/src/hotspot/share/c1/c1_ValueStack.hpp +++ b/src/hotspot/share/c1/c1_ValueStack.hpp @@ -34,8 +34,18 @@ class ValueStack: public CompilationResourceObj { CallerState, // Caller state when inlining StateBefore, // Before before execution of instruction StateAfter, // After execution of instruction - ExceptionState, // Exception handling of instruction - EmptyExceptionState, // Exception handling of instructions not covered by an xhandler + // Exception states for an instruction. + // Dead stack items or locals may be invalidated or cleared/removed. + // Locals are retained if needed for JVMTI. + // "empty" exception states are used when there is no handler, + // and invalidate the locals. + // "leaf" exception states clear the stack. + // "caller" exception states are used for the parent/caller, + // and invalidate the stack. + ExceptionState, // Exception state for leaf with handler, stack cleared + EmptyExceptionState, // Exception state for leaf w/o handler, stack cleared, locals invalidated + CallerExceptionState, // Exception state for parent with handler, stack invalidated + CallerEmptyExceptionState, // Exception state for parent w/o handler, stack+locals invalidated BlockBeginState // State of BlockBegin instruction with phi functions of this block }; @@ -75,10 +85,16 @@ class ValueStack: public CompilationResourceObj { ValueStack* copy(Kind new_kind, int new_bci) { return new ValueStack(this, new_kind, new_bci); } ValueStack* copy_for_parsing() { return new ValueStack(this, Parsing, -99); } + // Used when no exception handler is found + static Kind empty_exception_kind(bool caller = false) { + return Compilation::current()->env()->should_retain_local_variables() ? + (caller ? CallerExceptionState : ExceptionState) : // retain locals + (caller ? CallerEmptyExceptionState : EmptyExceptionState); // clear locals + } + void set_caller_state(ValueStack* s) { - assert(kind() == EmptyExceptionState || - (Compilation::current()->env()->should_retain_local_variables() && kind() == ExceptionState), - "only EmptyExceptionStates can be modified"); + assert(kind() == empty_exception_kind(false) || kind() == empty_exception_kind(true), + "only empty exception states can be modified"); _caller_state = s; } @@ -133,14 +149,14 @@ class ValueStack: public CompilationResourceObj { // stack access Value stack_at(int i) const { Value x = _stack.at(i); - assert(!x->type()->is_double_word() || + assert(x == nullptr || !x->type()->is_double_word() || _stack.at(i + 1) == nullptr, "hi-word of doubleword value must be null"); return x; } Value stack_at_inc(int& i) const { Value x = stack_at(i); - i += x->type()->size(); + i += ((x == nullptr) ? 1 : x->type()->size()); return x; } @@ -260,7 +276,8 @@ class ValueStack: public CompilationResourceObj { int temp_var = state->stack_size(); \ for (index = 0; \ index < temp_var && (value = state->stack_at(index), true); \ - index += value->type()->size()) + index += (value == nullptr ? 1 : value->type()->size())) \ + if (value != nullptr) #define for_each_lock_value(state, index, value) \ diff --git a/src/hotspot/share/c1/c1_globals.hpp b/src/hotspot/share/c1/c1_globals.hpp index 1c22cf16cfe79..4c73d7536b522 100644 --- a/src/hotspot/share/c1/c1_globals.hpp +++ b/src/hotspot/share/c1/c1_globals.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -275,9 +275,11 @@ develop(bool, InstallMethods, true, \ "Install methods at the end of successful compilations") \ \ + /* The compiler assumes, in many places, that methods are at most 1MB. */ \ + /* Therefore, we restrict this flag to at most 1MB. */ \ develop(intx, NMethodSizeLimit, (64*K)*wordSize, \ "Maximum size of a compiled method.") \ - range(0, max_jint) \ + range(0, 1*M) \ \ develop(bool, TraceFPUStack, false, \ "Trace emulation of the FPU stack (intel only)") \ diff --git a/src/hotspot/share/cds/cdsConfig.cpp b/src/hotspot/share/cds/cdsConfig.cpp index 6261321fc1fe0..818b92efe70d9 100644 --- a/src/hotspot/share/cds/cdsConfig.cpp +++ b/src/hotspot/share/cds/cdsConfig.cpp @@ -27,7 +27,12 @@ #include "cds/cdsConfig.hpp" #include "cds/heapShared.hpp" #include "classfile/classLoaderDataShared.hpp" +#include "classfile/moduleEntry.hpp" +#include "include/jvm_io.h" #include "logging/log.hpp" +#include "runtime/arguments.hpp" +#include "runtime/java.hpp" +#include "utilities/defaultStream.hpp" bool CDSConfig::_is_dumping_static_archive = false; bool CDSConfig::_is_dumping_dynamic_archive = false; @@ -38,6 +43,318 @@ bool CDSConfig::_is_dumping_dynamic_archive = false; bool CDSConfig::_dumping_full_module_graph_disabled = false; bool CDSConfig::_loading_full_module_graph_disabled = false; +char* CDSConfig::_default_archive_path = nullptr; +char* CDSConfig::_static_archive_path = nullptr; +char* CDSConfig::_dynamic_archive_path = nullptr; + +void CDSConfig::initialize() { + if (is_dumping_static_archive()) { + if (RequireSharedSpaces) { + warning("Cannot dump shared archive while using shared archive"); + } + UseSharedSpaces = false; + } + + // Initialize shared archive paths which could include both base and dynamic archive paths + // This must be after set_ergonomics_flags() called so flag UseCompressedOops is set properly. + // + // UseSharedSpaces may be disabled if -XX:SharedArchiveFile is invalid. + if (is_dumping_static_archive() || UseSharedSpaces) { + init_shared_archive_paths(); + } +} + +char* CDSConfig::default_archive_path() { + if (_default_archive_path == nullptr) { + char jvm_path[JVM_MAXPATHLEN]; + os::jvm_path(jvm_path, sizeof(jvm_path)); + char *end = strrchr(jvm_path, *os::file_separator()); + if (end != nullptr) *end = '\0'; + size_t jvm_path_len = strlen(jvm_path); + size_t file_sep_len = strlen(os::file_separator()); + const size_t len = jvm_path_len + file_sep_len + 20; + _default_archive_path = NEW_C_HEAP_ARRAY(char, len, mtArguments); + jio_snprintf(_default_archive_path, len, + LP64_ONLY(!UseCompressedOops ? "%s%sclasses_nocoops.jsa":) "%s%sclasses.jsa", + jvm_path, os::file_separator()); + } + return _default_archive_path; +} + +int CDSConfig::num_archives(const char* archive_path) { + if (archive_path == nullptr) { + return 0; + } + int npaths = 1; + char* p = (char*)archive_path; + while (*p != '\0') { + if (*p == os::path_separator()[0]) { + npaths++; + } + p++; + } + return npaths; +} + +void CDSConfig::extract_shared_archive_paths(const char* archive_path, + char** base_archive_path, + char** top_archive_path) { + char* begin_ptr = (char*)archive_path; + char* end_ptr = strchr((char*)archive_path, os::path_separator()[0]); + if (end_ptr == nullptr || end_ptr == begin_ptr) { + vm_exit_during_initialization("Base archive was not specified", archive_path); + } + size_t len = end_ptr - begin_ptr; + char* cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); + strncpy(cur_path, begin_ptr, len); + cur_path[len] = '\0'; + *base_archive_path = cur_path; + + begin_ptr = ++end_ptr; + if (*begin_ptr == '\0') { + vm_exit_during_initialization("Top archive was not specified", archive_path); + } + end_ptr = strchr(begin_ptr, '\0'); + assert(end_ptr != nullptr, "sanity"); + len = end_ptr - begin_ptr; + cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); + strncpy(cur_path, begin_ptr, len + 1); + *top_archive_path = cur_path; +} + +void CDSConfig::init_shared_archive_paths() { + if (ArchiveClassesAtExit != nullptr) { + assert(!RecordDynamicDumpInfo, "already checked"); + if (is_dumping_static_archive()) { + vm_exit_during_initialization("-XX:ArchiveClassesAtExit cannot be used with -Xshare:dump"); + } + check_unsupported_dumping_properties(); + + if (os::same_files(default_archive_path(), ArchiveClassesAtExit)) { + vm_exit_during_initialization( + "Cannot specify the default CDS archive for -XX:ArchiveClassesAtExit", default_archive_path()); + } + } + + if (SharedArchiveFile == nullptr) { + _static_archive_path = default_archive_path(); + } else { + int archives = num_archives(SharedArchiveFile); + assert(archives > 0, "must be"); + + if (is_dumping_archive() && archives > 1) { + vm_exit_during_initialization( + "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping"); + } + + if (is_dumping_static_archive()) { + assert(archives == 1, "must be"); + // Static dump is simple: only one archive is allowed in SharedArchiveFile. This file + // will be overwritten no matter regardless of its contents + _static_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments); + } else { + // SharedArchiveFile may specify one or two files. In case (c), the path for base.jsa + // is read from top.jsa + // (a) 1 file: -XX:SharedArchiveFile=base.jsa + // (b) 2 files: -XX:SharedArchiveFile=base.jsa:top.jsa + // (c) 2 files: -XX:SharedArchiveFile=top.jsa + // + // However, if either RecordDynamicDumpInfo or ArchiveClassesAtExit is used, we do not + // allow cases (b) and (c). Case (b) is already checked above. + + if (archives > 2) { + vm_exit_during_initialization( + "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option"); + } + if (archives == 1) { + char* base_archive_path = nullptr; + bool success = + FileMapInfo::get_base_archive_name_from_header(SharedArchiveFile, &base_archive_path); + if (!success) { + // If +AutoCreateSharedArchive and the specified shared archive does not exist, + // regenerate the dynamic archive base on default archive. + if (AutoCreateSharedArchive && !os::file_exists(SharedArchiveFile)) { + enable_dumping_dynamic_archive(); + ArchiveClassesAtExit = const_cast(SharedArchiveFile); + _static_archive_path = default_archive_path(); + SharedArchiveFile = nullptr; + } else { + if (AutoCreateSharedArchive) { + warning("-XX:+AutoCreateSharedArchive is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info."); + AutoCreateSharedArchive = false; + } + Arguments::no_shared_spaces("invalid archive"); + } + } else if (base_archive_path == nullptr) { + // User has specified a single archive, which is a static archive. + _static_archive_path = const_cast(SharedArchiveFile); + } else { + // User has specified a single archive, which is a dynamic archive. + _dynamic_archive_path = const_cast(SharedArchiveFile); + _static_archive_path = base_archive_path; // has been c-heap allocated. + } + } else { + extract_shared_archive_paths((const char*)SharedArchiveFile, + &_static_archive_path, &_dynamic_archive_path); + if (_static_archive_path == nullptr) { + assert(_dynamic_archive_path == nullptr, "must be"); + Arguments::no_shared_spaces("invalid archive"); + } + } + + if (_dynamic_archive_path != nullptr) { + // Check for case (c) + if (RecordDynamicDumpInfo) { + vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile", + SharedArchiveFile); + } + if (ArchiveClassesAtExit != nullptr) { + vm_exit_during_initialization("-XX:ArchiveClassesAtExit is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile", + SharedArchiveFile); + } + } + + if (ArchiveClassesAtExit != nullptr && os::same_files(SharedArchiveFile, ArchiveClassesAtExit)) { + vm_exit_during_initialization( + "Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit", + SharedArchiveFile); + } + } + } +} + +void CDSConfig::check_system_property(const char* key, const char* value) { + if (Arguments::is_internal_module_property(key)) { + MetaspaceShared::disable_optimized_module_handling(); + log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value); + } + if (strcmp(key, "jdk.module.showModuleResolution") == 0 || + strcmp(key, "jdk.module.validation") == 0 || + strcmp(key, "java.system.class.loader") == 0) { + disable_loading_full_module_graph(); + disable_dumping_full_module_graph(); + log_info(cds)("full module graph: disabled due to incompatible property: %s=%s", key, value); + } +} + +static const char* unsupported_properties[] = { + "jdk.module.limitmods", + "jdk.module.upgrade.path", + "jdk.module.patch.0" +}; +static const char* unsupported_options[] = { + "--limit-modules", + "--upgrade-module-path", + "--patch-module" +}; + +void CDSConfig::check_unsupported_dumping_properties() { + assert(is_dumping_archive(), "this function is only used with CDS dump time"); + assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be"); + // If a vm option is found in the unsupported_options array, vm will exit with an error message. + SystemProperty* sp = Arguments::system_properties(); + while (sp != nullptr) { + for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) { + if (strcmp(sp->key(), unsupported_properties[i]) == 0) { + vm_exit_during_initialization( + "Cannot use the following option when dumping the shared archive", unsupported_options[i]); + } + } + sp = sp->next(); + } + + // Check for an exploded module build in use with -Xshare:dump. + if (!Arguments::has_jimage()) { + vm_exit_during_initialization("Dumping the shared archive is not supported with an exploded module build"); + } +} + +bool CDSConfig::check_unsupported_cds_runtime_properties() { + assert(UseSharedSpaces, "this function is only used with -Xshare:{on,auto}"); + assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be"); + if (ArchiveClassesAtExit != nullptr) { + // dynamic dumping, just return false for now. + // check_unsupported_dumping_properties() will be called later to check the same set of + // properties, and will exit the VM with the correct error message if the unsupported properties + // are used. + return false; + } + for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) { + if (Arguments::get_property(unsupported_properties[i]) != nullptr) { + if (RequireSharedSpaces) { + warning("CDS is disabled when the %s option is specified.", unsupported_options[i]); + } else { + log_info(cds)("CDS is disabled when the %s option is specified.", unsupported_options[i]); + } + return true; + } + } + return false; +} + +bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) { + if (is_dumping_static_archive()) { + if (!mode_flag_cmd_line) { + // By default, -Xshare:dump runs in interpreter-only mode, which is required for deterministic archive. + // + // If your classlist is large and you don't care about deterministic dumping, you can use + // -Xshare:dump -Xmixed to improve dumping speed. + Arguments::set_mode_flags(Arguments::_int); + } else if (Arguments::mode() == Arguments::_comp) { + // -Xcomp may use excessive CPU for the test tiers. Also, -Xshare:dump runs a small and fixed set of + // Java code, so there's not much benefit in running -Xcomp. + log_info(cds)("reduced -Xcomp to -Xmixed for static dumping"); + Arguments::set_mode_flags(Arguments::_mixed); + } + + // String deduplication may cause CDS to iterate the strings in different order from one + // run to another which resulting in non-determinstic CDS archives. + // Disable UseStringDeduplication while dumping CDS archive. + UseStringDeduplication = false; + } + + // RecordDynamicDumpInfo is not compatible with ArchiveClassesAtExit + if (ArchiveClassesAtExit != nullptr && RecordDynamicDumpInfo) { + jio_fprintf(defaultStream::output_stream(), + "-XX:+RecordDynamicDumpInfo cannot be used with -XX:ArchiveClassesAtExit.\n"); + return false; + } + + if (ArchiveClassesAtExit == nullptr && !RecordDynamicDumpInfo) { + disable_dumping_dynamic_archive(); + } else { + enable_dumping_dynamic_archive(); + } + + if (AutoCreateSharedArchive) { + if (SharedArchiveFile == nullptr) { + log_warning(cds)("-XX:+AutoCreateSharedArchive requires -XX:SharedArchiveFile"); + return false; + } + if (ArchiveClassesAtExit != nullptr) { + log_warning(cds)("-XX:+AutoCreateSharedArchive does not work with ArchiveClassesAtExit"); + return false; + } + } + + if (UseSharedSpaces && patch_mod_javabase) { + Arguments::no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched."); + } + if (UseSharedSpaces && check_unsupported_cds_runtime_properties()) { + UseSharedSpaces = false; + } + + if (is_dumping_archive()) { + // Always verify non-system classes during CDS dump + if (!BytecodeVerificationRemote) { + BytecodeVerificationRemote = true; + log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time."); + } + } + + return true; +} + #if INCLUDE_CDS_JAVA_HEAP bool CDSConfig::is_dumping_heap() { // heap dump is not supported in dynamic dump diff --git a/src/hotspot/share/cds/cdsConfig.hpp b/src/hotspot/share/cds/cdsConfig.hpp index cc3c5556d0abe..ec5352b370394 100644 --- a/src/hotspot/share/cds/cdsConfig.hpp +++ b/src/hotspot/share/cds/cdsConfig.hpp @@ -26,6 +26,7 @@ #define SHARE_CDS_CDSCONFIG_HPP #include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" class CDSConfig : public AllStatic { @@ -34,9 +35,25 @@ class CDSConfig : public AllStatic { static bool _is_dumping_dynamic_archive; static bool _dumping_full_module_graph_disabled; static bool _loading_full_module_graph_disabled; + + static char* _default_archive_path; + static char* _static_archive_path; + static char* _dynamic_archive_path; #endif + static void extract_shared_archive_paths(const char* archive_path, + char** base_archive_path, + char** top_archive_path); + static void init_shared_archive_paths(); + static bool check_unsupported_cds_runtime_properties(); + public: + // Initialization and command-line checking + static void initialize() NOT_CDS_RETURN; + static void check_system_property(const char* key, const char* value) NOT_CDS_RETURN; + static void check_unsupported_dumping_properties() NOT_CDS_RETURN; + static bool check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) NOT_CDS_RETURN_(true); + // Basic CDS features static bool is_dumping_archive() { return is_dumping_static_archive() || is_dumping_dynamic_archive(); } static bool is_dumping_static_archive() { return CDS_ONLY(_is_dumping_static_archive) NOT_CDS(false); } @@ -45,6 +62,17 @@ class CDSConfig : public AllStatic { static void enable_dumping_dynamic_archive() { CDS_ONLY(_is_dumping_dynamic_archive = true); } static void disable_dumping_dynamic_archive() { CDS_ONLY(_is_dumping_dynamic_archive = false); } + // Archive paths + // Points to the classes.jsa in $JAVA_HOME + static char* default_archive_path() NOT_CDS_RETURN_(nullptr); + // The actual static archive (if any) selected at runtime + static const char* static_archive_path() { return CDS_ONLY(_static_archive_path) NOT_CDS(nullptr); } + // The actual dynamic archive (if any) selected at runtime + static const char* dynamic_archive_path() { return CDS_ONLY(_dynamic_archive_path) NOT_CDS(nullptr); } + + static int num_archives(const char* archive_path) NOT_CDS_RETURN_(0); + + // CDS archived heap static bool is_dumping_heap() NOT_CDS_JAVA_HEAP_RETURN_(false); static void disable_dumping_full_module_graph(const char* reason = nullptr) NOT_CDS_JAVA_HEAP_RETURN; diff --git a/src/hotspot/share/cds/cdsHeapVerifier.cpp b/src/hotspot/share/cds/cdsHeapVerifier.cpp index b687ad566b399..767454260d2c8 100644 --- a/src/hotspot/share/cds/cdsHeapVerifier.cpp +++ b/src/hotspot/share/cds/cdsHeapVerifier.cpp @@ -129,7 +129,23 @@ CDSHeapVerifier::CDSHeapVerifier() : _archived_objs(0), _problems(0) // This just points to an empty Map ADD_EXCL("jdk/internal/reflect/Reflection", "methodFilterMap"); // E ADD_EXCL("jdk/internal/util/StaticProperty", "FILE_ENCODING", // C - "JAVA_LOCALE_USE_OLD_ISO_CODES"); // C + "JAVA_LOCALE_USE_OLD_ISO_CODES", // C + "USER_LANGUAGE", // C + "USER_LANGUAGE_DISPLAY", // C + "USER_LANGUAGE_FORMAT", // C + "USER_SCRIPT", // C + "USER_SCRIPT_DISPLAY", // C + "USER_SCRIPT_FORMAT", // C + "USER_COUNTRY", // C + "USER_COUNTRY_DISPLAY", // C + "USER_COUNTRY_FORMAT", // C + "USER_VARIANT", // C + "USER_VARIANT_DISPLAY", // C + "USER_VARIANT_FORMAT", // C + "USER_EXTENSIONS", // C + "USER_EXTENSIONS_DISPLAY", // C + "USER_EXTENSIONS_FORMAT", // C + "USER_REGION"); // C // Integer for 0 and 1 are in java/lang/Integer$IntegerCache and are archived ADD_EXCL("sun/invoke/util/ValueConversions", "ONE_INT", // E diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 951077dcd46cd..3b50e01479718 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -162,8 +162,8 @@ void FileMapInfo::populate_header(size_t core_region_alignment) { c_header_size = sizeof(DynamicArchiveHeader); header_size = c_header_size; - const char* default_base_archive_name = Arguments::get_default_shared_archive_path(); - const char* current_base_archive_name = Arguments::GetSharedArchivePath(); + const char* default_base_archive_name = CDSConfig::default_archive_path(); + const char* current_base_archive_name = CDSConfig::static_archive_path(); if (!os::same_files(current_base_archive_name, default_base_archive_name)) { base_archive_name_size = strlen(current_base_archive_name) + 1; header_size += base_archive_name_size; @@ -199,7 +199,7 @@ void FileMapHeader::populate(FileMapInfo *info, size_t core_region_alignment, if (!info->is_static() && base_archive_name_size != 0) { // copy base archive name - copy_base_archive_name(Arguments::GetSharedArchivePath()); + copy_base_archive_name(CDSConfig::static_archive_path()); } _core_region_alignment = core_region_alignment; _obj_alignment = ObjectAlignmentInBytes; @@ -397,23 +397,25 @@ bool SharedClassPathEntry::validate(bool is_class_path) const { log_warning(cds)("directory is not empty: %s", name); ok = false; } - } else if ((has_timestamp() && _timestamp != st.st_mtime) || - _filesize != st.st_size) { - ok = false; - if (PrintSharedArchiveAndExit) { - log_warning(cds)(_timestamp != st.st_mtime ? - "Timestamp mismatch" : - "File size mismatch"); - } else { - const char* bad_jar_msg = "A jar file is not the one used while building the shared archive file:"; - log_warning(cds)("%s %s", bad_jar_msg, name); - if (!log_is_enabled(Info, cds)) { - log_warning(cds)("%s %s", bad_jar_msg, name); - } - if (_timestamp != st.st_mtime) { - log_warning(cds)("%s timestamp has changed.", name); + } else { + bool size_differs = _filesize != st.st_size; + bool time_differs = has_timestamp() && _timestamp != st.st_mtime; + if (time_differs || size_differs) { + ok = false; + if (PrintSharedArchiveAndExit) { + log_warning(cds)(time_differs ? "Timestamp mismatch" : "File size mismatch"); } else { - log_warning(cds)("%s size has changed.", name); + const char* bad_file_msg = "This file is not the one used while building the shared archive file:"; + log_warning(cds)("%s %s", bad_file_msg, name); + if (!log_is_enabled(Info, cds)) { + log_warning(cds)("%s %s", bad_file_msg, name); + } + if (time_differs) { + log_warning(cds)("%s timestamp has changed.", name); + } + if (size_differs) { + log_warning(cds)("%s size has changed.", name); + } } } } @@ -916,7 +918,7 @@ void FileMapInfo::log_paths(const char* msg, int start_idx, int end_idx) { bool FileMapInfo::check_module_paths() { const char* rp = Arguments::get_property("jdk.module.path"); - int num_paths = Arguments::num_archives(rp); + int num_paths = CDSConfig::num_archives(rp); if (num_paths != header()->num_module_paths()) { return false; } @@ -1248,7 +1250,7 @@ bool FileMapInfo::get_base_archive_name_from_header(const char* archive_name, const char* base = file_helper.base_archive_name(); if (base == nullptr) { - *base_archive_name = Arguments::get_default_shared_archive_path(); + *base_archive_name = CDSConfig::default_archive_path(); } else { *base_archive_name = os::strdup_check_oom(base); } @@ -1463,7 +1465,7 @@ BitMapView FileMapRegion::ptrmap_view() { return bitmap_view(false); } -bool FileMapRegion::check_region_crc() const { +bool FileMapRegion::check_region_crc(char* base) const { // This function should be called after the region has been properly // loaded into memory via FileMapInfo::map_region() or FileMapInfo::read_region(). // I.e., this->mapped_base() must be valid. @@ -1472,8 +1474,8 @@ bool FileMapRegion::check_region_crc() const { return true; } - assert(mapped_base() != nullptr, "must be initialized"); - int crc = ClassLoader::crc32(0, mapped_base(), (jint)sz); + assert(base != nullptr, "must be initialized"); + int crc = ClassLoader::crc32(0, base, (jint)sz); if (crc != this->crc()) { log_warning(cds)("Checksum verification failed."); return false; @@ -1758,13 +1760,13 @@ bool FileMapInfo::read_region(int i, char* base, size_t size, bool do_commit) { return false; } - r->set_mapped_from_file(false); - r->set_mapped_base(base); - - if (VerifySharedSpaces && !r->check_region_crc()) { + if (VerifySharedSpaces && !r->check_region_crc(base)) { return false; } + r->set_mapped_from_file(false); + r->set_mapped_base(base); + return true; } @@ -1801,6 +1803,7 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba return MAP_ARCHIVE_OTHER_FAILURE; // oom or I/O error. } else { assert(r->mapped_base() != nullptr, "must be initialized"); + return MAP_ARCHIVE_SUCCESS; } } else { // Note that this may either be a "fresh" mapping into unreserved address @@ -1815,15 +1818,16 @@ MapArchiveResult FileMapInfo::map_region(int i, intx addr_delta, char* mapped_ba _memory_mapping_failed = true; return MAP_ARCHIVE_MMAP_FAILURE; } + + if (VerifySharedSpaces && !r->check_region_crc(requested_addr)) { + return MAP_ARCHIVE_OTHER_FAILURE; + } + r->set_mapped_from_file(true); r->set_mapped_base(requested_addr); - } - if (VerifySharedSpaces && !r->check_region_crc()) { - return MAP_ARCHIVE_OTHER_FAILURE; + return MAP_ARCHIVE_SUCCESS; } - - return MAP_ARCHIVE_SUCCESS; } // The return value is the location of the archive relocation bitmap. @@ -1841,8 +1845,7 @@ char* FileMapInfo::map_bitmap_region() { return nullptr; } - r->set_mapped_base(bitmap_base); - if (VerifySharedSpaces && !r->check_region_crc()) { + if (VerifySharedSpaces && !r->check_region_crc(bitmap_base)) { log_error(cds)("relocation bitmap CRC error"); if (!os::unmap_memory(bitmap_base, r->used_aligned())) { fatal("os::unmap_memory of relocation bitmap failed"); @@ -1851,6 +1854,7 @@ char* FileMapInfo::map_bitmap_region() { } r->set_mapped_from_file(true); + r->set_mapped_base(bitmap_base); log_info(cds)("Mapped %s region #%d at base " INTPTR_FORMAT " top " INTPTR_FORMAT " (%s)", is_static() ? "static " : "dynamic", MetaspaceShared::bm, p2i(r->mapped_base()), p2i(r->mapped_end()), @@ -2126,13 +2130,14 @@ bool FileMapInfo::map_heap_region_impl() { return false; } - r->set_mapped_base(base); - if (VerifySharedSpaces && !r->check_region_crc()) { + if (VerifySharedSpaces && !r->check_region_crc(base)) { dealloc_heap_region(); log_info(cds)("UseSharedSpaces: mapped heap region is corrupt"); return false; } + r->set_mapped_base(base); + // If the requested range is different from the range allocated by GC, then // the pointers need to be patched. address mapped_start = (address) _mapped_heap_memregion.start(); @@ -2273,7 +2278,7 @@ bool FileMapInfo::initialize() { log_info(cds)("Initialize dynamic archive failed."); if (AutoCreateSharedArchive) { CDSConfig::enable_dumping_dynamic_archive(); - ArchiveClassesAtExit = Arguments::GetSharedDynamicArchivePath(); + ArchiveClassesAtExit = CDSConfig::dynamic_archive_path(); } return false; } diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp index 7ad7b62b7605f..3d2062093c6b7 100644 --- a/src/hotspot/share/cds/filemap.hpp +++ b/src/hotspot/share/cds/filemap.hpp @@ -170,7 +170,7 @@ class FileMapRegion: private CDSFileMapRegion { BitMapView ptrmap_view(); bool has_ptrmap() { return _ptrmap_size_in_bits != 0; } - bool check_region_crc() const; + bool check_region_crc(char* base) const; void print(outputStream* st, int region_index); }; diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index b73048a9bf58e..fedbc5841b682 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -539,7 +539,7 @@ void VM_PopulateDumpSharedSpace::doit() { builder.relocate_to_requested(); // Write the archive file - const char* static_archive = Arguments::GetSharedArchivePath(); + const char* static_archive = CDSConfig::static_archive_path(); assert(static_archive != nullptr, "SharedArchiveFile not set?"); FileMapInfo* mapinfo = new FileMapInfo(static_archive, true); mapinfo->populate_header(MetaspaceShared::core_region_alignment()); @@ -651,8 +651,7 @@ void MetaspaceShared::link_shared_classes(bool jcmd_request, TRAPS) { void MetaspaceShared::prepare_for_dumping() { assert(CDSConfig::is_dumping_archive(), "sanity"); - Arguments::check_unsupported_dumping_properties(); - + CDSConfig::check_unsupported_dumping_properties(); ClassLoader::initialize_shared_path(JavaThread::current()); } @@ -783,7 +782,6 @@ void MetaspaceShared::preload_and_dump_impl(TRAPS) { #if INCLUDE_CDS_JAVA_HEAP if (CDSConfig::is_dumping_heap()) { - StringTable::allocate_shared_strings_array(CHECK); if (!HeapShared::is_archived_boot_layer_available(THREAD)) { log_info(cds)("archivedBootLayer not available, disabling full module graph"); CDSConfig::disable_dumping_full_module_graph(); @@ -793,6 +791,10 @@ void MetaspaceShared::preload_and_dump_impl(TRAPS) { if (CDSConfig::is_dumping_full_module_graph()) { HeapShared::reset_archived_object_states(CHECK); } + + // Do this at the very end, when no Java code will be executed. Otherwise + // some new strings may be added to the intern table. + StringTable::allocate_shared_strings_array(CHECK); } #endif @@ -984,8 +986,8 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { } FileMapInfo* MetaspaceShared::open_static_archive() { - const char* static_archive = Arguments::GetSharedArchivePath(); - assert(static_archive != nullptr, "SharedArchivePath is nullptr"); + const char* static_archive = CDSConfig::static_archive_path(); + assert(static_archive != nullptr, "sanity"); FileMapInfo* mapinfo = new FileMapInfo(static_archive, true); if (!mapinfo->initialize()) { delete(mapinfo); @@ -998,7 +1000,7 @@ FileMapInfo* MetaspaceShared::open_dynamic_archive() { if (CDSConfig::is_dumping_dynamic_archive()) { return nullptr; } - const char* dynamic_archive = Arguments::GetSharedDynamicArchivePath(); + const char* dynamic_archive = CDSConfig::dynamic_archive_path(); if (dynamic_archive == nullptr) { return nullptr; } @@ -1331,11 +1333,11 @@ char* MetaspaceShared::reserve_address_space_for_archives(FileMapInfo* static_ma os::vm_page_size(), (char*) base_address); } else { // We did not manage to reserve at the preferred address, or were instructed to relocate. In that - // case we reserve whereever possible, but the start address needs to be encodable as narrow Klass - // encoding base since the archived heap objects contain nKlass IDs precalculated toward the start + // case we reserve wherever possible, but the start address needs to be encodable as narrow Klass + // encoding base since the archived heap objects contain nKlass IDs pre-calculated toward the start // of the shared Metaspace. That prevents us from using zero-based encoding and therefore we won't // try allocating in low-address regions. - total_space_rs = Metaspace::reserve_address_space_for_compressed_classes(total_range_size, false /* try_in_low_address_ranges */); + total_space_rs = Metaspace::reserve_address_space_for_compressed_classes(total_range_size, false /* optimize_for_zero_base */); } if (!total_space_rs.is_reserved()) { @@ -1491,7 +1493,7 @@ void MetaspaceShared::initialize_shared_spaces() { if (PrintSharedArchiveAndExit) { // Print archive names if (dynamic_mapinfo != nullptr) { - tty->print_cr("\n\nBase archive name: %s", Arguments::GetSharedArchivePath()); + tty->print_cr("\n\nBase archive name: %s", CDSConfig::static_archive_path()); tty->print_cr("Base archive version %d", static_mapinfo->version()); } else { tty->print_cr("Static archive name: %s", static_mapinfo->full_path()); diff --git a/src/hotspot/share/ci/ciMethod.hpp b/src/hotspot/share/ci/ciMethod.hpp index b8d7a21ef4ced..0c171d0cf0b7c 100644 --- a/src/hotspot/share/ci/ciMethod.hpp +++ b/src/hotspot/share/ci/ciMethod.hpp @@ -200,6 +200,7 @@ class ciMethod : public ciMetadata { bool intrinsic_candidate() const { return get_Method()->intrinsic_candidate(); } bool is_static_initializer() const { return get_Method()->is_static_initializer(); } bool changes_current_thread() const { return get_Method()->changes_current_thread(); } + bool deprecated() const { return is_loaded() && get_Method()->deprecated(); } bool check_intrinsic_candidate() const { if (intrinsic_id() == vmIntrinsics::_blackhole) { diff --git a/src/hotspot/share/ci/ciMethodData.cpp b/src/hotspot/share/ci/ciMethodData.cpp index 8d1772f655fa9..dc7082c15ca9d 100644 --- a/src/hotspot/share/ci/ciMethodData.cpp +++ b/src/hotspot/share/ci/ciMethodData.cpp @@ -474,6 +474,7 @@ ciBitData ciMethodData::exception_handler_bci_to_data(int bci) { } // called with invalid bci or wrong Method/MethodData ShouldNotReachHere(); + return ciBitData(nullptr); } // Conservatively decode the trap_state of a ciProfileData. diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index a7447211a1c43..a0762e5b4473a 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -149,6 +149,8 @@ #define JAVA_22_VERSION 66 +#define JAVA_23_VERSION 67 + void ClassFileParser::set_class_bad_constant_seen(short bad_constant) { assert((bad_constant == JVM_CONSTANT_Module || bad_constant == JVM_CONSTANT_Package) && _major_version >= JAVA_9_VERSION, @@ -951,6 +953,8 @@ class AnnotationCollector : public ResourceObj{ _field_Stable, _jdk_internal_vm_annotation_ReservedStackAccess, _jdk_internal_ValueBased, + _java_lang_Deprecated, + _java_lang_Deprecated_for_removal, _annotation_LIMIT }; const Location _location; @@ -1122,6 +1126,7 @@ static void parse_annotations(const ConstantPool* const cp, s_tag_val = 's', // payload is String s_con_off = 7, // utf8 payload, such as 'Ljava/lang/String;' s_size = 9, + b_tag_val = 'Z', // payload is boolean min_size = 6 // smallest possible size (zero members) }; // Cannot add min_size to index in case of overflow MAX_INT @@ -1144,6 +1149,32 @@ static void parse_annotations(const ConstantPool* const cp, AnnotationCollector::ID id = coll->annotation_index(loader_data, aname, can_access_vm_annotations); if (AnnotationCollector::_unknown == id) continue; coll->set_annotation(id); + if (AnnotationCollector::_java_lang_Deprecated == id) { + assert(count <= 2, "change this if more element-value pairs are added to the @Deprecated annotation"); + // @Deprecated can specify forRemoval=true + const u1* offset = abase + member_off; + for (int i = 0; i < count; ++i) { + int member_index = Bytes::get_Java_u2((address)offset); + offset += 2; + member = check_symbol_at(cp, member_index); + if (member == vmSymbols::since()) { + assert(*((address)offset) == s_tag_val, "invariant"); + offset += 3; + continue; + } + if (member == vmSymbols::for_removal()) { + assert(*((address)offset) == b_tag_val, "invariant"); + const u2 boolean_value_index = Bytes::get_Java_u2((address)offset + 1); + if (cp->int_at(boolean_value_index) == 1) { + // forRemoval == true + coll->set_annotation(AnnotationCollector::_java_lang_Deprecated_for_removal); + } + break; + } + + } + continue; + } if (AnnotationCollector::_jdk_internal_vm_annotation_Contended == id) { // @Contended can optionally specify the contention group. @@ -1959,6 +1990,9 @@ AnnotationCollector::annotation_index(const ClassLoaderData* loader_data, if (!privileged) break; // only allow in privileged code return _jdk_internal_ValueBased; } + case VM_SYMBOL_ENUM_NAME(java_lang_Deprecated): { + return _java_lang_Deprecated; + } default: { break; } @@ -2003,6 +2037,10 @@ void MethodAnnotationCollector::apply_to(const methodHandle& m) { m->set_intrinsic_candidate(); if (has_annotation(_jdk_internal_vm_annotation_ReservedStackAccess)) m->set_has_reserved_stack_access(); + if (has_annotation(_java_lang_Deprecated)) + m->set_deprecated(); + if (has_annotation(_java_lang_Deprecated_for_removal)) + m->set_deprecated_for_removal(); } void ClassFileParser::ClassAnnotationCollector::apply_to(InstanceKlass* ik) { @@ -2016,6 +2054,22 @@ void ClassFileParser::ClassAnnotationCollector::apply_to(InstanceKlass* ik) { ik->set_is_value_based(); } } + if (has_annotation(_java_lang_Deprecated)) { + Array* methods = ik->methods(); + int length = ik->methods()->length(); + for (int i = 0; i < length; i++) { + Method* m = methods->at(i); + m->set_deprecated(); + } + } + if (has_annotation(_java_lang_Deprecated_for_removal)) { + Array* methods = ik->methods(); + int length = ik->methods()->length(); + for (int i = 0; i < length; i++) { + Method* m = methods->at(i); + m->set_deprecated_for_removal(); + } + } } #define MAX_ARGS_SIZE 255 diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp index 47e8569d934ef..d383fff3eb13e 100644 --- a/src/hotspot/share/classfile/classLoaderData.cpp +++ b/src/hotspot/share/classfile/classLoaderData.cpp @@ -599,7 +599,7 @@ void ClassLoaderData::unload() { free_deallocate_list_C_heap_structures(); // Clean up class dependencies and tell serviceability tools - // these classes are unloading. Must be called + // these classes are unloading. This must be called // after erroneous classes are released. classes_do(InstanceKlass::unload_class); diff --git a/src/hotspot/share/classfile/classLoaderData.hpp b/src/hotspot/share/classfile/classLoaderData.hpp index 6b5cfdc0664a2..c9d025aded141 100644 --- a/src/hotspot/share/classfile/classLoaderData.hpp +++ b/src/hotspot/share/classfile/classLoaderData.hpp @@ -186,12 +186,16 @@ class ClassLoaderData : public CHeapObj { ClassLoaderData* next() const; void unlink_next(); - void set_unloading_next(ClassLoaderData* unloading_next); - ClassLoaderData* unloading_next() const; - ClassLoaderData(Handle h_class_loader, bool has_class_mirror_holder); + +public: ~ClassLoaderData(); + void set_unloading_next(ClassLoaderData* unloading_next); + ClassLoaderData* unloading_next() const; + void unload(); + +private: // The CLD are not placed in the Heap, so the Card Table or // the Mod Union Table can't be used to mark when CLD have modified oops. // The CT and MUT bits saves this information for the whole class loader data. @@ -203,11 +207,11 @@ class ClassLoaderData : public CHeapObj { oop holder_no_keepalive() const; oop holder() const; + void classes_do(void f(Klass* const)); + private: - void unload(); bool keep_alive() const { return _keep_alive > 0; } - void classes_do(void f(Klass* const)); void loaded_classes_do(KlassClosure* klass_closure); void classes_do(void f(InstanceKlass*)); void methods_do(void f(Method*)); diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.cpp b/src/hotspot/share/classfile/classLoaderDataGraph.cpp index ded677189295f..2046286651eae 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp @@ -31,6 +31,7 @@ #include "classfile/moduleEntry.hpp" #include "classfile/packageEntry.hpp" #include "code/dependencyContext.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" @@ -124,7 +125,6 @@ void ClassLoaderDataGraph::walk_metadata_and_clean_metaspaces() { // List head of all class loader data. ClassLoaderData* volatile ClassLoaderDataGraph::_head = nullptr; -ClassLoaderData* ClassLoaderDataGraph::_unloading_head = nullptr; bool ClassLoaderDataGraph::_should_clean_deallocate_lists = false; bool ClassLoaderDataGraph::_safepoint_cleanup_needed = false; @@ -342,11 +342,7 @@ void ClassLoaderDataGraph::loaded_classes_do(KlassClosure* klass_closure) { } void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) { - assert_locked_or_safepoint(ClassLoaderDataGraph_lock); - for (ClassLoaderData* cld = _unloading_head; cld != nullptr; cld = cld->unloading_next()) { - assert(cld->is_unloading(), "invariant"); - cld->classes_do(f); - } + ClassUnloadingContext::context()->classes_unloading_do(f); } void ClassLoaderDataGraph::verify_dictionary() { @@ -425,7 +421,8 @@ bool ClassLoaderDataGraph::do_unloading() { } else { // Found dead CLD. loaders_removed++; - data->unload(); + + ClassUnloadingContext::context()->register_unloading_class_loader_data(data); // Move dead CLD to unloading list. if (prev != nullptr) { @@ -435,8 +432,6 @@ bool ClassLoaderDataGraph::do_unloading() { // The GC might be walking this concurrently Atomic::store(&_head, data->next()); } - data->set_unloading_next(_unloading_head); - _unloading_head = data; } } @@ -469,16 +464,9 @@ void ClassLoaderDataGraph::clean_module_and_package_info() { } void ClassLoaderDataGraph::purge(bool at_safepoint) { - ClassLoaderData* list = _unloading_head; - _unloading_head = nullptr; - ClassLoaderData* next = list; - bool classes_unloaded = false; - while (next != nullptr) { - ClassLoaderData* purge_me = next; - next = purge_me->unloading_next(); - delete purge_me; - classes_unloaded = true; - } + ClassUnloadingContext::context()->purge_class_loader_data(); + + bool classes_unloaded = ClassUnloadingContext::context()->has_unloaded_classes(); Metaspace::purge(classes_unloaded); if (classes_unloaded) { diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.hpp b/src/hotspot/share/classfile/classLoaderDataGraph.hpp index ae502b6d30d9d..3de2c10850e1a 100644 --- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp +++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp @@ -43,8 +43,6 @@ class ClassLoaderDataGraph : public AllStatic { private: // All CLDs (except unlinked CLDs) can be reached by walking _head->_next->... static ClassLoaderData* volatile _head; - // All unlinked CLDs - static ClassLoaderData* _unloading_head; // Set if there's anything to purge in the deallocate lists or previous versions // during a safepoint after class unloading in a full GC. diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index c3946c862367f..d65c8b2b79ee6 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1986,26 +1986,27 @@ int java_lang_VirtualThread::state(oop vthread) { JavaThreadStatus java_lang_VirtualThread::map_state_to_thread_status(int state) { JavaThreadStatus status = JavaThreadStatus::NEW; switch (state & ~SUSPENDED) { - case NEW : + case NEW: status = JavaThreadStatus::NEW; break; - case STARTED : - case RUNNABLE : - case RUNNING : - case PARKING : + case STARTED: + case RUNNING: + case PARKING: case TIMED_PARKING: - case YIELDING : + case UNPARKED: + case YIELDING: + case YIELDED: status = JavaThreadStatus::RUNNABLE; break; - case PARKED : - case PINNED : + case PARKED: + case PINNED: status = JavaThreadStatus::PARKED; break; case TIMED_PARKED: case TIMED_PINNED: status = JavaThreadStatus::PARKED_TIMED; break; - case TERMINATED : + case TERMINATED: status = JavaThreadStatus::TERMINATED; break; default: diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 716c1f0d83697..23409f8247065 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -523,15 +523,16 @@ class java_lang_VirtualThread : AllStatic { enum { NEW = 0, STARTED = 1, - RUNNABLE = 2, - RUNNING = 3, - PARKING = 4, - PARKED = 5, - PINNED = 6, - TIMED_PARKING = 7, - TIMED_PARKED = 8, - TIMED_PINNED = 9, + RUNNING = 2, + PARKING = 3, + PARKED = 4, + PINNED = 5, + TIMED_PARKING = 6, + TIMED_PARKED = 7, + TIMED_PINNED = 8, + UNPARKED = 9, YIELDING = 10, + YIELDED = 11, TERMINATED = 99, // additional state bits diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp index 506eef46241da..9e96340d82b9c 100644 --- a/src/hotspot/share/classfile/stringTable.cpp +++ b/src/hotspot/share/classfile/stringTable.cpp @@ -806,7 +806,9 @@ oop StringTable::lookup_shared(const jchar* name, int len) { // This should be called when we know no more strings will be added (which will be easy // to guarantee because CDS runs with a single Java thread. See JDK-8253495.) void StringTable::allocate_shared_strings_array(TRAPS) { - assert(CDSConfig::is_dumping_heap(), "must be"); + if (!CDSConfig::is_dumping_heap()) { + return; + } if (_items_count > (size_t)max_jint) { fatal("Too many strings to be archived: %zu", _items_count); } diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp index 66b8a43640728..8ed99d74c0b53 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.hpp +++ b/src/hotspot/share/classfile/vmIntrinsics.hpp @@ -997,6 +997,7 @@ class methodHandle; "I" \ "Ljava/lang/Object;" \ "J" \ + "Z" \ "Ljava/lang/Object;" \ "J" \ "Ljdk/internal/vm/vector/VectorSupport$VectorSpecies;" \ @@ -1011,6 +1012,7 @@ class methodHandle; "I" \ "Ljava/lang/Object;" \ "J" \ + "Z" \ "Ljdk/internal/vm/vector/VectorSupport$VectorMask;" \ "I" \ "Ljava/lang/Object;" \ @@ -1026,6 +1028,7 @@ class methodHandle; "I" \ "Ljava/lang/Object;" \ "J" \ + "Z" \ "Ljdk/internal/vm/vector/VectorSupport$VectorPayload;" \ "Ljava/lang/Object;" \ "J" \ @@ -1040,6 +1043,7 @@ class methodHandle; "I" \ "Ljava/lang/Object;" \ "J" \ + "Z" \ "Ljdk/internal/vm/vector/VectorSupport$Vector;" \ "Ljdk/internal/vm/vector/VectorSupport$VectorMask;" \ "Ljava/lang/Object;" \ diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index b450c1250539c..16ddc2602b1c0 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -162,7 +162,9 @@ class SerializeClosure; template(jdk_internal_loader_BuiltinClassLoader, "jdk/internal/loader/BuiltinClassLoader") \ template(jdk_internal_loader_ClassLoaders_AppClassLoader, "jdk/internal/loader/ClassLoaders$AppClassLoader") \ template(jdk_internal_loader_ClassLoaders_PlatformClassLoader, "jdk/internal/loader/ClassLoaders$PlatformClassLoader") \ - \ + template(java_lang_Deprecated, "Ljava/lang/Deprecated;") \ + template(since, "since") \ + template(for_removal, "forRemoval") \ /* Java runtime version access */ \ template(java_lang_VersionProps, "java/lang/VersionProps") \ template(java_version_name, "java_version") \ diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index 75cf3fbf2d4cd..b8862b974b2d1 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -164,7 +164,7 @@ RuntimeBlob::RuntimeBlob( void RuntimeBlob::free(RuntimeBlob* blob) { assert(blob != nullptr, "caller must check for nullptr"); ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock - blob->flush(); + blob->purge(); { MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); CodeCache::free(blob); @@ -173,7 +173,7 @@ void RuntimeBlob::free(RuntimeBlob* blob) { MemoryService::track_code_cache_memory_usage(); } -void CodeBlob::flush() { +void CodeBlob::purge(bool free_code_cache_data) { if (_oop_maps != nullptr) { delete _oop_maps; _oop_maps = nullptr; @@ -759,6 +759,10 @@ UpcallStub* UpcallStub::create(const char* name, CodeBuffer* cb, jobject receive MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); blob = new (size) UpcallStub(name, cb, size, receiver, frame_data_offset); } + if (blob == nullptr) { + return nullptr; // caller must handle this + } + // Track memory usage statistic after releasing CodeCache_lock MemoryService::track_code_cache_memory_usage(); diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index c6c1e16b00dff..625918faf9c21 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -143,7 +143,7 @@ class CodeBlob { static unsigned int align_code_offset(int offset); // Deletion - virtual void flush(); + virtual void purge(bool free_code_cache_data = true); // Typing virtual bool is_buffer_blob() const { return false; } diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index e99c6230a8e12..9b10dab2ef77f 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -37,6 +37,7 @@ #include "compiler/compilerDefinitions.inline.hpp" #include "compiler/oopMap.hpp" #include "gc/shared/barrierSetNMethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/collectedHeap.hpp" #include "jfr/jfrEvents.hpp" #include "jvm_io.h" @@ -609,7 +610,7 @@ void CodeCache::free(CodeBlob* cb) { cb->~CodeBlob(); // Get heap for given CodeBlob and deallocate - get_code_heap(cb)->deallocate(cb); + heap->deallocate(cb); assert(heap->blob_count() >= 0, "sanity check"); } @@ -965,36 +966,8 @@ void CodeCache::purge_exception_caches() { _exception_cache_purge_list = nullptr; } -// Register an is_unloading nmethod to be flushed after unlinking -void CodeCache::register_unlinked(nmethod* nm) { - assert(nm->unlinked_next() == nullptr, "Only register for unloading once"); - for (;;) { - // Only need acquire when reading the head, when the next - // pointer is walked, which it is not here. - nmethod* head = Atomic::load(&_unlinked_head); - nmethod* next = head != nullptr ? head : nm; // Self looped means end of list - nm->set_unlinked_next(next); - if (Atomic::cmpxchg(&_unlinked_head, head, nm) == head) { - break; - } - } -} - -// Flush all the nmethods the GC unlinked -void CodeCache::flush_unlinked_nmethods() { - nmethod* nm = _unlinked_head; - _unlinked_head = nullptr; - size_t freed_memory = 0; - while (nm != nullptr) { - nmethod* next = nm->unlinked_next(); - freed_memory += nm->total_size(); - nm->flush(); - if (next == nm) { - // Self looped means end of list - break; - } - nm = next; - } +// Restart compiler if possible and required.. +void CodeCache::maybe_restart_compiler(size_t freed_memory) { // Try to start the compiler again if we freed any memory if (!CompileBroker::should_compile_new_jobs() && freed_memory != 0) { @@ -1008,7 +981,6 @@ void CodeCache::flush_unlinked_nmethods() { } uint8_t CodeCache::_unloading_cycle = 1; -nmethod* volatile CodeCache::_unlinked_head = nullptr; void CodeCache::increment_unloading_cycle() { // 2-bit value (see IsUnloadingState in nmethod.cpp for details) diff --git a/src/hotspot/share/code/codeCache.hpp b/src/hotspot/share/code/codeCache.hpp index 51d697735ec45..5418a29e58fc8 100644 --- a/src/hotspot/share/code/codeCache.hpp +++ b/src/hotspot/share/code/codeCache.hpp @@ -106,7 +106,6 @@ class CodeCache : AllStatic { static TruncatedSeq _unloading_gc_intervals; static TruncatedSeq _unloading_allocation_rates; static volatile bool _unloading_threshold_gc_requested; - static nmethod* volatile _unlinked_head; static ExceptionCache* volatile _exception_cache_purge_list; @@ -211,8 +210,7 @@ class CodeCache : AllStatic { // nmethod::is_cold. static void arm_all_nmethods(); - static void flush_unlinked_nmethods(); - static void register_unlinked(nmethod* nm); + static void maybe_restart_compiler(size_t freed_memory); static void do_unloading(bool unloading_occurred); static uint8_t unloading_cycle() { return _unloading_cycle; } diff --git a/src/hotspot/share/code/compiledMethod.hpp b/src/hotspot/share/code/compiledMethod.hpp index e89de609abb4d..fc119cf8795e4 100644 --- a/src/hotspot/share/code/compiledMethod.hpp +++ b/src/hotspot/share/code/compiledMethod.hpp @@ -174,7 +174,7 @@ class CompiledMethod : public CodeBlob { void* _gc_data; - virtual void flush() = 0; + virtual void purge(bool free_code_cache_data = true) = 0; private: DeoptimizationStatus deoptimization_status() const { diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index b8114e2c38b21..64adc566a24bb 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -42,6 +42,7 @@ #include "compiler/oopMap.inline.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetNMethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/collectedHeap.hpp" #include "interpreter/bytecode.hpp" #include "jvm.h" @@ -639,7 +640,7 @@ nmethod::nmethod( ByteSize basic_lock_sp_offset, OopMapSet* oop_maps ) : CompiledMethod(method, "native nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false, true), - _unlinked_next(nullptr), + _is_unlinked(false), _native_receiver_sp_offset(basic_lock_owner_sp_offset), _native_basic_lock_sp_offset(basic_lock_sp_offset), _is_unloading_state(0) @@ -783,7 +784,7 @@ nmethod::nmethod( #endif ) : CompiledMethod(method, "nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false, true), - _unlinked_next(nullptr), + _is_unlinked(false), _native_receiver_sp_offset(in_ByteSize(-1)), _native_basic_lock_sp_offset(in_ByteSize(-1)), _is_unloading_state(0) @@ -1406,7 +1407,7 @@ bool nmethod::make_not_entrant() { // For concurrent GCs, there must be a handshake between unlink and flush void nmethod::unlink() { - if (_unlinked_next != nullptr) { + if (_is_unlinked) { // Already unlinked. It can be invoked twice because concurrent code cache // unloading might need to restart when inline cache cleaning fails due to // running out of ICStubs, which can only be refilled at safepoints @@ -1440,10 +1441,10 @@ void nmethod::unlink() { // Register for flushing when it is safe. For concurrent class unloading, // that would be after the unloading handshake, and for STW class unloading // that would be when getting back to the VM thread. - CodeCache::register_unlinked(this); + ClassUnloadingContext::context()->register_unlinked_nmethod(this); } -void nmethod::flush() { +void nmethod::purge(bool free_code_cache_data) { MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag); // completely deallocate this method @@ -1466,8 +1467,10 @@ void nmethod::flush() { Universe::heap()->unregister_nmethod(this); CodeCache::unregister_old_nmethod(this); - CodeBlob::flush(); - CodeCache::free(this); + CodeBlob::purge(); + if (free_code_cache_data) { + CodeCache::free(this); + } } oop nmethod::oop_at(int index) const { diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index dea88ee6d1cd8..12ae9256eea56 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -196,7 +196,7 @@ class nmethod : public CompiledMethod { address _verified_entry_point; // entry point without class check address _osr_entry_point; // entry point for on stack replacement - nmethod* _unlinked_next; + bool _is_unlinked; // Shared fields for all nmethod's int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method @@ -441,8 +441,8 @@ class nmethod : public CompiledMethod { virtual bool is_unloading(); virtual void do_unloading(bool unloading_occurred); - nmethod* unlinked_next() const { return _unlinked_next; } - void set_unlinked_next(nmethod* next) { _unlinked_next = next; } + bool is_unlinked() const { return _is_unlinked; } + void set_is_unlinked() { assert(!_is_unlinked, "already unlinked"); _is_unlinked = true; } #if INCLUDE_RTM_OPT // rtm state accessing and manipulating @@ -522,7 +522,7 @@ class nmethod : public CompiledMethod { void unlink(); // Deallocate this nmethod - called by the GC - void flush(); + void purge(bool free_code_cache_data = true); // See comment at definition of _last_seen_on_stack void mark_as_maybe_on_stack(); diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index dce935a14d8cb..9ccbcf9481f55 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -278,7 +278,7 @@ bool CompileBroker::can_remove(CompilerThread *ct, bool do_it) { if (ct->idle_time_millis() < (c1 ? 500 : 100)) return false; #if INCLUDE_JVMCI - if (compiler->is_jvmci()) { + if (compiler->is_jvmci() && !UseJVMCINativeLibrary) { // Handles for JVMCI thread objects may get released concurrently. if (do_it) { assert(CompileThread_lock->owner() == ct, "must be holding lock"); @@ -297,7 +297,7 @@ bool CompileBroker::can_remove(CompilerThread *ct, bool do_it) { assert_locked_or_safepoint(CompileThread_lock); // Update must be consistent. compiler->set_num_compiler_threads(compiler_count - 1); #if INCLUDE_JVMCI - if (compiler->is_jvmci()) { + if (compiler->is_jvmci() && !UseJVMCINativeLibrary) { // Old j.l.Thread object can die when no longer referenced elsewhere. JNIHandles::destroy_global(compiler2_object(compiler_count - 1)); _compiler2_objects[compiler_count - 1] = nullptr; @@ -772,11 +772,6 @@ void CompileBroker::compilation_init(JavaThread* THREAD) { _initialized = true; } -Handle CompileBroker::create_thread_oop(const char* name, TRAPS) { - Handle thread_oop = JavaThread::create_system_thread_object(name, CHECK_NH); - return thread_oop; -} - #if defined(ASSERT) && COMPILER2_OR_JVMCI // Stress testing. Dedicated threads revert optimizations based on escape analysis concurrently to // the running java application. Configured with vm options DeoptimizeObjectsALot*. @@ -923,6 +918,13 @@ static bool trace_compiler_threads() { return TraceCompilerThreads || lt.is_enabled(); } +static jobject create_compiler_thread(AbstractCompiler* compiler, int i, TRAPS) { + char name_buffer[256]; + os::snprintf_checked(name_buffer, sizeof(name_buffer), "%s CompilerThread%d", compiler->name(), i); + Handle thread_oop = JavaThread::create_system_thread_object(name_buffer, CHECK_NULL); + return JNIHandles::make_global(thread_oop); +} + static void print_compiler_threads(stringStream& msg) { if (TraceCompilerThreads) { tty->print_cr("%7d %s", (int)tty->time_stamp().milliseconds(), msg.as_string()); @@ -953,18 +955,9 @@ void CompileBroker::init_compiler_threads() { _compiler1_logs = NEW_C_HEAP_ARRAY(CompileLog*, _c1_count, mtCompiler); } - char name_buffer[256]; - for (int i = 0; i < _c2_count; i++) { - jobject thread_handle = nullptr; - // Create all j.l.Thread objects for C1 and C2 threads here, but only one - // for JVMCI compiler which can create further ones on demand. - JVMCI_ONLY(if (!UseJVMCICompiler || !UseDynamicNumberOfCompilerThreads || i == 0) {) // Create a name for our thread. - os::snprintf_checked(name_buffer, sizeof(name_buffer), "%s CompilerThread%d", _compilers[1]->name(), i); - Handle thread_oop = create_thread_oop(name_buffer, CHECK); - thread_handle = JNIHandles::make_global(thread_oop); - JVMCI_ONLY(}) + jobject thread_handle = create_compiler_thread(_compilers[1], i, CHECK); _compiler2_objects[i] = thread_handle; _compiler2_logs[i] = nullptr; @@ -985,9 +978,7 @@ void CompileBroker::init_compiler_threads() { for (int i = 0; i < _c1_count; i++) { // Create a name for our thread. - os::snprintf_checked(name_buffer, sizeof(name_buffer), "C1 CompilerThread%d", i); - Handle thread_oop = create_thread_oop(name_buffer, CHECK); - jobject thread_handle = JNIHandles::make_global(thread_oop); + jobject thread_handle = create_compiler_thread(_compilers[0], i, CHECK); _compiler1_objects[i] = thread_handle; _compiler1_logs[i] = nullptr; @@ -1015,7 +1006,7 @@ void CompileBroker::init_compiler_threads() { // Initialize and start the object deoptimizer threads const int total_count = DeoptimizeObjectsALotThreadCountSingle + DeoptimizeObjectsALotThreadCountAll; for (int count = 0; count < total_count; count++) { - Handle thread_oop = create_thread_oop("Deoptimize objects a lot single mode", CHECK); + Handle thread_oop = JavaThread::create_system_thread_object("Deoptimize objects a lot single mode", CHECK); jobject thread_handle = JNIHandles::make_local(THREAD, thread_oop()); make_thread(deoptimizer_t, thread_handle, nullptr, nullptr, THREAD); } @@ -1042,13 +1033,15 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) { for (int i = old_c2_count; i < new_c2_count; i++) { #if INCLUDE_JVMCI - if (UseJVMCICompiler) { - // Native compiler threads as used in C1/C2 can reuse the j.l.Thread - // objects as their existence is completely hidden from the rest of - // the VM (and those compiler threads can't call Java code to do the - // creation anyway). For JVMCI we have to create new j.l.Thread objects - // as they are visible and we can see unexpected thread lifecycle - // transitions if we bind them to new JavaThreads. + if (UseJVMCICompiler && !UseJVMCINativeLibrary && _compiler2_objects[i] == nullptr) { + // Native compiler threads as used in C1/C2 can reuse the j.l.Thread objects as their + // existence is completely hidden from the rest of the VM (and those compiler threads can't + // call Java code to do the creation anyway). + // + // For pure Java JVMCI we have to create new j.l.Thread objects as they are visible and we + // can see unexpected thread lifecycle transitions if we bind them to new JavaThreads. For + // native library JVMCI it's preferred to use the C1/C2 strategy as this avoids unnecessary + // coupling with Java. if (!THREAD->can_call_java()) break; char name_buffer[256]; os::snprintf_checked(name_buffer, sizeof(name_buffer), "%s CompilerThread%d", _compilers[1]->name(), i); @@ -1056,7 +1049,7 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) { { // We have to give up the lock temporarily for the Java calls. MutexUnlocker mu(CompileThread_lock); - thread_oop = create_thread_oop(name_buffer, THREAD); + thread_oop = JavaThread::create_system_thread_object(name_buffer, THREAD); } if (HAS_PENDING_EXCEPTION) { if (trace_compiler_threads()) { @@ -1076,6 +1069,7 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) { _compiler2_objects[i] = thread_handle; } #endif + guarantee(compiler2_object(i) != nullptr, "Thread oop must exist"); JavaThread *ct = make_thread(compiler_t, compiler2_object(i), _c2_compile_queue, _compilers[1], THREAD); if (ct == nullptr) break; _compilers[1]->set_num_compiler_threads(i + 1); @@ -1794,7 +1788,7 @@ bool CompileBroker::init_compiler_runtime() { void CompileBroker::free_buffer_blob_if_allocated(CompilerThread* thread) { BufferBlob* blob = thread->get_buffer_blob(); if (blob != nullptr) { - blob->flush(); + blob->purge(); MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); CodeCache::free(blob); } diff --git a/src/hotspot/share/compiler/compileBroker.hpp b/src/hotspot/share/compiler/compileBroker.hpp index d136045102a8b..71a9c9dd6bbb0 100644 --- a/src/hotspot/share/compiler/compileBroker.hpp +++ b/src/hotspot/share/compiler/compileBroker.hpp @@ -241,7 +241,6 @@ class CompileBroker: AllStatic { deoptimizer_t }; - static Handle create_thread_oop(const char* name, TRAPS); static JavaThread* make_thread(ThreadType type, jobject thread_oop, CompileQueue* queue, AbstractCompiler* comp, JavaThread* THREAD); static void init_compiler_threads(); static void possibly_add_compiler_threads(JavaThread* THREAD); diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 6b2adcc8ff888..25d7ed13ab08e 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -25,7 +25,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/metadataOnStackMark.hpp" -#include "classfile/stringTable.hpp" +#include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" #include "compiler/oopMap.hpp" @@ -70,15 +70,15 @@ #include "gc/g1/g1UncommitRegionTask.hpp" #include "gc/g1/g1VMOperations.hpp" #include "gc/g1/g1YoungCollector.hpp" -#include "gc/g1/g1YoungGCEvacFailureInjector.hpp" +#include "gc/g1/g1YoungGCAllocationFailureInjector.hpp" #include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionRemSet.inline.hpp" #include "gc/g1/heapRegionSet.inline.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/concurrentGCBreakpoints.hpp" #include "gc/shared/gcBehaviours.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcId.hpp" -#include "gc/shared/gcLocker.inline.hpp" #include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/isGCActiveMark.hpp" @@ -103,6 +103,7 @@ #include "oops/compressedOops.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" +#include "runtime/cpuTimeCounters.hpp" #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" #include "runtime/java.hpp" @@ -411,13 +412,11 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size) { // We should only get here after the first-level allocation attempt // (attempt_allocation()) failed to allocate. - // We will loop until a) we manage to successfully perform the - // allocation or b) we successfully schedule a collection which - // fails to perform the allocation. b) is the only case when we'll - // return null. + // We will loop until a) we manage to successfully perform the allocation or b) + // successfully schedule a collection which fails to perform the allocation. + // Case b) is the only case when we'll return null. HeapWord* result = nullptr; - for (uint try_count = 1, gclocker_retry_count = 0; /* we'll return */; try_count += 1) { - bool should_try_gc; + for (uint try_count = 1; /* we'll return */; try_count++) { uint gc_count_before; { @@ -430,67 +429,26 @@ HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size) { return result; } - // If the GCLocker is active and we are bound for a GC, try expanding young gen. - // This is different to when only GCLocker::needs_gc() is set: try to avoid - // waiting because the GCLocker is active to not wait too long. - if (GCLocker::is_active_and_needs_gc() && policy()->can_expand_young_list()) { - // No need for an ergo message here, can_expand_young_list() does this when - // it returns true. - result = _allocator->attempt_allocation_force(word_size); - if (result != nullptr) { - return result; - } - } - - // Only try a GC if the GCLocker does not signal the need for a GC. Wait until - // the GCLocker initiated GC has been performed and then retry. This includes - // the case when the GC Locker is not active but has not been performed. - should_try_gc = !GCLocker::needs_gc(); // Read the GC count while still holding the Heap_lock. gc_count_before = total_collections(); } - if (should_try_gc) { - bool succeeded; - result = do_collection_pause(word_size, gc_count_before, &succeeded, GCCause::_g1_inc_collection_pause); - if (result != nullptr) { - assert(succeeded, "only way to get back a non-null result"); - log_trace(gc, alloc)("%s: Successfully scheduled collection returning " PTR_FORMAT, - Thread::current()->name(), p2i(result)); - return result; - } - - if (succeeded) { - // We successfully scheduled a collection which failed to allocate. No - // point in trying to allocate further. We'll just return null. - log_trace(gc, alloc)("%s: Successfully scheduled collection failing to allocate " - SIZE_FORMAT " words", Thread::current()->name(), word_size); - return nullptr; - } - log_trace(gc, alloc)("%s: Unsuccessfully scheduled collection allocating " SIZE_FORMAT " words", - Thread::current()->name(), word_size); - } else { - // Failed to schedule a collection. - if (gclocker_retry_count > GCLockerRetryAllocationCount) { - log_warning(gc, alloc)("%s: Retried waiting for GCLocker too often allocating " - SIZE_FORMAT " words", Thread::current()->name(), word_size); - return nullptr; - } - log_trace(gc, alloc)("%s: Stall until clear", Thread::current()->name()); - // The GCLocker is either active or the GCLocker initiated - // GC has not yet been performed. Stall until it is and - // then retry the allocation. - GCLocker::stall_until_clear(); - gclocker_retry_count += 1; + bool succeeded; + result = do_collection_pause(word_size, gc_count_before, &succeeded, GCCause::_g1_inc_collection_pause); + if (succeeded) { + log_trace(gc, alloc)("%s: Successfully scheduled collection returning " PTR_FORMAT, + Thread::current()->name(), p2i(result)); + return result; } - // We can reach here if we were unsuccessful in scheduling a - // collection (because another thread beat us to it) or if we were - // stalled due to the GC locker. In either can we should retry the - // allocation attempt in case another thread successfully - // performed a collection and reclaimed enough space. We do the - // first attempt (without holding the Heap_lock) here and the - // follow-on attempt will be at the start of the next loop + log_trace(gc, alloc)("%s: Unsuccessfully scheduled collection allocating " SIZE_FORMAT " words", + Thread::current()->name(), word_size); + + // We can reach here if we were unsuccessful in scheduling a collection (because + // another thread beat us to it). In this case immeditealy retry the allocation + // attempt because another thread successfully performed a collection and possibly + // reclaimed enough space. The first attempt (without holding the Heap_lock) is + // here and the follow-on attempt will be at the start of the next loop // iteration (after taking the Heap_lock). size_t dummy = 0; result = _allocator->attempt_allocation(word_size, word_size, &dummy); @@ -673,13 +631,11 @@ HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size) { collect(GCCause::_g1_humongous_allocation); } - // We will loop until a) we manage to successfully perform the - // allocation or b) we successfully schedule a collection which - // fails to perform the allocation. b) is the only case when we'll - // return null. + // We will loop until a) we manage to successfully perform the allocation or b) + // successfully schedule a collection which fails to perform the allocation. + // Case b) is the only case when we'll return null. HeapWord* result = nullptr; - for (uint try_count = 1, gclocker_retry_count = 0; /* we'll return */; try_count += 1) { - bool should_try_gc; + for (uint try_count = 1; /* we'll return */; try_count++) { uint gc_count_before; @@ -697,64 +653,35 @@ HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size) { return result; } - // Only try a GC if the GCLocker does not signal the need for a GC. Wait until - // the GCLocker initiated GC has been performed and then retry. This includes - // the case when the GC Locker is not active but has not been performed. - should_try_gc = !GCLocker::needs_gc(); // Read the GC count while still holding the Heap_lock. gc_count_before = total_collections(); } - if (should_try_gc) { - bool succeeded; - result = do_collection_pause(word_size, gc_count_before, &succeeded, GCCause::_g1_humongous_allocation); + bool succeeded; + result = do_collection_pause(word_size, gc_count_before, &succeeded, GCCause::_g1_humongous_allocation); + if (succeeded) { + log_trace(gc, alloc)("%s: Successfully scheduled collection returning " PTR_FORMAT, + Thread::current()->name(), p2i(result)); if (result != nullptr) { - assert(succeeded, "only way to get back a non-null result"); - log_trace(gc, alloc)("%s: Successfully scheduled collection returning " PTR_FORMAT, - Thread::current()->name(), p2i(result)); size_t size_in_regions = humongous_obj_size_in_regions(word_size); policy()->old_gen_alloc_tracker()-> record_collection_pause_humongous_allocation(size_in_regions * HeapRegion::GrainBytes); - return result; - } - - if (succeeded) { - // We successfully scheduled a collection which failed to allocate. No - // point in trying to allocate further. We'll just return null. - log_trace(gc, alloc)("%s: Successfully scheduled collection failing to allocate " - SIZE_FORMAT " words", Thread::current()->name(), word_size); - return nullptr; } - log_trace(gc, alloc)("%s: Unsuccessfully scheduled collection allocating " SIZE_FORMAT "", - Thread::current()->name(), word_size); - } else { - // Failed to schedule a collection. - if (gclocker_retry_count > GCLockerRetryAllocationCount) { - log_warning(gc, alloc)("%s: Retried waiting for GCLocker too often allocating " - SIZE_FORMAT " words", Thread::current()->name(), word_size); - return nullptr; - } - log_trace(gc, alloc)("%s: Stall until clear", Thread::current()->name()); - // The GCLocker is either active or the GCLocker initiated - // GC has not yet been performed. Stall until it is and - // then retry the allocation. - GCLocker::stall_until_clear(); - gclocker_retry_count += 1; + return result; } + log_trace(gc, alloc)("%s: Unsuccessfully scheduled collection allocating " SIZE_FORMAT "", + Thread::current()->name(), word_size); - // We can reach here if we were unsuccessful in scheduling a - // collection (because another thread beat us to it) or if we were - // stalled due to the GC locker. In either can we should retry the - // allocation attempt in case another thread successfully - // performed a collection and reclaimed enough space. + // We can reach here if we were unsuccessful in scheduling a collection (because + // another thread beat us to it). // Humongous object allocation always needs a lock, so we wait for the retry // in the next iteration of the loop, unlike for the regular iteration case. // Give a warning if we seem to be looping forever. if ((QueuedAllocationWarningCount > 0) && (try_count % QueuedAllocationWarningCount == 0)) { - log_warning(gc, alloc)("%s: Retried allocation %u times for " SIZE_FORMAT " words", + log_warning(gc, alloc)("%s: Retried allocation %u times for %zu words", Thread::current()->name(), try_count, word_size); } } @@ -847,10 +774,6 @@ void G1CollectedHeap::verify_before_full_collection() { } void G1CollectedHeap::prepare_for_mutator_after_full_collection() { - // Delete metaspaces for unloaded class loaders and clean up loader_data graph - ClassLoaderDataGraph::purge(/*at_safepoint*/true); - DEBUG_ONLY(MetaspaceUtils::verify();) - // Prepare heap for normal collections. assert(num_free_regions() == 0, "we should not have added any free regions"); rebuild_region_sets(false /* free_list_only */); @@ -908,11 +831,6 @@ bool G1CollectedHeap::do_full_collection(bool clear_all_soft_refs, bool do_maximal_compaction) { assert_at_safepoint_on_vm_thread(); - if (GCLocker::check_active_before_gc()) { - // Full GC was not completed. - return false; - } - const bool do_clear_all_soft_refs = clear_all_soft_refs || soft_ref_policy()->should_clear_all_soft_refs(); @@ -1226,7 +1144,7 @@ G1CollectedHeap::G1CollectedHeap() : _numa(G1NUMA::create()), _hrm(), _allocator(nullptr), - _evac_failure_injector(), + _allocation_failure_injector(), _verifier(nullptr), _summary_bytes_used(0), _bytes_used_during_gc(0), @@ -1269,9 +1187,11 @@ G1CollectedHeap::G1CollectedHeap() : _humongous_object_threshold_in_words = humongous_threshold_for(HeapRegion::GrainWords); - // Override the default _filler_array_max_size so that no humongous filler - // objects are created. - _filler_array_max_size = _humongous_object_threshold_in_words; + // Since filler arrays are never referenced, we can make them region sized. + // This simplifies filling up the region in case we have some potentially + // unreferenced (by Java code, but still in use by native code) pinned objects + // in there. + _filler_array_max_size = HeapRegion::GrainWords; // Override the default _stack_chunk_max_size so that no humongous stack chunks are created _stack_chunk_max_size = _humongous_object_threshold_in_words; @@ -1512,7 +1432,12 @@ jint G1CollectedHeap::initialize() { _collection_set.initialize(max_reserved_regions()); - evac_failure_injector()->reset(); + allocation_failure_injector()->reset(); + + CPUTimeCounters::create_counter(CPUTimeGroups::CPUTimeType::gc_parallel_workers); + CPUTimeCounters::create_counter(CPUTimeGroups::CPUTimeType::gc_conc_mark); + CPUTimeCounters::create_counter(CPUTimeGroups::CPUTimeType::gc_conc_refine); + CPUTimeCounters::create_counter(CPUTimeGroups::CPUTimeType::gc_service); G1InitLogger::print(); @@ -1904,12 +1829,6 @@ bool G1CollectedHeap::try_collect_concurrently(GCCause::Cause cause, // Collection failed and should be retried. assert(op.transient_failure(), "invariant"); - if (GCLocker::is_active_and_needs_gc()) { - // If GCLocker is active, wait until clear before retrying. - LOG_COLLECT_CONCURRENTLY(cause, "gc-locker stall"); - GCLocker::stall_until_clear(); - } - LOG_COLLECT_CONCURRENTLY(cause, "retry"); } } @@ -1935,11 +1854,6 @@ bool G1CollectedHeap::try_collect_fullgc(GCCause::Cause cause, return true; } } - - if (GCLocker::is_active_and_needs_gc()) { - // If GCLocker is active, wait until clear before retrying. - GCLocker::stall_until_clear(); - } } } @@ -1949,11 +1863,6 @@ bool G1CollectedHeap::try_collect(GCCause::Cause cause, return try_collect_concurrently(cause, counters_before.total_collections(), counters_before.old_marking_cycles_started()); - } else if (GCLocker::should_discard(cause, counters_before.total_collections())) { - // Indicate failure to be consistent with VMOp failure due to - // another collection slipping in after our gc_count but before - // our request is processed. - return false; } else if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { @@ -2179,14 +2088,6 @@ bool G1CollectedHeap::is_obj_dead_cond(const oop obj, return false; // keep some compilers happy } -void G1CollectedHeap::pin_object(JavaThread* thread, oop obj) { - GCLocker::lock_critical(thread); -} - -void G1CollectedHeap::unpin_object(JavaThread* thread, oop obj) { - GCLocker::unlock_critical(thread); -} - void G1CollectedHeap::print_heap_regions() const { LogTarget(Trace, gc, heap, region) lt; if (lt.is_enabled()) { @@ -2329,6 +2230,8 @@ void G1CollectedHeap::gc_epilogue(bool full) { _free_arena_memory_task->notify_new_stats(&_young_gen_card_set_stats, &_collection_set_candidates_card_set_stats); + + update_parallel_gc_threads_cpu_time(); } uint G1CollectedHeap::uncommit_regions(uint region_limit) { @@ -2413,6 +2316,26 @@ void G1CollectedHeap::verify_region_attr_remset_is_tracked() { } #endif +void G1CollectedHeap::update_parallel_gc_threads_cpu_time() { + assert(Thread::current()->is_VM_thread(), + "Must be called from VM thread to avoid races"); + if (!UsePerfData || !os::is_thread_cpu_time_supported()) { + return; + } + + // Ensure ThreadTotalCPUTimeClosure destructor is called before publishing gc + // time. + { + ThreadTotalCPUTimeClosure tttc(CPUTimeGroups::CPUTimeType::gc_parallel_workers); + // Currently parallel worker threads never terminate (JDK-8081682), so it is + // safe for VMThread to read their CPU times. However, if JDK-8087340 is + // resolved so they terminate, we should rethink if it is still safe. + workers()->threads_do(&tttc); + } + + CPUTimeCounters::publish_gc_total_cpu_time(); +} + void G1CollectedHeap::start_new_collection_set() { collection_set()->start_incremental_building(); @@ -2489,10 +2412,6 @@ bool G1CollectedHeap::do_collection_pause_at_safepoint() { assert_at_safepoint_on_vm_thread(); guarantee(!is_gc_active(), "collection is not reentrant"); - if (GCLocker::check_active_before_gc()) { - return false; - } - do_collection_pause_at_safepoint_helper(); return true; } @@ -2594,6 +2513,33 @@ void G1CollectedHeap::complete_cleaning(bool class_unloading_occurred) { workers()->run_task(&unlink_task); } +void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjectClosure* is_alive, GCTimer* timer) { + GCTraceTime(Debug, gc, phases) debug(description, timer); + + ClassUnloadingContext ctx(workers()->active_workers(), + false /* lock_codeblob_free_separately */); + { + CodeCache::UnlinkingScope scope(is_alive); + bool unloading_occurred = SystemDictionary::do_unloading(timer); + GCTraceTime(Debug, gc, phases) t("G1 Complete Cleaning", timer); + complete_cleaning(unloading_occurred); + } + { + GCTraceTime(Debug, gc, phases) t("Purge Unlinked NMethods", timer); + ctx.purge_nmethods(); + } + { + GCTraceTime(Debug, gc, phases) t("Free Code Blobs", timer); + ctx.free_code_blobs(); + } + { + GCTraceTime(Debug, gc, phases) t("Purge Class Loader Data", timer); + ClassLoaderDataGraph::purge(true /* at_safepoint */); + DEBUG_ONLY(MetaspaceUtils::verify();) + } +} + + bool G1STWSubjectToDiscoveryClosure::do_object_b(oop obj) { assert(obj != nullptr, "must not be null"); assert(_g1h->is_in_reserved(obj), "Trying to discover obj " PTR_FORMAT " not in heap", p2i(obj)); @@ -2647,6 +2593,8 @@ void G1CollectedHeap::free_region(HeapRegion* hr, FreeRegionList* free_list) { assert(!hr->is_free(), "the region should not be free"); assert(!hr->is_empty(), "the region should not be empty"); assert(_hrm.is_available(hr->hrm_index()), "region should be committed"); + assert(!hr->has_pinned_objects(), + "must not free a region which contains pinned objects"); // Reset region metadata to allow reuse. hr->hr_clear(true /* clear_space */); @@ -3054,9 +3002,6 @@ void G1CollectedHeap::unregister_nmethod(nmethod* nm) { void G1CollectedHeap::update_used_after_gc(bool evacuation_failed) { if (evacuation_failed) { - // Reset the G1EvacuationFailureALot counters and flags - evac_failure_injector()->reset(); - set_used(recalculate_used()); } else { // The "used" of the collection set have already been subtracted diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 96cb75777a6dd..1d25ea278deda 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -44,7 +44,7 @@ #include "gc/g1/g1MonotonicArenaFreePool.hpp" #include "gc/g1/g1NUMA.hpp" #include "gc/g1/g1SurvivorRegions.hpp" -#include "gc/g1/g1YoungGCEvacFailureInjector.hpp" +#include "gc/g1/g1YoungGCAllocationFailureInjector.hpp" #include "gc/g1/heapRegionManager.hpp" #include "gc/g1/heapRegionSet.hpp" #include "gc/shared/barrierSet.hpp" @@ -220,7 +220,7 @@ class G1CollectedHeap : public CollectedHeap { // Manages all allocations with regions except humongous object allocations. G1Allocator* _allocator; - G1YoungGCEvacFailureInjector _evac_failure_injector; + G1YoungGCAllocationFailureInjector _allocation_failure_injector; // Manages all heap verification. G1HeapVerifier* _verifier; @@ -264,6 +264,7 @@ class G1CollectedHeap : public CollectedHeap { void set_collection_set_candidates_stats(G1MonotonicArenaMemoryStats& stats); void set_young_gen_card_set_stats(const G1MonotonicArenaMemoryStats& stats); + void update_parallel_gc_threads_cpu_time(); private: G1HRPrinter _hr_printer; @@ -549,7 +550,7 @@ class G1CollectedHeap : public CollectedHeap { return _allocator; } - G1YoungGCEvacFailureInjector* evac_failure_injector() { return &_evac_failure_injector; } + G1YoungGCAllocationFailureInjector* allocation_failure_injector() { return &_allocation_failure_injector; } G1HeapVerifier* verifier() { return _verifier; @@ -560,6 +561,9 @@ class G1CollectedHeap : public CollectedHeap { return _monitoring_support; } + void pin_object(JavaThread* thread, oop obj) override; + void unpin_object(JavaThread* thread, oop obj) override; + void resize_heap_if_necessary(); // Check if there is memory to uncommit and if so schedule a task to do it. @@ -613,7 +617,7 @@ class G1CollectedHeap : public CollectedHeap { // We register a region with the fast "in collection set" test. We // simply set to true the array slot corresponding to this region. void register_young_region_with_region_attr(HeapRegion* r) { - _region_attr.set_in_young(r->hrm_index()); + _region_attr.set_in_young(r->hrm_index(), r->has_pinned_objects()); } inline void register_new_survivor_region_with_region_attr(HeapRegion* r); inline void register_region_with_region_attr(HeapRegion* r); @@ -1264,6 +1268,8 @@ class G1CollectedHeap : public CollectedHeap { // Performs cleaning of data structures after class unloading. void complete_cleaning(bool class_unloading_occurred); + void unload_classes_and_code(const char* description, BoolObjectClosure* cl, GCTimer* timer); + // Verification // Perform any cleanup actions necessary before allowing a verification. @@ -1292,9 +1298,6 @@ class G1CollectedHeap : public CollectedHeap { G1HeapSummary create_g1_heap_summary(); G1EvacSummary create_g1_evac_summary(G1EvacStats* stats); - void pin_object(JavaThread* thread, oop obj) override; - void unpin_object(JavaThread* thread, oop obj) override; - // Printing private: void print_heap_regions() const; diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp index 05d3a65fd59ef..7b81a93abe177 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp @@ -209,6 +209,8 @@ G1HeapRegionAttr G1CollectedHeap::region_attr(uint idx) const { } void G1CollectedHeap::register_humongous_candidate_region_with_region_attr(uint index) { + assert(!region_at(index)->has_pinned_objects(), "must be"); + assert(region_at(index)->rem_set()->is_complete(), "must be"); _region_attr.set_humongous_candidate(index); } @@ -218,9 +220,12 @@ void G1CollectedHeap::register_new_survivor_region_with_region_attr(HeapRegion* void G1CollectedHeap::register_region_with_region_attr(HeapRegion* r) { _region_attr.set_remset_is_tracked(r->hrm_index(), r->rem_set()->is_tracked()); + _region_attr.set_is_pinned(r->hrm_index(), r->has_pinned_objects()); } void G1CollectedHeap::register_old_region_with_region_attr(HeapRegion* r) { + assert(!r->has_pinned_objects(), "must be"); + assert(r->rem_set()->is_complete(), "must be"); _region_attr.set_in_old(r->hrm_index(), r->rem_set()->is_tracked()); _rem_set->exclude_region_from_scan(r->hrm_index()); } @@ -257,6 +262,21 @@ inline bool G1CollectedHeap::is_obj_dead(const oop obj, const HeapRegion* hr) co } } +inline void G1CollectedHeap::pin_object(JavaThread* thread, oop obj) { + assert(obj != nullptr, "obj must not be null"); + assert(!is_gc_active(), "must not pin objects during a GC"); + assert(obj->is_typeArray(), "must be typeArray"); + HeapRegion *r = heap_region_containing(obj); + r->increment_pinned_object_count(); +} + +inline void G1CollectedHeap::unpin_object(JavaThread* thread, oop obj) { + assert(obj != nullptr, "obj must not be null"); + assert(!is_gc_active(), "must not unpin objects during a GC"); + HeapRegion *r = heap_region_containing(obj); + r->decrement_pinned_object_count(); +} + inline bool G1CollectedHeap::is_obj_dead(const oop obj) const { assert(obj != nullptr, "precondition"); diff --git a/src/hotspot/share/gc/g1/g1CollectionSet.cpp b/src/hotspot/share/gc/g1/g1CollectionSet.cpp index 3c43d6ec10016..30787adbe543b 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSet.cpp +++ b/src/hotspot/share/gc/g1/g1CollectionSet.cpp @@ -270,6 +270,9 @@ void G1CollectionSet::print(outputStream* st) { } #endif // !PRODUCT +// Always evacuate out pinned regions (apart from object types that can actually be +// pinned by JNI) to allow faster future evacuation. We already "paid" for this work +// when sizing the young generation. double G1CollectionSet::finalize_young_part(double target_pause_time_ms, G1SurvivorRegions* survivors) { Ticks start_time = Ticks::now(); @@ -317,6 +320,19 @@ static int compare_region_idx(const uint a, const uint b) { return static_cast(a-b); } +// The current mechanism skips evacuation of pinned old regions like g1 does for +// young regions: +// * evacuating pinned marking collection set candidate regions (available during mixed +// gc) like young regions would not result in any memory gain but only take additional +// time away from processing regions that would actually result in memory being freed. +// To advance mixed gc progress (we committed to evacuate all marking collection set +// candidate regions within the maximum number of mixed gcs in the phase), move them +// to the optional collection set candidates to reclaim them asap as time permits. +// * evacuating out retained collection set candidates would also just take up time with +// no actual space freed in old gen. Better to concentrate on others. +// Retained collection set candidates are aged out, ie. made to regular old regions +// without remembered sets after a few attempts to save computation costs of keeping +// them candidates for very long living pinned regions. void G1CollectionSet::finalize_old_part(double time_remaining_ms) { double non_young_start_time_sec = os::elapsedTime(); @@ -325,12 +341,15 @@ void G1CollectionSet::finalize_old_part(double time_remaining_ms) { G1CollectionCandidateRegionList initial_old_regions; assert(_optional_old_regions.length() == 0, "must be"); + G1CollectionCandidateRegionList pinned_marking_regions; + G1CollectionCandidateRegionList pinned_retained_regions; if (collector_state()->in_mixed_phase()) { time_remaining_ms = _policy->select_candidates_from_marking(&candidates()->marking_regions(), time_remaining_ms, &initial_old_regions, - &_optional_old_regions); + &_optional_old_regions, + &pinned_marking_regions); } else { log_debug(gc, ergo, cset)("Do not add marking candidates to collection set due to pause type."); } @@ -338,12 +357,20 @@ void G1CollectionSet::finalize_old_part(double time_remaining_ms) { _policy->select_candidates_from_retained(&candidates()->retained_regions(), time_remaining_ms, &initial_old_regions, - &_optional_old_regions); + &_optional_old_regions, + &pinned_retained_regions); // Move initially selected old regions to collection set directly. move_candidates_to_collection_set(&initial_old_regions); // Only prepare selected optional regions for now. prepare_optional_regions(&_optional_old_regions); + // Move pinned marking regions we came across to retained candidates so that + // there is progress in the mixed gc phase. + move_pinned_marking_to_retained(&pinned_marking_regions); + // Drop pinned retained regions to make progress with retained regions. Regions + // in that list must have been pinned for at least G1NumCollectionsKeepPinned + // GCs and hence are considered "long lived". + drop_pinned_retained_regions(&pinned_retained_regions); candidates()->verify(); } else { @@ -378,6 +405,32 @@ void G1CollectionSet::prepare_optional_regions(G1CollectionCandidateRegionList* } } +void G1CollectionSet::move_pinned_marking_to_retained(G1CollectionCandidateRegionList* regions) { + if (regions->length() == 0) { + return; + } + candidates()->remove(regions); + + for (HeapRegion* r : *regions) { + assert(r->has_pinned_objects(), "must be pinned"); + assert(r->rem_set()->is_complete(), "must be complete"); + candidates()->add_retained_region_unsorted(r); + } + candidates()->sort_by_efficiency(); +} + +void G1CollectionSet::drop_pinned_retained_regions(G1CollectionCandidateRegionList* regions) { + if (regions->length() == 0) { + return; + } + candidates()->remove(regions); + + // We can now drop these region's remembered sets. + for (HeapRegion* r : *regions) { + r->rem_set()->clear(true /* only_cardset */); + } +} + void G1CollectionSet::finalize_initial_collection_set(double target_pause_time_ms, G1SurvivorRegions* survivor) { double time_remaining_ms = finalize_young_part(target_pause_time_ms, survivor); finalize_old_part(time_remaining_ms); diff --git a/src/hotspot/share/gc/g1/g1CollectionSet.hpp b/src/hotspot/share/gc/g1/g1CollectionSet.hpp index 133246a52081d..fba166e9c75b0 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSet.hpp +++ b/src/hotspot/share/gc/g1/g1CollectionSet.hpp @@ -177,6 +177,12 @@ class G1CollectionSet { // Prepares old regions in the given set for optional collection later. Does not // add the region to collection set yet. void prepare_optional_regions(G1CollectionCandidateRegionList* regions); + // Moves given old regions from the marking candidates to the retained candidates. + // This makes sure that marking candidates will not remain there to unnecessarily + // prolong the mixed phase. + void move_pinned_marking_to_retained(G1CollectionCandidateRegionList* regions); + // Removes the given list of regions from the retained candidates. + void drop_pinned_retained_regions(G1CollectionCandidateRegionList* regions); // Finalize the young part of the initial collection set. Relabel survivor regions // as Eden and calculate a prediction on how long the evacuation of all young regions @@ -186,8 +192,8 @@ class G1CollectionSet { // can use them. void finalize_incremental_building(); - // Select the old regions of the initial collection set and determine how many optional - // regions we might be able to evacuate in this pause. + // Select the regions comprising the initial and optional collection set from marking + // and retained collection set candidates. void finalize_old_part(double time_remaining_ms); // Iterate the part of the collection set given by the offset and length applying the given diff --git a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp index 426e96ea779ba..9f903bc924f1e 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.cpp @@ -31,15 +31,15 @@ G1CollectionCandidateList::G1CollectionCandidateList() : _candidates(2, mtGC) { } -void G1CollectionCandidateList::set(G1CollectionCandidateList::CandidateInfo* candidate_infos, uint num_infos) { +void G1CollectionCandidateList::set(G1CollectionSetCandidateInfo* candidate_infos, uint num_infos) { assert(_candidates.is_empty(), "must be"); - GrowableArrayFromArray a(candidate_infos, (int)num_infos); + GrowableArrayFromArray a(candidate_infos, (int)num_infos); _candidates.appendAll(&a); } void G1CollectionCandidateList::append_unsorted(HeapRegion* r) { - CandidateInfo c(r, r->calc_gc_efficiency()); + G1CollectionSetCandidateInfo c(r, r->calc_gc_efficiency()); _candidates.append(c); } @@ -58,7 +58,7 @@ void G1CollectionCandidateList::remove(G1CollectionCandidateRegionList* other) { // Create a list from scratch, copying over the elements from the candidate // list not in the other list. Finally deallocate and overwrite the old list. int new_length = _candidates.length() - other->length(); - GrowableArray new_list(new_length, mtGC); + GrowableArray new_list(new_length, mtGC); uint other_idx = 0; @@ -81,10 +81,10 @@ void G1CollectionCandidateList::clear() { #ifndef PRODUCT void G1CollectionCandidateList::verify() { - CandidateInfo* prev = nullptr; + G1CollectionSetCandidateInfo* prev = nullptr; for (uint i = 0; i < (uint)_candidates.length(); i++) { - CandidateInfo& ci = _candidates.at(i); + G1CollectionSetCandidateInfo& ci = _candidates.at(i); assert(prev == nullptr || prev->_gc_efficiency >= ci._gc_efficiency, "Stored gc efficiency must be descending from region %u to %u", prev->_r->hrm_index(), ci._r->hrm_index()); @@ -94,7 +94,7 @@ void G1CollectionCandidateList::verify() { } #endif -int G1CollectionCandidateList::compare(CandidateInfo* ci1, CandidateInfo* ci2) { +int G1CollectionCandidateList::compare(G1CollectionSetCandidateInfo* ci1, G1CollectionSetCandidateInfo* ci2) { // Make sure that null entries are moved to the end. if (ci1->_r == nullptr) { if (ci2->_r == nullptr) { @@ -182,7 +182,7 @@ void G1CollectionSetCandidates::clear() { _last_marking_candidates_length = 0; } -void G1CollectionSetCandidates::set_candidates_from_marking(G1CollectionCandidateList::CandidateInfo* candidate_infos, +void G1CollectionSetCandidates::set_candidates_from_marking(G1CollectionSetCandidateInfo* candidate_infos, uint num_infos) { assert(_marking_regions.length() == 0, "must be empty before adding new ones"); diff --git a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp index 4b0ec643aa9a9..4eb5523d0399e 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.hpp @@ -26,6 +26,8 @@ #define SHARE_GC_G1_G1COLLECTIONSETCANDIDATES_HPP #include "gc/g1/g1CollectionSetCandidates.hpp" +#include "gc/g1/g1_globals.hpp" +#include "gc/shared/gc_globals.hpp" #include "gc/shared/workerThread.hpp" #include "memory/allocation.hpp" #include "runtime/globals.hpp" @@ -64,6 +66,20 @@ class G1CollectionCandidateRegionList { G1CollectionCandidateRegionListIterator end() const { return _regions.end(); } }; +struct G1CollectionSetCandidateInfo { + HeapRegion* _r; + double _gc_efficiency; + uint _num_unreclaimed; // Number of GCs this region has been found unreclaimable. + + G1CollectionSetCandidateInfo() : G1CollectionSetCandidateInfo(nullptr, 0.0) { } + G1CollectionSetCandidateInfo(HeapRegion* r, double gc_efficiency) : _r(r), _gc_efficiency(gc_efficiency), _num_unreclaimed(0) { } + + bool update_num_unreclaimed() { + ++_num_unreclaimed; + return _num_unreclaimed < G1NumCollectionsKeepPinned; + } +}; + class G1CollectionCandidateListIterator : public StackObj { G1CollectionCandidateList* _which; uint _position; @@ -72,7 +88,7 @@ class G1CollectionCandidateListIterator : public StackObj { G1CollectionCandidateListIterator(G1CollectionCandidateList* which, uint position); G1CollectionCandidateListIterator& operator++(); - HeapRegion* operator*(); + G1CollectionSetCandidateInfo* operator*(); bool operator==(const G1CollectionCandidateListIterator& rhs); bool operator!=(const G1CollectionCandidateListIterator& rhs); @@ -83,23 +99,13 @@ class G1CollectionCandidateListIterator : public StackObj { class G1CollectionCandidateList : public CHeapObj { friend class G1CollectionCandidateListIterator; -public: - struct CandidateInfo { - HeapRegion* _r; - double _gc_efficiency; - - CandidateInfo() : CandidateInfo(nullptr, 0.0) { } - CandidateInfo(HeapRegion* r, double gc_efficiency) : _r(r), _gc_efficiency(gc_efficiency) { } - }; - -private: - GrowableArray _candidates; + GrowableArray _candidates; public: G1CollectionCandidateList(); // Put the given set of candidates into this list, preserving the efficiency ordering. - void set(CandidateInfo* candidate_infos, uint num_infos); + void set(G1CollectionSetCandidateInfo* candidate_infos, uint num_infos); // Add the given HeapRegion to this list at the end, (potentially) making the list unsorted. void append_unsorted(HeapRegion* r); // Restore sorting order by decreasing gc efficiency, using the existing efficiency @@ -114,7 +120,7 @@ class G1CollectionCandidateList : public CHeapObj { void clear(); - CandidateInfo& at(uint position) { return _candidates.at(position); } + G1CollectionSetCandidateInfo& at(uint position) { return _candidates.at(position); } uint length() const { return (uint)_candidates.length(); } @@ -123,7 +129,7 @@ class G1CollectionCandidateList : public CHeapObj { // Comparison function to order regions in decreasing GC efficiency order. This // will cause regions with a lot of live objects and large remembered sets to end // up at the end of the list. - static int compare(CandidateInfo* ci1, CandidateInfo* ci2); + static int compare(G1CollectionSetCandidateInfo* ci1, G1CollectionSetCandidateInfo* ci2); G1CollectionCandidateListIterator begin() { return G1CollectionCandidateListIterator(this, 0); @@ -138,9 +144,9 @@ class G1CollectionCandidateList : public CHeapObj { // of the regions returned. class G1CollectionSetCandidatesIterator : public StackObj { G1CollectionSetCandidates* _which; - uint _position; + uint _position; -public: + public: G1CollectionSetCandidatesIterator(G1CollectionSetCandidates* which, uint position); G1CollectionSetCandidatesIterator& operator++(); @@ -198,7 +204,7 @@ class G1CollectionSetCandidates : public CHeapObj { // Merge collection set candidates from marking into the current marking list // (which needs to be empty). - void set_candidates_from_marking(G1CollectionCandidateList::CandidateInfo* candidate_infos, + void set_candidates_from_marking(G1CollectionSetCandidateInfo* candidate_infos, uint num_infos); // The most recent length of the list that had been merged last via // set_candidates_from_marking(). Used for calculating minimum collection set diff --git a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.inline.hpp b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.inline.hpp index 0d391e6bebf70..638a50b474535 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetCandidates.inline.hpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetCandidates.inline.hpp @@ -38,8 +38,8 @@ inline G1CollectionCandidateListIterator& G1CollectionCandidateListIterator::ope return *this; } -inline HeapRegion* G1CollectionCandidateListIterator::operator*() { - return _which->_candidates.at(_position)._r; +inline G1CollectionSetCandidateInfo* G1CollectionCandidateListIterator::operator*() { + return &_which->_candidates.at(_position); } inline bool G1CollectionCandidateListIterator::operator==(const G1CollectionCandidateListIterator& rhs) { diff --git a/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp b/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp index 28132ea172b1a..f19488a49a8ae 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetChooser.cpp @@ -39,7 +39,7 @@ // moved to the destination. class G1BuildCandidateRegionsTask : public WorkerTask { - using CandidateInfo = G1CollectionCandidateList::CandidateInfo; + using CandidateInfo = G1CollectionSetCandidateInfo; // Work area for building the set of collection set candidates. Contains references // to heap regions with their GC efficiencies calculated. To reduce contention diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index d41fd381e2365..78e1bec34381a 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -25,8 +25,6 @@ #include "precompiled.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderDataGraph.hpp" -#include "classfile/systemDictionary.hpp" -#include "code/codeCache.hpp" #include "gc/g1/g1BarrierSet.hpp" #include "gc/g1/g1BatchedTask.hpp" #include "gc/g1/g1CardSetMemory.hpp" @@ -1131,13 +1129,10 @@ class G1UpdateRemSetTrackingBeforeRebuildTask : public WorkerTask { // Distribute the given marked bytes across the humongous object starting // with hr and note end of marking for these regions. void distribute_marked_bytes(HeapRegion* hr, size_t marked_bytes) { - size_t const obj_size_in_words = cast_to_oop(hr->bottom())->size(); - - // "Distributing" zero words means that we only note end of marking for these - // regions. - assert(marked_bytes == 0 || obj_size_in_words * HeapWordSize == marked_bytes, + // Dead humongous objects (marked_bytes == 0) may have already been unloaded. + assert(marked_bytes == 0 || cast_to_oop(hr->bottom())->size() * HeapWordSize == marked_bytes, "Marked bytes should either be 0 or the same as humongous object (%zu) but is %zu", - obj_size_in_words * HeapWordSize, marked_bytes); + cast_to_oop(hr->bottom())->size() * HeapWordSize, marked_bytes); auto distribute_bytes = [&] (HeapRegion* r) { size_t const bytes_to_add = MIN2(HeapRegion::GrainBytes, marked_bytes); @@ -1148,10 +1143,6 @@ class G1UpdateRemSetTrackingBeforeRebuildTask : public WorkerTask { marked_bytes -= bytes_to_add; }; _g1h->humongous_obj_regions_iterate(hr, distribute_bytes); - - assert(marked_bytes == 0, - "%zu bytes left after distributing space across %zu regions", - marked_bytes, G1CollectedHeap::humongous_obj_size_in_regions(obj_size_in_words)); } void update_marked_bytes(HeapRegion* hr) { @@ -1262,6 +1253,12 @@ void G1ConcurrentMark::remark() { if (mark_finished) { weak_refs_work(); + // Unload Klasses, String, Code Cache, etc. + if (ClassUnloadingWithConcurrentMark) { + G1CMIsAliveClosure is_alive(_g1h); + _g1h->unload_classes_and_code("Class Unloading", &is_alive, _gc_timer_cm); + } + SATBMarkQueueSet& satb_mq_set = G1BarrierSet::satb_mark_queue_set(); // We're done with marking. // This is the end of the marking cycle, we're expected all @@ -1299,12 +1296,6 @@ void G1ConcurrentMark::remark() { reclaim_empty_regions(); } - // Clean out dead classes - if (ClassUnloadingWithConcurrentMark) { - GCTraceTime(Debug, gc, phases) debug("Purge Metaspace", _gc_timer_cm); - ClassLoaderDataGraph::purge(/*at_safepoint*/true); - } - // Potentially, some empty-regions have been reclaimed; make this a // "collection" so that pending allocation can retry before attempting a // GC pause. @@ -1345,6 +1336,8 @@ void G1ConcurrentMark::remark() { _remark_weak_ref_times.add((now - mark_work_end) * 1000.0); _remark_times.add((now - start) * 1000.0); + _g1h->update_parallel_gc_threads_cpu_time(); + policy->record_concurrent_mark_remark_end(); } @@ -1370,7 +1363,10 @@ class G1ReclaimEmptyRegionsTask : public WorkerTask { uint humongous_regions_removed() { return _humongous_regions_removed; } bool do_heap_region(HeapRegion *hr) { - if (hr->used() > 0 && hr->live_bytes() == 0 && !hr->is_young()) { + bool can_reclaim = hr->used() > 0 && hr->live_bytes() == 0 && + !hr->is_young() && !hr->has_pinned_objects(); + + if (can_reclaim) { log_trace(gc, marking)("Reclaimed empty old gen region %u (%s) bot " PTR_FORMAT, hr->hrm_index(), hr->get_short_type_str(), p2i(hr->bottom())); _freed_bytes += hr->used(); @@ -1629,9 +1625,6 @@ class G1CMRefProcProxyTask : public RefProcProxyTask { void G1ConcurrentMark::weak_refs_work() { ResourceMark rm; - // Is alive closure. - G1CMIsAliveClosure g1_is_alive(_g1h); - { GCTraceTime(Debug, gc, phases) debug("Reference Processing", _gc_timer_cm); @@ -1688,18 +1681,8 @@ void G1ConcurrentMark::weak_refs_work() { { GCTraceTime(Debug, gc, phases) debug("Weak Processing", _gc_timer_cm); - WeakProcessor::weak_oops_do(_g1h->workers(), &g1_is_alive, &do_nothing_cl, 1); - } - - // Unload Klasses, String, Code Cache, etc. - if (ClassUnloadingWithConcurrentMark) { - GCTraceTime(Debug, gc, phases) debug("Class Unloading", _gc_timer_cm); - { - CodeCache::UnlinkingScope scope(&g1_is_alive); - bool unloading_occurred = SystemDictionary::do_unloading(_gc_timer_cm); - _g1h->complete_cleaning(unloading_occurred); - } - CodeCache::flush_unlinked_nmethods(); + G1CMIsAliveClosure is_alive(_g1h); + WeakProcessor::weak_oops_do(_g1h->workers(), &is_alive, &do_nothing_cl, 1); } } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp index a04cea5e87b57..37e76a73fe79c 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp @@ -39,6 +39,7 @@ #include "gc/shared/suspendibleThreadSet.hpp" #include "logging/log.hpp" #include "memory/resourceArea.hpp" +#include "runtime/cpuTimeCounters.hpp" #include "runtime/handles.inline.hpp" #include "runtime/vmThread.hpp" #include "utilities/debug.hpp" @@ -134,6 +135,8 @@ void G1ConcurrentMarkThread::run_service() { concurrent_cycle_end(_state == FullMark && !_cm->has_aborted()); _vtime_accum = (os::elapsedVTime() - _vtime_start); + + update_threads_cpu_time(); } _cm->root_regions()->cancel_scan(); } @@ -169,6 +172,7 @@ bool G1ConcurrentMarkThread::phase_clear_cld_claimed_marks() { bool G1ConcurrentMarkThread::phase_scan_root_regions() { G1ConcPhaseTimer p(_cm, "Concurrent Scan Root Regions"); _cm->scan_root_regions(); + update_threads_cpu_time(); return _cm->has_aborted(); } @@ -228,6 +232,7 @@ bool G1ConcurrentMarkThread::subphase_delay_to_keep_mmu_before_remark() { bool G1ConcurrentMarkThread::subphase_remark() { ConcurrentGCBreakpoints::at("BEFORE MARKING COMPLETED"); + update_threads_cpu_time(); VM_G1PauseRemark op; VMThread::execute(&op); return _cm->has_aborted(); @@ -237,6 +242,7 @@ bool G1ConcurrentMarkThread::phase_rebuild_and_scrub() { ConcurrentGCBreakpoints::at("AFTER REBUILD STARTED"); G1ConcPhaseTimer p(_cm, "Concurrent Rebuild Remembered Sets and Scrub Regions"); _cm->rebuild_and_scrub(); + update_threads_cpu_time(); return _cm->has_aborted(); } @@ -336,3 +342,12 @@ void G1ConcurrentMarkThread::concurrent_cycle_end(bool mark_cycle_completed) { _cm->concurrent_cycle_end(mark_cycle_completed); ConcurrentGCBreakpoints::notify_active_to_idle(); } + +void G1ConcurrentMarkThread::update_threads_cpu_time() { + if (!UsePerfData || !os::is_thread_cpu_time_supported()) { + return; + } + ThreadTotalCPUTimeClosure tttc(CPUTimeGroups::CPUTimeType::gc_conc_mark); + tttc.do_thread(this); + _cm->threads_do(&tttc); +} diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.hpp index 37b4573afc0be..55655ac2c14ca 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.hpp @@ -108,6 +108,9 @@ class G1ConcurrentMarkThread: public ConcurrentGCThread { bool in_progress() const; bool in_undo_mark() const; + + // Update the perf data counter for concurrent mark. + void update_threads_cpu_time(); }; #endif // SHARE_GC_G1_G1CONCURRENTMARKTHREAD_HPP diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp index aebdd2c43f5a1..b05dd34009a6d 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp @@ -175,7 +175,7 @@ G1ConcurrentRefine::G1ConcurrentRefine(G1Policy* policy) : {} jint G1ConcurrentRefine::initialize() { - return _thread_control.initialize(this, max_num_threads()); + return _thread_control.initialize(this, G1ConcRefinementThreads); } G1ConcurrentRefine* G1ConcurrentRefine::create(G1Policy* policy, jint* ecode) { @@ -199,10 +199,6 @@ void G1ConcurrentRefine::threads_do(ThreadClosure *tc) { _thread_control.worker_threads_do(tc); } -uint G1ConcurrentRefine::max_num_threads() { - return G1ConcRefinementThreads; -} - void G1ConcurrentRefine::update_pending_cards_target(double logged_cards_time_ms, size_t processed_logged_cards, size_t predicted_thread_buffer_cards, diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp index 30a8fe7f75731..4cb66d5d625f4 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp @@ -215,9 +215,6 @@ class G1ConcurrentRefine : public CHeapObj { // Iterate over all concurrent refinement threads applying the given closure. void threads_do(ThreadClosure *tc); - - // Maximum number of refinement threads. - static uint max_num_threads(); }; #endif // SHARE_GC_G1_G1CONCURRENTREFINE_HPP diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp index 5278fc2861a00..ed69ac08d1bf0 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp @@ -30,6 +30,7 @@ #include "gc/g1/g1DirtyCardQueue.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "logging/log.hpp" +#include "runtime/cpuTimeCounters.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" #include "runtime/thread.hpp" @@ -74,11 +75,7 @@ void G1ConcurrentRefineThread::run_service() { } } report_inactive("Deactivated", _refinement_stats - active_stats_start); - if (os::supports_vtime()) { - _vtime_accum = (os::elapsedVTime() - _vtime_start); - } else { - _vtime_accum = 0.0; - } + track_usage(); } log_debug(gc, refine)("Stopping %d", _worker_id); @@ -137,6 +134,7 @@ class G1PrimaryConcurrentRefineThread final : public G1ConcurrentRefineThread { bool wait_for_completed_buffers() override; bool maybe_deactivate() override; void do_refinement_step() override; + void track_usage() override; public: G1PrimaryConcurrentRefineThread(G1ConcurrentRefine* cr) : @@ -182,6 +180,15 @@ void G1PrimaryConcurrentRefineThread::do_refinement_step() { } } +void G1PrimaryConcurrentRefineThread::track_usage() { + G1ConcurrentRefineThread::track_usage(); + // The primary thread is responsible for updating the CPU time for all workers. + if (UsePerfData && os::is_thread_cpu_time_supported()) { + ThreadTotalCPUTimeClosure tttc(CPUTimeGroups::CPUTimeType::gc_conc_refine); + cr()->threads_do(&tttc); + } +} + class G1SecondaryConcurrentRefineThread final : public G1ConcurrentRefineThread { bool wait_for_completed_buffers() override; void do_refinement_step() override; diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp index 623bf05acc998..0711b61b194fb 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp @@ -71,6 +71,16 @@ class G1ConcurrentRefineThread: public ConcurrentGCThread { // precondition: this is the current thread. virtual void do_refinement_step() = 0; + // Update concurrent refine threads stats. + // If we are in Primary thread, we additionally update CPU time tracking. + virtual void track_usage() { + if (os::supports_vtime()) { + _vtime_accum = (os::elapsedVTime() - _vtime_start); + } else { + _vtime_accum = 0.0; + } + }; + // Helper for do_refinement_step implementations. Try to perform some // refinement work, limited by stop_at. Returns true if any refinement work // was performed, false if no work available per stop_at. diff --git a/src/hotspot/share/gc/g1/g1EvacFailureRegions.cpp b/src/hotspot/share/gc/g1/g1EvacFailureRegions.cpp index 6964028d1f87d..a308fe7a3934a 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailureRegions.cpp +++ b/src/hotspot/share/gc/g1/g1EvacFailureRegions.cpp @@ -33,29 +33,35 @@ #include "utilities/bitMap.inline.hpp" G1EvacFailureRegions::G1EvacFailureRegions() : - _regions_failed_evacuation(mtGC), - _evac_failure_regions(nullptr), - _evac_failure_regions_cur_length(0) { } + _regions_evac_failed(mtGC), + _regions_pinned(mtGC), + _regions_alloc_failed(mtGC), + _evac_failed_regions(nullptr), + _num_regions_evac_failed(0) { } G1EvacFailureRegions::~G1EvacFailureRegions() { - assert(_evac_failure_regions == nullptr, "not cleaned up"); + assert(_evac_failed_regions == nullptr, "not cleaned up"); } void G1EvacFailureRegions::pre_collection(uint max_regions) { - Atomic::store(&_evac_failure_regions_cur_length, 0u); - _regions_failed_evacuation.resize(max_regions); - _evac_failure_regions = NEW_C_HEAP_ARRAY(uint, max_regions, mtGC); + Atomic::store(&_num_regions_evac_failed, 0u); + _regions_evac_failed.resize(max_regions); + _regions_pinned.resize(max_regions); + _regions_alloc_failed.resize(max_regions); + _evac_failed_regions = NEW_C_HEAP_ARRAY(uint, max_regions, mtGC); } void G1EvacFailureRegions::post_collection() { - _regions_failed_evacuation.resize(0); + _regions_evac_failed.resize(0); + _regions_pinned.resize(0); + _regions_alloc_failed.resize(0); - FREE_C_HEAP_ARRAY(uint, _evac_failure_regions); - _evac_failure_regions = nullptr; + FREE_C_HEAP_ARRAY(uint, _evac_failed_regions); + _evac_failed_regions = nullptr; } bool G1EvacFailureRegions::contains(uint region_idx) const { - return _regions_failed_evacuation.par_at(region_idx, memory_order_relaxed); + return _regions_evac_failed.par_at(region_idx, memory_order_relaxed); } void G1EvacFailureRegions::par_iterate(HeapRegionClosure* closure, @@ -63,7 +69,7 @@ void G1EvacFailureRegions::par_iterate(HeapRegionClosure* closure, uint worker_id) const { G1CollectedHeap::heap()->par_iterate_regions_array(closure, hrclaimer, - _evac_failure_regions, - Atomic::load(&_evac_failure_regions_cur_length), + _evac_failed_regions, + Atomic::load(&_num_regions_evac_failed), worker_id); } diff --git a/src/hotspot/share/gc/g1/g1EvacFailureRegions.hpp b/src/hotspot/share/gc/g1/g1EvacFailureRegions.hpp index 043d69ff143ba..b8f9ea8003884 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailureRegions.hpp +++ b/src/hotspot/share/gc/g1/g1EvacFailureRegions.hpp @@ -25,32 +25,43 @@ #ifndef SHARE_GC_G1_G1EVACFAILUREREGIONS_HPP #define SHARE_GC_G1_G1EVACFAILUREREGIONS_HPP -#include "runtime/atomic.hpp" #include "utilities/bitMap.hpp" class G1AbstractSubTask; -class G1HeapRegionChunkClosure; class HeapRegionClosure; class HeapRegionClaimer; -// This class records for every region on the heap whether evacuation failed for it, -// and records for every evacuation failure region to speed up iteration of these -// regions in post evacuation phase. +// This class records for every region on the heap whether it had experienced an +// evacuation failure. +// An evacuation failure may occur due to pinning or due to allocation failure +// (not enough to-space). For every such occurrence the class records region +// information to speed up iteration of these regions in various gc phases. +// +// Pinned regions may experience an allocation failure at the same time as G1 +// tries to evacuate anything but objects that are possible to be pinned. So +// +// _num_regions_pinned + _num_regions_alloc_failed >= _num_regions_evac_failed +// class G1EvacFailureRegions { - // Records for every region on the heap whether evacuation failed for it. - CHeapBitMap _regions_failed_evacuation; - // Regions (index) of evacuation failed in the current collection. - uint* _evac_failure_regions; + // Records for every region on the heap whether the region has experienced an + // evacuation failure. + CHeapBitMap _regions_evac_failed; + // Records for every region on the heap whether the evacuation failure cause + // has been allocation failure or region pinning. + CHeapBitMap _regions_pinned; + CHeapBitMap _regions_alloc_failed; + // Evacuation failed regions (indexes) in the current collection. + uint* _evac_failed_regions; // Number of regions evacuation failed in the current collection. - volatile uint _evac_failure_regions_cur_length; + volatile uint _num_regions_evac_failed; public: G1EvacFailureRegions(); ~G1EvacFailureRegions(); uint get_region_idx(uint idx) const { - assert(idx < _evac_failure_regions_cur_length, "precondition"); - return _evac_failure_regions[idx]; + assert(idx < _num_regions_evac_failed, "precondition"); + return _evac_failed_regions[idx]; } // Sets up the bitmap and failed regions array for addition. @@ -66,18 +77,16 @@ class G1EvacFailureRegions { // Return a G1AbstractSubTask which does necessary preparation for evacuation failed regions G1AbstractSubTask* create_prepare_regions_task(); - uint num_regions_failed_evacuation() const { - return Atomic::load(&_evac_failure_regions_cur_length); - } + inline uint num_regions_evac_failed() const; - bool evacuation_failed() const { - return num_regions_failed_evacuation() > 0; - } + inline bool has_regions_evac_failed() const; + inline bool has_regions_evac_pinned() const; + inline bool has_regions_alloc_failed() const; // Record that the garbage collection encountered an evacuation failure in the // given region. Returns whether this has been the first occurrence of an evacuation // failure in that region. - inline bool record(uint region_idx); + inline bool record(uint worker_id, uint region_idx, bool cause_pinned); }; #endif //SHARE_GC_G1_G1EVACFAILUREREGIONS_HPP diff --git a/src/hotspot/share/gc/g1/g1EvacFailureRegions.inline.hpp b/src/hotspot/share/gc/g1/g1EvacFailureRegions.inline.hpp index 48d9eb6deaac8..28be8562b523f 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailureRegions.inline.hpp +++ b/src/hotspot/share/gc/g1/g1EvacFailureRegions.inline.hpp @@ -27,19 +27,60 @@ #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1EvacFailureRegions.hpp" +#include "gc/g1/g1GCPhaseTimes.hpp" #include "runtime/atomic.hpp" -bool G1EvacFailureRegions::record(uint region_idx) { - bool success = _regions_failed_evacuation.par_set_bit(region_idx, - memory_order_relaxed); +uint G1EvacFailureRegions::num_regions_evac_failed() const { + return Atomic::load(&_num_regions_evac_failed); +} + +bool G1EvacFailureRegions::has_regions_evac_failed() const { + return num_regions_evac_failed() > 0; +} + +bool G1EvacFailureRegions::has_regions_evac_pinned() const { + G1GCPhaseTimes* p = G1CollectedHeap::heap()->phase_times(); + size_t count = p->sum_thread_work_items(G1GCPhaseTimes::RestoreEvacuationFailedRegions, + G1GCPhaseTimes::RestoreEvacFailureRegionsPinnedNum); + return count != 0; +} + +bool G1EvacFailureRegions::has_regions_alloc_failed() const { + G1GCPhaseTimes* p = G1CollectedHeap::heap()->phase_times(); + size_t count = p->sum_thread_work_items(G1GCPhaseTimes::RestoreEvacuationFailedRegions, + G1GCPhaseTimes::RestoreEvacFailureRegionsAllocFailedNum); + return count != 0; +} + +bool G1EvacFailureRegions::record(uint worker_id, uint region_idx, bool cause_pinned) { + bool success = _regions_evac_failed.par_set_bit(region_idx, + memory_order_relaxed); if (success) { - size_t offset = Atomic::fetch_then_add(&_evac_failure_regions_cur_length, 1u); - _evac_failure_regions[offset] = region_idx; + size_t offset = Atomic::fetch_then_add(&_num_regions_evac_failed, 1u); + _evac_failed_regions[offset] = region_idx; G1CollectedHeap* g1h = G1CollectedHeap::heap(); HeapRegion* hr = g1h->region_at(region_idx); hr->note_evacuation_failure(); } + + if (cause_pinned) { + if (_regions_pinned.par_set_bit(region_idx, memory_order_relaxed)) { + G1GCPhaseTimes* p = G1CollectedHeap::heap()->phase_times(); + p->record_or_add_thread_work_item(G1GCPhaseTimes::RestoreEvacuationFailedRegions, + worker_id, + 1, + G1GCPhaseTimes::RestoreEvacFailureRegionsPinnedNum); + } + } else { + if (_regions_alloc_failed.par_set_bit(region_idx, memory_order_relaxed)) { + G1GCPhaseTimes* p = G1CollectedHeap::heap()->phase_times(); + p->record_or_add_thread_work_item(G1GCPhaseTimes::RestoreEvacuationFailedRegions, + worker_id, + 1, + G1GCPhaseTimes::RestoreEvacFailureRegionsAllocFailedNum); + } + } return success; } diff --git a/src/hotspot/share/gc/g1/g1FromCardCache.cpp b/src/hotspot/share/gc/g1/g1FromCardCache.cpp index d3e7af768b5a0..062130f40ab7f 100644 --- a/src/hotspot/share/gc/g1/g1FromCardCache.cpp +++ b/src/hotspot/share/gc/g1/g1FromCardCache.cpp @@ -81,7 +81,7 @@ void G1FromCardCache::print(outputStream* out) { #endif uint G1FromCardCache::num_par_rem_sets() { - return G1DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::max_num_threads() + MAX2(ConcGCThreads, ParallelGCThreads); + return G1DirtyCardQueueSet::num_par_ids() + G1ConcRefinementThreads + MAX2(ConcGCThreads, ParallelGCThreads); } void G1FromCardCache::clear(uint region_idx) { diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 62e7cdfabd4fc..6ae43c770cc4e 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -24,9 +24,6 @@ #include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" -#include "classfile/systemDictionary.hpp" -#include "code/codeCache.hpp" -#include "compiler/oopMap.hpp" #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1FullCollector.inline.hpp" #include "gc/g1/g1FullGCAdjustTask.hpp" @@ -41,6 +38,7 @@ #include "gc/g1/g1RegionMarkStatsCache.inline.hpp" #include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/preservedMarks.inline.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/referenceProcessor.hpp" #include "gc/shared/verifyOption.hpp" #include "gc/shared/weakProcessor.inline.hpp" @@ -257,9 +255,9 @@ void G1FullCollector::complete_collection() { void G1FullCollector::before_marking_update_attribute_table(HeapRegion* hr) { if (hr->is_free()) { _region_attr_table.set_free(hr->hrm_index()); - } else if (hr->is_humongous()) { - // Humongous objects will never be moved in the "main" compaction phase, but - // afterwards in a special phase if needed. + } else if (hr->is_humongous() || hr->has_pinned_objects()) { + // Humongous objects or pinned regions will never be moved in the "main" + // compaction phase, but non-pinned regions might afterwards in a special phase. _region_attr_table.set_skip_compacting(hr->hrm_index()); } else { // Everything else should be compacted. @@ -319,14 +317,7 @@ void G1FullCollector::phase1_mark_live_objects() { // Class unloading and cleanup. if (ClassUnloading) { - GCTraceTime(Debug, gc, phases) debug("Phase 1: Class Unloading and Cleanup", scope()->timer()); - { - CodeCache::UnlinkingScope unloading_scope(&_is_alive); - // Unload classes and purge the SystemDictionary. - bool unloading_occurred = SystemDictionary::do_unloading(scope()->timer()); - _heap->complete_cleaning(unloading_occurred); - } - CodeCache::flush_unlinked_nmethods(); + _heap->unload_classes_and_code("Phase 1: Class Unloading and Cleanup", &_is_alive, scope()->timer()); } { @@ -454,10 +445,16 @@ void G1FullCollector::phase2d_prepare_humongous_compaction() { region_index++; continue; } else if (hr->is_starts_humongous()) { - uint num_regions = humongous_cp->forward_humongous(hr); - region_index += num_regions; // Skip over the continues humongous regions. + size_t obj_size = cast_to_oop(hr->bottom())->size(); + uint num_regions = (uint)G1CollectedHeap::humongous_obj_size_in_regions(obj_size); + // Even during last-ditch compaction we should not move pinned humongous objects. + if (!hr->has_pinned_objects()) { + humongous_cp->forward_humongous(hr); + } + region_index += num_regions; // Advance over all humongous regions. continue; } else if (is_compaction_target(region_index)) { + assert(!hr->has_pinned_objects(), "pinned regions should not be compaction targets"); // Add the region to the humongous compaction point. humongous_cp->add(hr); } diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp index 8c4fa4eb2e030..2ed6ccd4735fb 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp @@ -67,6 +67,7 @@ void G1FullGCCompactTask::copy_object_to_new_location(oop obj) { } void G1FullGCCompactTask::compact_region(HeapRegion* hr) { + assert(!hr->has_pinned_objects(), "Should be no region with pinned objects in compaction queue"); assert(!hr->is_humongous(), "Should be no humongous regions in compaction queue"); if (!collector()->is_free(hr->hrm_index())) { diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp index dabff2bc9fb5a..7669771eb6c3c 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp @@ -145,7 +145,7 @@ void G1FullGCCompactionPoint::add_humongous(HeapRegion* hr) { }); } -uint G1FullGCCompactionPoint::forward_humongous(HeapRegion* hr) { +void G1FullGCCompactionPoint::forward_humongous(HeapRegion* hr) { assert(hr->is_starts_humongous(), "Sanity!"); oop obj = cast_to_oop(hr->bottom()); @@ -153,7 +153,7 @@ uint G1FullGCCompactionPoint::forward_humongous(HeapRegion* hr) { uint num_regions = (uint)G1CollectedHeap::humongous_obj_size_in_regions(obj_size); if (!has_regions()) { - return num_regions; + return; } // Find contiguous compaction target regions for the humongous object. @@ -161,7 +161,7 @@ uint G1FullGCCompactionPoint::forward_humongous(HeapRegion* hr) { if (range_begin == UINT_MAX) { // No contiguous compaction target regions found, so the object cannot be moved. - return num_regions; + return; } // Preserve the mark for the humongous object as the region was initially not compacting. @@ -177,7 +177,7 @@ uint G1FullGCCompactionPoint::forward_humongous(HeapRegion* hr) { // Remove covered regions from compaction target candidates. _compaction_regions->remove_range(range_begin, (range_begin + num_regions)); - return num_regions; + return; } uint G1FullGCCompactionPoint::find_contiguous_before(HeapRegion* hr, uint num_regions) { diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp index ea8351f1299f8..ca76f7e6b9408 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp @@ -55,7 +55,7 @@ class G1FullGCCompactionPoint : public CHeapObj { void initialize(HeapRegion* hr); void update(); void forward(oop object, size_t size); - uint forward_humongous(HeapRegion* hr); + void forward_humongous(HeapRegion* hr); void add(HeapRegion* hr); void add_humongous(HeapRegion* hr); diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp index 76a647a3da373..2a2add76f48c6 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp @@ -42,7 +42,7 @@ void G1DetermineCompactionQueueClosure::free_empty_humongous_region(HeapRegion* inline bool G1DetermineCompactionQueueClosure::should_compact(HeapRegion* hr) const { // There is no need to iterate and forward objects in non-movable regions ie. // prepare them for compaction. - if (hr->is_humongous()) { + if (hr->is_humongous() || hr->has_pinned_objects()) { return false; } size_t live_words = _collector->live_words(hr->hrm_index()); @@ -73,29 +73,41 @@ inline void G1DetermineCompactionQueueClosure::add_to_compaction_queue(HeapRegio cp->add(hr); } +static bool has_pinned_objects(HeapRegion* hr) { + return hr->has_pinned_objects() || + (hr->is_humongous() && hr->humongous_start_region()->has_pinned_objects()); +} + inline bool G1DetermineCompactionQueueClosure::do_heap_region(HeapRegion* hr) { if (should_compact(hr)) { assert(!hr->is_humongous(), "moving humongous objects not supported."); add_to_compaction_queue(hr); - } else { - assert(hr->containing_set() == nullptr, "already cleared by PrepareRegionsClosure"); - if (hr->is_humongous()) { - oop obj = cast_to_oop(hr->humongous_start_region()->bottom()); - bool is_empty = !_collector->mark_bitmap()->is_marked(obj); - if (is_empty) { - free_empty_humongous_region(hr); - } else { - _collector->set_has_humongous(); - } + return false; + } + + assert(hr->containing_set() == nullptr, "already cleared by PrepareRegionsClosure"); + if (has_pinned_objects(hr)) { + // First check regions with pinned objects: they need to be skipped regardless + // of region type and never be considered for reclamation. + assert(_collector->is_skip_compacting(hr->hrm_index()), "pinned region %u must be skip_compacting", hr->hrm_index()); + log_trace(gc, phases)("Phase 2: skip compaction region index: %u (%s), has pinned objects", + hr->hrm_index(), hr->get_short_type_str()); + } else if (hr->is_humongous()) { + oop obj = cast_to_oop(hr->humongous_start_region()->bottom()); + bool is_empty = !_collector->mark_bitmap()->is_marked(obj); + if (is_empty) { + free_empty_humongous_region(hr); } else { - assert(MarkSweepDeadRatio > 0, - "only skip compaction for other regions when MarkSweepDeadRatio > 0"); + _collector->set_has_humongous(); + } + } else { + assert(MarkSweepDeadRatio > 0, + "only skip compaction for other regions when MarkSweepDeadRatio > 0"); - // Too many live objects in the region; skip compacting it. - _collector->update_from_compacting_to_skip_compacting(hr->hrm_index()); - log_trace(gc, phases)("Phase 2: skip compaction region index: %u, live words: " SIZE_FORMAT, + // Too many live objects in the region; skip compacting it. + _collector->update_from_compacting_to_skip_compacting(hr->hrm_index()); + log_trace(gc, phases)("Phase 2: skip compaction region index: %u, live words: " SIZE_FORMAT, hr->hrm_index(), _collector->live_words(hr->hrm_index())); - } } return false; diff --git a/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp b/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp index 003cc2b3f2b89..ddbaaa0b75ef2 100644 --- a/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCResetMetadataTask.cpp @@ -89,10 +89,11 @@ void G1FullGCResetMetadataTask::G1ResetMetadataClosure::reset_skip_compacting(He if (hr->is_humongous()) { oop obj = cast_to_oop(hr->humongous_start_region()->bottom()); - assert(_collector->mark_bitmap()->is_marked(obj), "must be live"); + assert(hr->humongous_start_region()->has_pinned_objects() || + _collector->mark_bitmap()->is_marked(obj), "must be live"); } else { - assert(_collector->live_words(region_index) > _collector->scope()->region_compaction_threshold(), - "should be quite full"); + assert(hr->has_pinned_objects() || _collector->live_words(region_index) > _collector->scope()->region_compaction_threshold(), + "should be quite full or pinned %u", region_index); } assert(_collector->compaction_top(hr) == nullptr, diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp index 83824c486562d..43b582b7dd901 100644 --- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp +++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp @@ -97,7 +97,7 @@ G1GCPhaseTimes::G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads) : _gc_par_phases[GCWorkerEnd] = new WorkerDataArray("GCWorkerEnd", "GC Worker End (ms):", max_gc_threads); _gc_par_phases[Other] = new WorkerDataArray("Other", "GC Worker Other (ms):", max_gc_threads); _gc_par_phases[MergePSS] = new WorkerDataArray("MergePSS", "Merge Per-Thread State (ms):", max_gc_threads); - _gc_par_phases[RestoreRetainedRegions] = new WorkerDataArray("RestoreRetainedRegions", "Restore Retained Regions (ms):", max_gc_threads); + _gc_par_phases[RestoreEvacuationFailedRegions] = new WorkerDataArray("RestoreEvacuationFailedRegions", "Restore Evacuation Failed Regions (ms):", max_gc_threads); _gc_par_phases[RemoveSelfForwards] = new WorkerDataArray("RemoveSelfForwards", "Remove Self Forwards (ms):", max_gc_threads); _gc_par_phases[ClearCardTable] = new WorkerDataArray("ClearLoggedCards", "Clear Logged Cards (ms):", max_gc_threads); _gc_par_phases[RecalculateUsed] = new WorkerDataArray("RecalculateUsed", "Recalculate Used Memory (ms):", max_gc_threads); @@ -132,8 +132,9 @@ G1GCPhaseTimes::G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads) : _gc_par_phases[MergePSS]->create_thread_work_items("LAB Undo Waste", MergePSSLABUndoWasteBytes); _gc_par_phases[MergePSS]->create_thread_work_items("Evac Fail Extra Cards", MergePSSEvacFailExtra); - _gc_par_phases[RestoreRetainedRegions]->create_thread_work_items("Evacuation Failed Regions:", RestoreRetainedRegionsFailedNum); - _gc_par_phases[RestoreRetainedRegions]->create_thread_work_items("New Retained Regions:", RestoreRetainedRegionsRetainedNum); + _gc_par_phases[RestoreEvacuationFailedRegions]->create_thread_work_items("Evacuation Failed Regions:", RestoreEvacFailureRegionsEvacFailedNum); + _gc_par_phases[RestoreEvacuationFailedRegions]->create_thread_work_items("Pinned Regions:", RestoreEvacFailureRegionsPinnedNum); + _gc_par_phases[RestoreEvacuationFailedRegions]->create_thread_work_items("Allocation Failed Regions:", RestoreEvacFailureRegionsAllocFailedNum); _gc_par_phases[RemoveSelfForwards]->create_thread_work_items("Forward Chunks:", RemoveSelfForwardChunksNum); _gc_par_phases[RemoveSelfForwards]->create_thread_work_items("Empty Forward Chunks:", RemoveSelfForwardEmptyChunksNum); @@ -502,7 +503,7 @@ double G1GCPhaseTimes::print_post_evacuate_collection_set(bool evacuation_failed debug_phase(_gc_par_phases[ClearCardTable], 1); debug_phase(_gc_par_phases[RecalculateUsed], 1); if (evacuation_failed) { - debug_phase(_gc_par_phases[RestoreRetainedRegions], 1); + debug_phase(_gc_par_phases[RestoreEvacuationFailedRegions], 1); debug_phase(_gc_par_phases[RemoveSelfForwards], 2); } diff --git a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp index de03ecab99ff6..713b411bda110 100644 --- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp +++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp @@ -79,7 +79,7 @@ class G1GCPhaseTimes : public CHeapObj { RebuildFreeList, SampleCollectionSetCandidates, MergePSS, - RestoreRetainedRegions, + RestoreEvacuationFailedRegions, RemoveSelfForwards, ClearCardTable, RecalculateUsed, @@ -146,9 +146,10 @@ class G1GCPhaseTimes : public CHeapObj { MergePSSEvacFailExtra }; - enum RestoreRetainedRegionsWorkItems { - RestoreRetainedRegionsFailedNum, - RestoreRetainedRegionsRetainedNum + enum RestoreEvacFailureRegionsWorkItems { + RestoreEvacFailureRegionsEvacFailedNum, // How many regions experienced an evacuation failure (pinned or allocation failure) + RestoreEvacFailureRegionsPinnedNum, // How many regions were found as pinned. + RestoreEvacFailureRegionsAllocFailedNum // How many regions were found experiencing an allocation failure. }; enum RemoveSelfForwardsWorkItems { diff --git a/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp b/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp index 7d2ab4f26ea5b..e5a10858ed126 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp @@ -36,10 +36,14 @@ struct G1HeapRegionAttr { // remset_is_tracked_t is essentially bool, but we need precise control // on the size, and sizeof(bool) is implementation specific. typedef uint8_t remset_is_tracked_t; + // _is_pinned_t is essentially bool, but we want precise control + // on the size, and sizeof(bool) is implementation specific. + typedef uint8_t is_pinned_t; private: remset_is_tracked_t _remset_is_tracked; region_type_t _type; + is_pinned_t _is_pinned; public: // Selection of the values for the _type field were driven to micro-optimize the @@ -59,9 +63,8 @@ struct G1HeapRegionAttr { static const region_type_t Old = 1; // The region is in the collection set and an old region. static const region_type_t Num = 2; - G1HeapRegionAttr(region_type_t type = NotInCSet, bool remset_is_tracked = false) : - _remset_is_tracked(remset_is_tracked), _type(type) { - + G1HeapRegionAttr(region_type_t type = NotInCSet, bool remset_is_tracked = false, bool is_pinned = false) : + _remset_is_tracked(remset_is_tracked ? 1 : 0), _type(type), _is_pinned(is_pinned ? 1 : 0) { assert(is_valid(), "Invalid type %d", _type); } @@ -82,12 +85,16 @@ struct G1HeapRegionAttr { bool remset_is_tracked() const { return _remset_is_tracked != 0; } void set_new_survivor() { _type = NewSurvivor; } + bool is_pinned() const { return _is_pinned != 0; } + void set_old() { _type = Old; } void clear_humongous_candidate() { assert(is_humongous_candidate() || !is_in_cset(), "must be"); _type = NotInCSet; } + void set_remset_is_tracked(bool value) { _remset_is_tracked = value ? 1 : 0; } + void set_is_pinned(bool value) { _is_pinned = value ? 1 : 0; } bool is_in_cset_or_humongous_candidate() const { return is_in_cset() || is_humongous_candidate(); } bool is_in_cset() const { return type() >= Young; } @@ -136,7 +143,9 @@ class G1HeapRegionAttrBiasedMappedArray : public G1BiasedMappedArrayset_remset_is_tracked(remset_is_tracked); } - void set_in_young(uintptr_t index) { + void set_is_pinned(uintptr_t index, bool is_pinned) { + get_ref_by_index(index)->set_is_pinned(is_pinned); + } + + void set_in_young(uintptr_t index, bool is_pinned) { assert(get_by_index(index).is_default(), "Region attributes at index " INTPTR_FORMAT " should be default but is %s", index, get_by_index(index).get_type_str()); - set_by_index(index, G1HeapRegionAttr(G1HeapRegionAttr::Young, true)); + set_by_index(index, G1HeapRegionAttr(G1HeapRegionAttr::Young, true, is_pinned)); } void set_in_old(uintptr_t index, bool remset_is_tracked) { assert(get_by_index(index).is_default(), "Region attributes at index " INTPTR_FORMAT " should be default but is %s", index, get_by_index(index).get_type_str()); - set_by_index(index, G1HeapRegionAttr(G1HeapRegionAttr::Old, remset_is_tracked)); + // We do not select regions with pinned objects into the collection set. + const bool region_is_pinned = false; + set_by_index(index, G1HeapRegionAttr(G1HeapRegionAttr::Old, remset_is_tracked, region_is_pinned)); } bool is_in_cset_or_humongous_candidate(HeapWord* addr) const { return at(addr).is_in_cset_or_humongous_candidate(); } diff --git a/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp b/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp index c4f2c1284032b..4e0a7dcfc3d6b 100644 --- a/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp +++ b/src/hotspot/share/gc/g1/g1MonitoringSupport.cpp @@ -247,11 +247,10 @@ void G1MonitoringSupport::recalculate_sizes() { _old_gen_used = _overall_used - MIN2(_overall_used, _eden_space_used + _survivor_space_used); uint survivor_list_length = _g1h->survivor_regions_count(); - // Max length includes any potential extensions to the young gen - // we'll do when the GC locker is active. - uint young_list_max_length = _g1h->policy()->young_list_max_length(); - assert(young_list_max_length >= survivor_list_length, "invariant"); - uint eden_list_max_length = young_list_max_length - survivor_list_length; + + uint young_list_target_length = _g1h->policy()->young_list_target_length(); + assert(young_list_target_length >= survivor_list_length, "invariant"); + uint eden_list_max_length = young_list_target_length - survivor_list_length; // First calculate the committed sizes that can be calculated independently. _survivor_space_committed = survivor_list_length * HeapRegion::GrainBytes; diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp index f9fc1fd019814..8d7ee0b1dfdd0 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp @@ -32,7 +32,7 @@ #include "gc/g1/g1RootClosures.hpp" #include "gc/g1/g1StringDedup.hpp" #include "gc/g1/g1Trace.hpp" -#include "gc/g1/g1YoungGCEvacFailureInjector.inline.hpp" +#include "gc/g1/g1YoungGCAllocationFailureInjector.inline.hpp" #include "gc/shared/continuationGCSupport.inline.hpp" #include "gc/shared/partialArrayTaskStepper.inline.hpp" #include "gc/shared/preservedMarks.inline.hpp" @@ -85,7 +85,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, _max_num_optional_regions(collection_set->optional_region_length()), _numa(g1h->numa()), _obj_alloc_stat(nullptr), - EVAC_FAILURE_INJECTOR_ONLY(_evac_failure_inject_counter(0) COMMA) + ALLOCATION_FAILURE_INJECTOR_ONLY(_allocation_failure_inject_counter(0) COMMA) _preserved_marks(preserved_marks), _evacuation_failed_info(), _evac_failure_regions(evac_failure_regions), @@ -427,9 +427,9 @@ HeapWord* G1ParScanThreadState::allocate_copy_slow(G1HeapRegionAttr* dest_attr, return obj_ptr; } -#if EVAC_FAILURE_INJECTOR -bool G1ParScanThreadState::inject_evacuation_failure(uint region_idx) { - return _g1h->evac_failure_injector()->evacuation_should_fail(_evac_failure_inject_counter, region_idx); +#if ALLOCATION_FAILURE_INJECTOR +bool G1ParScanThreadState::inject_allocation_failure(uint region_idx) { + return _g1h->allocation_failure_injector()->allocation_should_fail(_allocation_failure_inject_counter, region_idx); } #endif @@ -461,6 +461,11 @@ oop G1ParScanThreadState::do_copy_to_survivor_space(G1HeapRegionAttr const regio Klass* klass = old->klass(); const size_t word_sz = old->size_given_klass(klass); + // JNI only allows pinning of typeArrays, so we only need to keep those in place. + if (region_attr.is_pinned() && klass->is_typeArray_klass()) { + return handle_evacuation_failure_par(old, old_mark, word_sz, true /* cause_pinned */); + } + uint age = 0; G1HeapRegionAttr dest_attr = next_region_attr(region_attr, old_mark, age); HeapRegion* const from_region = _g1h->heap_region_containing(old); @@ -475,7 +480,7 @@ oop G1ParScanThreadState::do_copy_to_survivor_space(G1HeapRegionAttr const regio if (obj_ptr == nullptr) { // This will either forward-to-self, or detect that someone else has // installed a forwarding pointer. - return handle_evacuation_failure_par(old, old_mark, word_sz); + return handle_evacuation_failure_par(old, old_mark, word_sz, false /* cause_pinned */); } } @@ -483,11 +488,11 @@ oop G1ParScanThreadState::do_copy_to_survivor_space(G1HeapRegionAttr const regio assert(_g1h->is_in_reserved(obj_ptr), "Allocated memory should be in the heap"); // Should this evacuation fail? - if (inject_evacuation_failure(from_region->hrm_index())) { + if (inject_allocation_failure(from_region->hrm_index())) { // Doing this after all the allocation attempts also tests the // undo_allocation() method too. undo_allocation(dest_attr, obj_ptr, word_sz, node_index); - return handle_evacuation_failure_par(old, old_mark, word_sz); + return handle_evacuation_failure_par(old, old_mark, word_sz, false /* cause_pinned */); } // We're going to allocate linearly, so might as well prefetch ahead. @@ -624,7 +629,7 @@ void G1ParScanThreadStateSet::record_unused_optional_region(HeapRegion* hr) { } NOINLINE -oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markWord m, size_t word_sz) { +oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markWord m, size_t word_sz, bool cause_pinned) { assert(_g1h->is_in_cset(old), "Object " PTR_FORMAT " should be in the CSet", p2i(old)); oop forward_ptr = old->forward_to_atomic(old, m, memory_order_relaxed); @@ -632,7 +637,7 @@ oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markWord m, siz // Forward-to-self succeeded. We are the "owner" of the object. HeapRegion* r = _g1h->heap_region_containing(old); - if (_evac_failure_regions->record(r->hrm_index())) { + if (_evac_failure_regions->record(_worker_id, r->hrm_index(), cause_pinned)) { _g1h->hr_printer()->evac_failure(r); } diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp index d1e8c0cb6d676..4f72e61f82be7 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp @@ -28,7 +28,7 @@ #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1RedirtyCardsQueue.hpp" #include "gc/g1/g1OopClosures.hpp" -#include "gc/g1/g1YoungGCEvacFailureInjector.hpp" +#include "gc/g1/g1YoungGCAllocationFailureInjector.hpp" #include "gc/g1/g1_globals.hpp" #include "gc/shared/ageTable.hpp" #include "gc/shared/copyFailedInfo.hpp" @@ -104,7 +104,7 @@ class G1ParScanThreadState : public CHeapObj { size_t* _obj_alloc_stat; // Per-thread evacuation failure data structures. - EVAC_FAILURE_INJECTOR_ONLY(size_t _evac_failure_inject_counter;) + ALLOCATION_FAILURE_INJECTOR_ONLY(size_t _allocation_failure_inject_counter;) PreservedMarks* _preserved_marks; EvacuationFailedInfo _evacuation_failed_info; @@ -120,7 +120,7 @@ class G1ParScanThreadState : public CHeapObj { // Enqueue the card of p into the (evacuation failed) region. template void enqueue_card_into_evac_fail_region(T* p, oop obj); - bool inject_evacuation_failure(uint region_idx) EVAC_FAILURE_INJECTOR_RETURN_( return false; ); + bool inject_allocation_failure(uint region_idx) ALLOCATION_FAILURE_INJECTOR_RETURN_( return false; ); public: G1ParScanThreadState(G1CollectedHeap* g1h, @@ -231,7 +231,7 @@ class G1ParScanThreadState : public CHeapObj { void reset_trim_ticks(); // An attempt to evacuate "obj" has failed; take necessary steps. - oop handle_evacuation_failure_par(oop obj, markWord m, size_t word_sz); + oop handle_evacuation_failure_par(oop obj, markWord m, size_t word_sz, bool cause_pinned); template inline void remember_root_into_optional_region(T* p); diff --git a/src/hotspot/share/gc/g1/g1Policy.cpp b/src/hotspot/share/gc/g1/g1Policy.cpp index 1bc1d44691bbb..9e22acc73ca33 100644 --- a/src/hotspot/share/gc/g1/g1Policy.cpp +++ b/src/hotspot/share/gc/g1/g1Policy.cpp @@ -63,7 +63,6 @@ G1Policy::G1Policy(STWGCTimer* gc_timer) : _full_collection_start_sec(0.0), _young_list_desired_length(0), _young_list_target_length(0), - _young_list_max_length(0), _eden_surv_rate_group(new G1SurvRateGroup()), _survivor_surv_rate_group(new G1SurvRateGroup()), _reserve_factor((double) G1ReservePercent / 100.0), @@ -198,15 +197,13 @@ void G1Policy::update_young_length_bounds(size_t pending_cards, size_t card_rs_l uint new_young_list_desired_length = calculate_young_desired_length(pending_cards, card_rs_length, code_root_rs_length); uint new_young_list_target_length = calculate_young_target_length(new_young_list_desired_length); - uint new_young_list_max_length = calculate_young_max_length(new_young_list_target_length); - log_trace(gc, ergo, heap)("Young list length update: pending cards %zu card_rs_length %zu old target %u desired: %u target: %u max: %u", + log_trace(gc, ergo, heap)("Young list length update: pending cards %zu card_rs_length %zu old target %u desired: %u target: %u", pending_cards, card_rs_length, old_young_list_target_length, new_young_list_desired_length, - new_young_list_target_length, - new_young_list_max_length); + new_young_list_target_length); // Write back. This is not an attempt to control visibility order to other threads // here; all the revising of the young gen length are best effort to keep pause time. @@ -217,7 +214,6 @@ void G1Policy::update_young_length_bounds(size_t pending_cards, size_t card_rs_l // early or too late. Atomic::store(&_young_list_desired_length, new_young_list_desired_length); Atomic::store(&_young_list_target_length, new_young_list_target_length); - Atomic::store(&_young_list_max_length, new_young_list_max_length); } // Calculates desired young gen length. It is calculated from: @@ -321,8 +317,7 @@ uint G1Policy::calculate_young_target_length(uint desired_young_length) const { uint receiving_additional_eden; if (allocated_young_length >= desired_young_length) { // Already used up all we actually want (may happen as G1 revises the - // young list length concurrently, or caused by gclocker). Do not allow more, - // potentially resulting in GC. + // young list length concurrently). Do not allow more, potentially resulting in GC. receiving_additional_eden = 0; log_trace(gc, ergo, heap)("Young target length: Already used up desired young %u allocated %u", desired_young_length, @@ -496,11 +491,13 @@ uint G1Policy::calculate_desired_eden_length_before_mixed(double base_time_ms, uint min_marking_candidates = MIN2(calc_min_old_cset_length(candidates()->last_marking_candidates_length()), candidates()->marking_regions_length()); double predicted_region_evac_time_ms = base_time_ms; - for (HeapRegion* r : candidates()->marking_regions()) { + for (G1CollectionSetCandidateInfo* ci : candidates()->marking_regions()) { + // We optimistically assume that any of these marking candidate regions will + // not be pinned, so just consider them as normal. if (min_marking_candidates == 0) { break; } - predicted_region_evac_time_ms += predict_region_total_time_ms(r, false /* for_young_only_phase */); + predicted_region_evac_time_ms += predict_region_total_time_ms(ci->_r, false /* for_young_only_phase */); min_marking_candidates--; } @@ -523,13 +520,21 @@ double G1Policy::predict_survivor_regions_evac_time() const { double G1Policy::predict_retained_regions_evac_time() const { uint num_regions = 0; + uint num_pinned_regions = 0; + double result = 0.0; G1CollectionCandidateList& list = candidates()->retained_regions(); uint min_regions_left = MIN2(min_retained_old_cset_length(), list.length()); - for (HeapRegion* r : list) { + for (G1CollectionSetCandidateInfo* ci : list) { + HeapRegion* r = ci->_r; + // We optimistically assume that any of these marking candidate regions will + // be reclaimable the next gc, so just consider them as normal. + if (r->has_pinned_objects()) { + num_pinned_regions++; + } if (min_regions_left == 0) { // Minimum amount of regions considered. Exit. break; @@ -539,8 +544,8 @@ double G1Policy::predict_retained_regions_evac_time() const { num_regions++; } - log_trace(gc, ergo, heap)("Selected %u of %u retained candidates taking %1.3fms additional time", - num_regions, list.length(), result); + log_trace(gc, ergo, heap)("Selected %u of %u retained candidates (pinned %u) taking %1.3fms additional time", + num_regions, list.length(), num_pinned_regions, result); return result; } @@ -655,12 +660,14 @@ void G1Policy::record_concurrent_refinement_stats(size_t pending_cards, } bool G1Policy::should_retain_evac_failed_region(uint index) const { - size_t live_bytes= _g1h->region_at(index)->live_bytes(); + size_t live_bytes = _g1h->region_at(index)->live_bytes(); +#ifdef ASSERT + HeapRegion* r = _g1h->region_at(index); assert(live_bytes != 0, - "live bytes not set for %u used %zu garbage %zu cm-live %zu", - index, _g1h->region_at(index)->used(), _g1h->region_at(index)->garbage_bytes(), live_bytes); - + "live bytes not set for %u used %zu garbage %zu cm-live %zu pinned %d", + index, r->used(), r->garbage_bytes(), live_bytes, r->has_pinned_objects()); +#endif size_t threshold = G1RetainRegionLiveThresholdPercent * HeapRegion::GrainBytes / 100; return live_bytes < threshold; } @@ -784,7 +791,7 @@ double G1Policy::logged_cards_processing_time() const { // Anything below that is considered to be zero #define MIN_TIMER_GRANULARITY 0.0000001 -void G1Policy::record_young_collection_end(bool concurrent_operation_is_full_mark, bool evacuation_failure) { +void G1Policy::record_young_collection_end(bool concurrent_operation_is_full_mark, bool allocation_failure) { G1GCPhaseTimes* p = phase_times(); double start_time_sec = phase_times()->cur_collection_start_sec(); @@ -810,7 +817,7 @@ void G1Policy::record_young_collection_end(bool concurrent_operation_is_full_mar // Evacuation failures skew the timing too much to be considered for some statistics updates. // We make the assumption that these are rare. - bool update_stats = !evacuation_failure; + bool update_stats = !allocation_failure; if (update_stats) { // We maintain the invariant that all objects allocated by mutator @@ -826,7 +833,7 @@ void G1Policy::record_young_collection_end(bool concurrent_operation_is_full_mar _analytics->report_alloc_rate_ms(alloc_rate_ms); } - record_pause(this_pause, start_time_sec, end_time_sec, evacuation_failure); + record_pause(this_pause, start_time_sec, end_time_sec, allocation_failure); if (G1GCPauseTypeHelper::is_last_young_pause(this_pause)) { assert(!G1GCPauseTypeHelper::is_concurrent_start_pause(this_pause), @@ -1153,11 +1160,6 @@ bool G1Policy::should_allocate_mutator_region() const { return young_list_length < young_list_target_length(); } -bool G1Policy::can_expand_young_list() const { - uint young_list_length = _g1h->young_regions_count(); - return young_list_length < young_list_max_length(); -} - bool G1Policy::use_adaptive_young_list_length() const { return _young_gen_sizer.use_adaptive_young_list_length(); } @@ -1181,20 +1183,6 @@ void G1Policy::print_age_table() { _survivors_age_table.print_age_table(_tenuring_threshold); } -uint G1Policy::calculate_young_max_length(uint target_young_length) const { - uint expansion_region_num = 0; - if (GCLockerEdenExpansionPercent > 0) { - double perc = GCLockerEdenExpansionPercent / 100.0; - double expansion_region_num_d = perc * young_list_target_length(); - // We use ceiling so that if expansion_region_num_d is > 0.0 (but - // less than 1.0) we'll get 1. - expansion_region_num = (uint) ceil(expansion_region_num_d); - } - uint max_length = target_young_length + expansion_region_num; - assert(target_young_length <= max_length, "overflow"); - return max_length; -} - // Calculates survivor space parameters. void G1Policy::update_survivors_policy() { double max_survivor_regions_d = @@ -1377,13 +1365,13 @@ void G1Policy::update_gc_pause_time_ratios(G1GCPauseType gc_type, double start_t void G1Policy::record_pause(G1GCPauseType gc_type, double start, double end, - bool evacuation_failure) { + bool allocation_failure) { // Manage the MMU tracker. For some reason it ignores Full GCs. if (gc_type != G1GCPauseType::FullGC) { _mmu_tracker->add_pause(start, end); } - if (!evacuation_failure) { + if (!allocation_failure) { update_gc_pause_time_ratios(gc_type, start, end); } @@ -1477,13 +1465,15 @@ static void print_finish_message(const char* reason, bool from_marking) { double G1Policy::select_candidates_from_marking(G1CollectionCandidateList* marking_list, double time_remaining_ms, G1CollectionCandidateRegionList* initial_old_regions, - G1CollectionCandidateRegionList* optional_old_regions) { + G1CollectionCandidateRegionList* optional_old_regions, + G1CollectionCandidateRegionList* pinned_old_regions) { assert(marking_list != nullptr, "must be"); uint num_expensive_regions = 0; uint num_initial_regions_selected = 0; uint num_optional_regions_selected = 0; + uint num_pinned_regions = 0; double predicted_initial_time_ms = 0.0; double predicted_optional_time_ms = 0.0; @@ -1496,9 +1486,9 @@ double G1Policy::select_candidates_from_marking(G1CollectionCandidateList* marki bool check_time_remaining = use_adaptive_young_list_length(); log_debug(gc, ergo, cset)("Start adding marking candidates to collection set. " - "Min %u regions, max %u regions, " + "Min %u regions, max %u regions, available %u regions" "time remaining %1.2fms, optional threshold %1.2fms", - min_old_cset_length, max_old_cset_length, time_remaining_ms, optional_threshold_ms); + min_old_cset_length, max_old_cset_length, marking_list->length(), time_remaining_ms, optional_threshold_ms); G1CollectionCandidateListIterator iter = marking_list->begin(); for (; iter != marking_list->end(); ++iter) { @@ -1507,7 +1497,18 @@ double G1Policy::select_candidates_from_marking(G1CollectionCandidateList* marki print_finish_message("Maximum number of regions reached", true); break; } - HeapRegion* hr = *iter; + HeapRegion* hr = (*iter)->_r; + // Skip evacuating pinned marking regions because we are not getting any free + // space from them (and we expect to get free space from marking candidates). + // Also prepare to move them to retained regions to be evacuated optionally later + // to not impact the mixed phase too much. + if (hr->has_pinned_objects()) { + num_pinned_regions++; + (*iter)->update_num_unreclaimed(); + log_trace(gc, ergo, cset)("Marking candidate %u can not be reclaimed currently. Skipping.", hr->hrm_index()); + pinned_old_regions->append(hr); + continue; + } double predicted_time_ms = predict_region_total_time_ms(hr, false); time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0); // Add regions to old set until we reach the minimum amount @@ -1551,9 +1552,9 @@ double G1Policy::select_candidates_from_marking(G1CollectionCandidateList* marki num_expensive_regions); } - log_debug(gc, ergo, cset)("Finish adding marking candidates to collection set. Initial: %u, optional: %u, " + log_debug(gc, ergo, cset)("Finish adding marking candidates to collection set. Initial: %u, optional: %u, pinned: %u, " "predicted initial time: %1.2fms, predicted optional time: %1.2fms, time remaining: %1.2fms", - num_initial_regions_selected, num_optional_regions_selected, + num_initial_regions_selected, num_optional_regions_selected, num_pinned_regions, predicted_initial_time_ms, predicted_optional_time_ms, time_remaining_ms); assert(initial_old_regions->length() == num_initial_regions_selected, "must be"); @@ -1564,13 +1565,15 @@ double G1Policy::select_candidates_from_marking(G1CollectionCandidateList* marki void G1Policy::select_candidates_from_retained(G1CollectionCandidateList* retained_list, double time_remaining_ms, G1CollectionCandidateRegionList* initial_old_regions, - G1CollectionCandidateRegionList* optional_old_regions) { + G1CollectionCandidateRegionList* optional_old_regions, + G1CollectionCandidateRegionList* pinned_old_regions) { uint const min_regions = min_retained_old_cset_length(); uint num_initial_regions_selected = 0; uint num_optional_regions_selected = 0; uint num_expensive_regions_selected = 0; + uint num_pinned_regions = 0; double predicted_initial_time_ms = 0.0; double predicted_optional_time_ms = 0.0; @@ -1584,13 +1587,25 @@ void G1Policy::select_candidates_from_retained(G1CollectionCandidateList* retain time_remaining_ms = MIN2(time_remaining_ms, optional_time_remaining_ms); log_debug(gc, ergo, cset)("Start adding retained candidates to collection set. " - "Min %u regions, " + "Min %u regions, available %u, " "time remaining %1.2fms, optional remaining %1.2fms", - min_regions, time_remaining_ms, optional_time_remaining_ms); + min_regions, retained_list->length(), time_remaining_ms, optional_time_remaining_ms); - for (HeapRegion* r : *retained_list) { + for (G1CollectionSetCandidateInfo* ci : *retained_list) { + HeapRegion* r = ci->_r; double predicted_time_ms = predict_region_total_time_ms(r, collector_state()->in_young_only_phase()); bool fits_in_remaining_time = predicted_time_ms <= time_remaining_ms; + // If we can't reclaim that region ignore it for now. + if (r->has_pinned_objects()) { + num_pinned_regions++; + if (ci->update_num_unreclaimed()) { + log_trace(gc, ergo, cset)("Retained candidate %u can not be reclaimed currently. Skipping.", r->hrm_index()); + } else { + log_trace(gc, ergo, cset)("Retained candidate %u can not be reclaimed currently. Dropping.", r->hrm_index()); + pinned_old_regions->append(r); + } + continue; + } if (fits_in_remaining_time || (num_expensive_regions_selected < min_regions)) { predicted_initial_time_ms += predicted_time_ms; @@ -1620,10 +1635,10 @@ void G1Policy::select_candidates_from_retained(G1CollectionCandidateList* retain num_expensive_regions_selected); } - log_debug(gc, ergo, cset)("Finish adding retained candidates to collection set. Initial: %u, optional: %u, " + log_debug(gc, ergo, cset)("Finish adding retained candidates to collection set. Initial: %u, optional: %u, pinned: %u, " "predicted initial time: %1.2fms, predicted optional time: %1.2fms, " "time remaining: %1.2fms optional time remaining %1.2fms", - num_initial_regions_selected, num_optional_regions_selected, + num_initial_regions_selected, num_optional_regions_selected, num_pinned_regions, predicted_initial_time_ms, predicted_optional_time_ms, time_remaining_ms, optional_time_remaining_ms); } diff --git a/src/hotspot/share/gc/g1/g1Policy.hpp b/src/hotspot/share/gc/g1/g1Policy.hpp index c5ab4e9e1de13..c951909788c2e 100644 --- a/src/hotspot/share/gc/g1/g1Policy.hpp +++ b/src/hotspot/share/gc/g1/g1Policy.hpp @@ -243,9 +243,6 @@ class G1Policy: public CHeapObj { uint calculate_young_desired_length(size_t pending_cards, size_t card_rs_length, size_t code_root_rs_length) const; // Limit the given desired young length to available free regions. uint calculate_young_target_length(uint desired_young_length) const; - // The GCLocker might cause us to need more regions than the target. Calculate - // the maximum number of regions to use in that case. - uint calculate_young_max_length(uint target_young_length) const; size_t predict_bytes_to_copy(HeapRegion* hr) const; double predict_survivor_regions_evac_time() const; @@ -275,7 +272,7 @@ class G1Policy: public CHeapObj { void record_pause(G1GCPauseType gc_type, double start, double end, - bool evacuation_failure = false); + bool allocation_failure = false); void update_gc_pause_time_ratios(G1GCPauseType gc_type, double start_sec, double end_sec); @@ -314,7 +311,7 @@ class G1Policy: public CHeapObj { // Record the start and end of the actual collection part of the evacuation pause. void record_young_collection_start(); - void record_young_collection_end(bool concurrent_operation_is_full_mark, bool evacuation_failure); + void record_young_collection_end(bool concurrent_operation_is_full_mark, bool allocation_failure); // Record the start and end of a full collection. void record_full_collection_start(); @@ -335,18 +332,20 @@ class G1Policy: public CHeapObj { // Amount of allowed waste in bytes in the collection set. size_t allowed_waste_in_collection_set() const; - // Calculate and fill in the initial and optional old gen candidate regions from + // Calculate and fill in the initial, optional and pinned old gen candidate regions from // the given candidate list and the remaining time. // Returns the remaining time. double select_candidates_from_marking(G1CollectionCandidateList* marking_list, double time_remaining_ms, G1CollectionCandidateRegionList* initial_old_regions, - G1CollectionCandidateRegionList* optional_old_regions); + G1CollectionCandidateRegionList* optional_old_regions, + G1CollectionCandidateRegionList* pinned_old_regions); void select_candidates_from_retained(G1CollectionCandidateList* retained_list, double time_remaining_ms, G1CollectionCandidateRegionList* initial_old_regions, - G1CollectionCandidateRegionList* optional_old_regions); + G1CollectionCandidateRegionList* optional_old_regions, + G1CollectionCandidateRegionList* pinned_old_regions); // Calculate the number of optional regions from the given collection set candidates, // the remaining time and the maximum number of these regions and return the number @@ -383,12 +382,9 @@ class G1Policy: public CHeapObj { uint young_list_desired_length() const { return Atomic::load(&_young_list_desired_length); } uint young_list_target_length() const { return Atomic::load(&_young_list_target_length); } - uint young_list_max_length() const { return Atomic::load(&_young_list_max_length); } bool should_allocate_mutator_region() const; - bool can_expand_young_list() const; - bool use_adaptive_young_list_length() const; // Return an estimate of the number of bytes used in young gen. diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index 2ff7e835d33e7..ac445850085cd 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -91,11 +91,6 @@ class G1RemSetScanState : public CHeapObj { size_t _max_reserved_regions; - // Has this region that is part of the regions in the collection set been processed yet. - typedef bool G1RemsetIterState; - - G1RemsetIterState volatile* _collection_set_iter_state; - // Card table iteration claim for each heap region, from 0 (completely unscanned) // to (>=) HeapRegion::CardsPerRegion (completely scanned). uint volatile* _card_table_scan_state; diff --git a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp index cedbefe1fe86b..4156e85fbfa00 100644 --- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp +++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp @@ -67,7 +67,7 @@ double G1RemSetSummary::rs_thread_vtime(uint thread) const { } G1RemSetSummary::G1RemSetSummary(bool should_update) : - _num_vtimes(G1ConcurrentRefine::max_num_threads()), + _num_vtimes(G1ConcRefinementThreads), _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)) { memset(_rs_threads_vtimes, 0, sizeof(double) * _num_vtimes); diff --git a/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp b/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp index 6c084a72d9430..c227b625b8de6 100644 --- a/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp +++ b/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp @@ -38,18 +38,16 @@ bool G1RemSetTrackingPolicy::needs_scan_for_rebuild(HeapRegion* r) const { } void G1RemSetTrackingPolicy::update_at_allocate(HeapRegion* r) { - if (r->is_young()) { - // Always collect remembered set for young regions. - r->rem_set()->set_state_complete(); - } else if (r->is_humongous()) { - // Collect remembered sets for humongous regions by default to allow eager reclaim. - r->rem_set()->set_state_complete(); - } else if (r->is_old()) { + assert(r->is_young() || r->is_humongous() || r->is_old(), + "Region %u with unexpected heap region type %s", r->hrm_index(), r->get_type_str()); + if (r->is_old()) { // By default, do not create remembered set for new old regions. r->rem_set()->set_state_untracked(); - } else { - guarantee(false, "Unhandled region %u with heap region type %s", r->hrm_index(), r->get_type_str()); + return; } + // Always collect remembered set for young regions and for humongous regions. + // Humongous regions need that for eager reclaim. + r->rem_set()->set_state_complete(); } void G1RemSetTrackingPolicy::update_at_free(HeapRegion* r) { diff --git a/src/hotspot/share/gc/g1/g1ServiceThread.cpp b/src/hotspot/share/gc/g1/g1ServiceThread.cpp index 8cda065f047c0..655220c349bbd 100644 --- a/src/hotspot/share/gc/g1/g1ServiceThread.cpp +++ b/src/hotspot/share/gc/g1/g1ServiceThread.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "gc/g1/g1ServiceThread.hpp" #include "logging/log.hpp" +#include "runtime/cpuTimeCounters.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/timer.hpp" #include "runtime/os.hpp" @@ -130,6 +131,8 @@ void G1ServiceThread::run_task(G1ServiceTask* task) { task->execute(); + update_thread_cpu_time(); + log_debug(gc, task)("G1 Service Thread (%s) (run: %1.3fms) (cpu: %1.3fms)", task->name(), TimeHelper::counter_to_millis(os::elapsed_counter() - start), @@ -151,6 +154,13 @@ void G1ServiceThread::stop_service() { ml.notify(); } +void G1ServiceThread::update_thread_cpu_time() { + if (UsePerfData && os::is_thread_cpu_time_supported()) { + ThreadTotalCPUTimeClosure tttc(CPUTimeGroups::CPUTimeType::gc_service); + tttc.do_thread(this); + } +} + G1ServiceTask::G1ServiceTask(const char* name) : _time(), _name(name), diff --git a/src/hotspot/share/gc/g1/g1ServiceThread.hpp b/src/hotspot/share/gc/g1/g1ServiceThread.hpp index b51bf0baa9e40..cfa7abb6552c9 100644 --- a/src/hotspot/share/gc/g1/g1ServiceThread.hpp +++ b/src/hotspot/share/gc/g1/g1ServiceThread.hpp @@ -120,6 +120,9 @@ class G1ServiceThread: public ConcurrentGCThread { // to schedule a registered task to run after the given delay. void schedule(G1ServiceTask* task, jlong delay, bool notify); + // Update the perf data counter for service thread. + void update_thread_cpu_time(); + public: G1ServiceThread(); diff --git a/src/hotspot/share/gc/g1/g1VMOperations.cpp b/src/hotspot/share/gc/g1/g1VMOperations.cpp index 7820c9abff716..c2254e4287f38 100644 --- a/src/hotspot/share/gc/g1/g1VMOperations.cpp +++ b/src/hotspot/share/gc/g1/g1VMOperations.cpp @@ -68,11 +68,9 @@ VM_G1TryInitiateConcMark::VM_G1TryInitiateConcMark(uint gc_count_before, bool VM_G1TryInitiateConcMark::doit_prologue() { bool result = VM_GC_Operation::doit_prologue(); // The prologue can fail for a couple of reasons. The first is that another GC - // got scheduled and prevented the scheduling of the concurrent start GC. The - // second is that the GC locker may be active and the heap can't be expanded. - // In both cases we want to retry the GC so that the concurrent start pause is - // actually scheduled. In the second case, however, we should stall until - // until the GC locker is no longer active and then retry the concurrent start GC. + // got scheduled and prevented the scheduling of the concurrent start GC. + // In this case we want to retry the GC so that the concurrent start pause is + // actually scheduled. if (!result) _transient_failure = true; return result; } @@ -103,16 +101,9 @@ void VM_G1TryInitiateConcMark::doit() { // request will be remembered for a later partial collection, even though // we've rejected this request. _whitebox_attached = true; - } else if (!g1h->do_collection_pause_at_safepoint()) { - // Failure to perform the collection at all occurs because GCLocker is - // active, and we have the bad luck to be the collection request that - // makes a later _gc_locker collection needed. (Else we would have hit - // the GCLocker check in the prologue.) - _transient_failure = true; - } else if (g1h->should_upgrade_to_full_gc()) { - _gc_succeeded = g1h->upgrade_to_full_collection(); } else { - _gc_succeeded = true; + _gc_succeeded = g1h->do_collection_pause_at_safepoint(); + assert(_gc_succeeded, "No reason to fail"); } } @@ -125,37 +116,20 @@ VM_G1CollectForAllocation::VM_G1CollectForAllocation(size_t word_size, void VM_G1CollectForAllocation::doit() { G1CollectedHeap* g1h = G1CollectedHeap::heap(); - if (_word_size > 0) { - // An allocation has been requested. So, try to do that first. - // During the execution of this VM operation, there may have been a concurrent active - // GCLocker, potentially leading to expansion of the Eden space by other mutators. - // If the Eden space were expanded, this allocation request might succeed without - // the need for triggering a garbage collection. - _result = g1h->attempt_allocation_at_safepoint(_word_size, - false /* expect_null_cur_alloc_region */); - if (_result != nullptr) { - // If we can successfully allocate before we actually do the - // pause then we will consider this pause successful. - _gc_succeeded = true; - return; - } - } - GCCauseSetter x(g1h, _gc_cause); // Try a partial collection of some kind. _gc_succeeded = g1h->do_collection_pause_at_safepoint(); + assert(_gc_succeeded, "no reason to fail"); - if (_gc_succeeded) { - if (_word_size > 0) { - // An allocation had been requested. Do it, eventually trying a stronger - // kind of GC. - _result = g1h->satisfy_failed_allocation(_word_size, &_gc_succeeded); - } else if (g1h->should_upgrade_to_full_gc()) { - // There has been a request to perform a GC to free some space. We have no - // information on how much memory has been asked for. In case there are - // absolutely no regions left to allocate into, do a full compaction. - _gc_succeeded = g1h->upgrade_to_full_collection(); - } + if (_word_size > 0) { + // An allocation had been requested. Do it, eventually trying a stronger + // kind of GC. + _result = g1h->satisfy_failed_allocation(_word_size, &_gc_succeeded); + } else if (g1h->should_upgrade_to_full_gc()) { + // There has been a request to perform a GC to free some space. We have no + // information on how much memory has been asked for. In case there are + // absolutely no regions left to allocate into, do a full compaction. + _gc_succeeded = g1h->upgrade_to_full_collection(); } } diff --git a/src/hotspot/share/gc/g1/g1YoungCollector.cpp b/src/hotspot/share/gc/g1/g1YoungCollector.cpp index 351ecd06efb79..ec32f8b589b5c 100644 --- a/src/hotspot/share/gc/g1/g1YoungCollector.cpp +++ b/src/hotspot/share/gc/g1/g1YoungCollector.cpp @@ -34,7 +34,7 @@ #include "gc/g1/g1CollectorState.hpp" #include "gc/g1/g1ConcurrentMark.hpp" #include "gc/g1/g1GCPhaseTimes.hpp" -#include "gc/g1/g1YoungGCEvacFailureInjector.hpp" +#include "gc/g1/g1EvacFailureRegions.inline.hpp" #include "gc/g1/g1EvacInfo.hpp" #include "gc/g1/g1HRPrinter.hpp" #include "gc/g1/g1MonitoringSupport.hpp" @@ -45,6 +45,7 @@ #include "gc/g1/g1RootProcessor.hpp" #include "gc/g1/g1Trace.hpp" #include "gc/g1/g1YoungCollector.hpp" +#include "gc/g1/g1YoungGCAllocationFailureInjector.hpp" #include "gc/g1/g1YoungGCPostEvacuateTasks.hpp" #include "gc/g1/g1YoungGCPreEvacuateTasks.hpp" #include "gc/g1/g1_globals.hpp" @@ -77,12 +78,23 @@ class G1YoungGCTraceTime { GCTraceTime(Info, gc) _tt; const char* update_young_gc_name() { + char evacuation_failed_string[48]; + evacuation_failed_string[0] = '\0'; + + if (_collector->evacuation_failed()) { + snprintf(evacuation_failed_string, + ARRAY_SIZE(evacuation_failed_string), + " (Evacuation Failure: %s%s%s)", + _collector->evacuation_alloc_failed() ? "Allocation" : "", + _collector->evacuation_alloc_failed() && _collector->evacuation_pinned() ? " / " : "", + _collector->evacuation_pinned() ? "Pinned" : ""); + } snprintf(_young_gc_name_data, MaxYoungGCNameLength, "Pause Young (%s) (%s)%s", G1GCPauseTypeHelper::to_string(_pause_type), GCCause::to_string(_pause_cause), - _collector->evacuation_failed() ? " (Evacuation Failure)" : ""); + evacuation_failed_string); return _young_gc_name_data; } @@ -231,8 +243,8 @@ WorkerThreads* G1YoungCollector::workers() const { return _g1h->workers(); } -G1YoungGCEvacFailureInjector* G1YoungCollector::evac_failure_injector() const { - return _g1h->evac_failure_injector(); +G1YoungGCAllocationFailureInjector* G1YoungCollector::allocation_failure_injector() const { + return _g1h->allocation_failure_injector(); } @@ -314,6 +326,10 @@ class G1PrepareEvacuationTask : public WorkerTask { if (!region->rem_set()->is_complete()) { return false; } + // We also cannot collect the humongous object if it is pinned. + if (region->has_pinned_objects()) { + return false; + } // Candidate selection must satisfy the following constraints // while concurrent marking is in progress: // @@ -386,13 +402,15 @@ class G1PrepareEvacuationTask : public WorkerTask { } else { _g1h->register_region_with_region_attr(hr); } - log_debug(gc, humongous)("Humongous region %u (object size %zu @ " PTR_FORMAT ") remset %zu code roots %zu marked %d reclaim candidate %d type array %d", + log_debug(gc, humongous)("Humongous region %u (object size %zu @ " PTR_FORMAT ") remset %zu code roots %zu " + "marked %d pinned count %u reclaim candidate %d type array %d", index, cast_to_oop(hr->bottom())->size() * HeapWordSize, p2i(hr->bottom()), hr->rem_set()->occupied(), hr->rem_set()->code_roots_list_length(), _g1h->concurrent_mark()->mark_bitmap()->is_marked(hr->bottom()), + hr->pinned_count(), _g1h->is_humongous_reclaim_candidate(index), cast_to_oop(hr->bottom())->is_typeArray() ); @@ -516,7 +534,7 @@ void G1YoungCollector::pre_evacuate_collection_set(G1EvacInfo* evacuation_info) DerivedPointerTable::clear(); #endif - evac_failure_injector()->arm_if_needed(); + allocation_failure_injector()->arm_if_needed(); } class G1ParEvacuateFollowersClosure : public VoidClosure { @@ -759,7 +777,7 @@ void G1YoungCollector::evacuate_next_optional_regions(G1ParScanThreadStateSet* p void G1YoungCollector::evacuate_optional_collection_set(G1ParScanThreadStateSet* per_thread_states) { const double collection_start_time_ms = phase_times()->cur_collection_start_sec() * 1000.0; - while (!evacuation_failed() && collection_set()->optional_region_length() > 0) { + while (!evacuation_alloc_failed() && collection_set()->optional_region_length() > 0) { double time_used_ms = os::elapsedTime() * 1000.0 - collection_start_time_ms; double time_left_ms = MaxGCPauseMillis - time_used_ms; @@ -1010,7 +1028,15 @@ void G1YoungCollector::post_evacuate_collection_set(G1EvacInfo* evacuation_info, } bool G1YoungCollector::evacuation_failed() const { - return _evac_failure_regions.evacuation_failed(); + return _evac_failure_regions.has_regions_evac_failed(); +} + +bool G1YoungCollector::evacuation_pinned() const { + return _evac_failure_regions.has_regions_evac_pinned(); +} + +bool G1YoungCollector::evacuation_alloc_failed() const { + return _evac_failure_regions.has_regions_alloc_failed(); } G1YoungCollector::G1YoungCollector(GCCause::Cause gc_cause) : @@ -1083,7 +1109,7 @@ void G1YoungCollector::collect() { // modifies it to the next state. jtm.report_pause_type(collector_state()->young_gc_pause_type(_concurrent_operation_is_full_mark)); - policy()->record_young_collection_end(_concurrent_operation_is_full_mark, evacuation_failed()); + policy()->record_young_collection_end(_concurrent_operation_is_full_mark, evacuation_alloc_failed()); } TASKQUEUE_STATS_ONLY(_g1h->task_queues()->print_and_reset_taskqueue_stats("Oop Queue");) } diff --git a/src/hotspot/share/gc/g1/g1YoungCollector.hpp b/src/hotspot/share/gc/g1/g1YoungCollector.hpp index 4a81ee97ed7da..e7f3c51b65ca0 100644 --- a/src/hotspot/share/gc/g1/g1YoungCollector.hpp +++ b/src/hotspot/share/gc/g1/g1YoungCollector.hpp @@ -26,7 +26,7 @@ #define SHARE_GC_G1_G1YOUNGCOLLECTOR_HPP #include "gc/g1/g1EvacFailureRegions.hpp" -#include "gc/g1/g1YoungGCEvacFailureInjector.hpp" +#include "gc/g1/g1YoungGCAllocationFailureInjector.hpp" #include "gc/shared/gcCause.hpp" #include "gc/shared/taskqueue.hpp" @@ -49,7 +49,7 @@ class G1Policy; class G1RedirtyCardsQueueSet; class G1RemSet; class G1SurvivorRegions; -class G1YoungGCEvacFailureInjector; +class G1YoungGCAllocationFailureInjector; class STWGCTimer; class WorkerThreads; @@ -78,7 +78,7 @@ class G1YoungCollector { G1SurvivorRegions* survivor_regions() const; ReferenceProcessor* ref_processor_stw() const; WorkerThreads* workers() const; - G1YoungGCEvacFailureInjector* evac_failure_injector() const; + G1YoungGCAllocationFailureInjector* allocation_failure_injector() const; GCCause::Cause _gc_cause; @@ -131,8 +131,12 @@ class G1YoungCollector { void post_evacuate_collection_set(G1EvacInfo* evacuation_info, G1ParScanThreadStateSet* per_thread_states); - // True iff an evacuation has failed in the most-recent collection. + // True iff an evacuation failure of any kind occurred in the most-recent collection. bool evacuation_failed() const; + // True iff an evacuation had pinned regions in the most-recent collection. + bool evacuation_pinned() const; + // True iff an evacuation had allocation failures in the most-recent collection. + bool evacuation_alloc_failed() const; public: G1YoungCollector(GCCause::Cause gc_cause); diff --git a/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.cpp b/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.cpp new file mode 100644 index 0000000000000..60b7e0872f2ef --- /dev/null +++ b/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1YoungGCAllocationFailureInjector.inline.hpp" +#include "gc/g1/g1_globals.hpp" + +#if ALLOCATION_FAILURE_INJECTOR + +class SelectAllocationFailureRegionClosure : public HeapRegionClosure { + CHeapBitMap& _allocation_failure_regions; + size_t _allocation_failure_regions_num; + +public: + SelectAllocationFailureRegionClosure(CHeapBitMap& allocation_failure_regions, size_t cset_length) : + _allocation_failure_regions(allocation_failure_regions), + _allocation_failure_regions_num(cset_length * G1GCAllocationFailureALotCSetPercent / 100) { } + + bool do_heap_region(HeapRegion* r) override { + assert(r->in_collection_set(), "must be"); + if (_allocation_failure_regions_num > 0) { + _allocation_failure_regions.set_bit(r->hrm_index()); + --_allocation_failure_regions_num; + } + return _allocation_failure_regions_num == 0; + } +}; + +G1YoungGCAllocationFailureInjector::G1YoungGCAllocationFailureInjector() + : _inject_allocation_failure_for_current_gc(), + _last_collection_with_allocation_failure(), + _allocation_failure_regions(mtGC) {} + +void G1YoungGCAllocationFailureInjector::select_allocation_failure_regions() { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + _allocation_failure_regions.reinitialize(g1h->max_reserved_regions()); + SelectAllocationFailureRegionClosure closure(_allocation_failure_regions, g1h->collection_set()->cur_length()); + g1h->collection_set_iterate_all(&closure); +} + +bool G1YoungGCAllocationFailureInjector::arm_if_needed_for_gc_type(bool for_young_only_phase, + bool during_concurrent_start, + bool mark_or_rebuild_in_progress) { + bool res = false; + if (mark_or_rebuild_in_progress) { + res |= G1GCAllocationFailureALotDuringConcMark; + } + if (during_concurrent_start) { + res |= G1GCAllocationFailureALotDuringConcurrentStart; + } + if (for_young_only_phase) { + res |= G1GCAllocationFailureALotDuringYoungGC; + } else { + // GCs are mixed + res |= G1GCAllocationFailureALotDuringMixedGC; + } + return res; +} + +void G1YoungGCAllocationFailureInjector::arm_if_needed() { + if (G1GCAllocationFailureALot) { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + // Check if we have gone over the interval. + const size_t gc_num = g1h->total_collections(); + const size_t elapsed_gcs = gc_num - _last_collection_with_allocation_failure; + + _inject_allocation_failure_for_current_gc = (elapsed_gcs >= G1GCAllocationFailureALotInterval); + + // Now check if evacuation failure injection should be enabled for the current GC. + G1CollectorState* collector_state = g1h->collector_state(); + const bool in_young_only_phase = collector_state->in_young_only_phase(); + const bool in_concurrent_start_gc = collector_state->in_concurrent_start_gc(); + const bool mark_or_rebuild_in_progress = collector_state->mark_or_rebuild_in_progress(); + + _inject_allocation_failure_for_current_gc &= + arm_if_needed_for_gc_type(in_young_only_phase, + in_concurrent_start_gc, + mark_or_rebuild_in_progress); + + if (_inject_allocation_failure_for_current_gc) { + select_allocation_failure_regions(); + } + } +} + +void G1YoungGCAllocationFailureInjector::reset() { + _last_collection_with_allocation_failure = G1CollectedHeap::heap()->total_collections(); + _inject_allocation_failure_for_current_gc = false; +} + +#endif // #if ALLOCATION_FAILURE_INJECTOR diff --git a/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.hpp b/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.hpp new file mode 100644 index 0000000000000..fb7e8cd3ad3bb --- /dev/null +++ b/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.hpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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_G1_G1YOUNGGCALLOCATIONFAILUREINJECTOR_HPP +#define SHARE_GC_G1_G1YOUNGGCALLOCATIONFAILUREINJECTOR_HPP + +#include "gc/g1/g1_globals.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" + +#if ALLOCATION_FAILURE_INJECTOR +#define ALLOCATION_FAILURE_INJECTOR_RETURN +#define ALLOCATION_FAILURE_INJECTOR_RETURN_(code) +#define ALLOCATION_FAILURE_INJECTOR_ONLY(code) code +#else +#define ALLOCATION_FAILURE_INJECTOR_RETURN { return; } +#define ALLOCATION_FAILURE_INJECTOR_RETURN_(code) { code } +#define ALLOCATION_FAILURE_INJECTOR_ONLY(code) +#endif // ALLOCATION_FAILURE_INJECTOR + +// Support for injecting allocation failures based on the G1GCAllocationFailureALot* +// flags. Analogous to PromotionFailureALot for the other collectors. +// +// Every G1GCAllocationFailureALotInterval collections without evacuation failure +// in between we "arm" the injector to induce allocation failures after +// G1GCAllocationFailureALotCount successful evacuations. +// +// Available only when ALLOCATION_FAILURE_INJECTOR is defined. +class G1YoungGCAllocationFailureInjector { +#if ALLOCATION_FAILURE_INJECTOR + // Should we inject evacuation failures in the current GC. + bool _inject_allocation_failure_for_current_gc; + + // Records the number of the last collection when allocation failure happened. + // Used to determine whether allocation failure injection should be in effect + // for the current GC. + size_t _last_collection_with_allocation_failure; + + // Records the regions that will fail evacuation. + CHeapBitMap _allocation_failure_regions; +#endif + + bool arm_if_needed_for_gc_type(bool for_young_only_phase, + bool during_concurrent_start, + bool mark_or_rebuild_in_progress) ALLOCATION_FAILURE_INJECTOR_RETURN_( return false; ); + + // Selects the regions that will fail allocation by G1GCAllocationFailureALotCSetPercent. + void select_allocation_failure_regions() ALLOCATION_FAILURE_INJECTOR_RETURN; +public: + + G1YoungGCAllocationFailureInjector() ALLOCATION_FAILURE_INJECTOR_RETURN; + + // Arm the allocation failure injector if needed for the current + // GC (based upon the type of GC and which command line flags are set); + void arm_if_needed() ALLOCATION_FAILURE_INJECTOR_RETURN; + + // Return true if it's time to cause an allocation failure; the caller + // provides the (preferably thread-local) counter to minimize performance impact. + bool allocation_should_fail(size_t& counter, uint region_idx) ALLOCATION_FAILURE_INJECTOR_RETURN_( return false; ); + + // Reset the allocation failure injection counters. Should be called at + // the end of an evacuation pause in which an allocation failure occurred. + void reset() ALLOCATION_FAILURE_INJECTOR_RETURN; +}; + +#endif /* SHARE_GC_G1_G1YOUNGGCALLOCATIONFAILUREINJECTOR_HPP */ diff --git a/src/hotspot/share/gc/g1/g1YoungGCEvacFailureInjector.inline.hpp b/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.inline.hpp similarity index 63% rename from src/hotspot/share/gc/g1/g1YoungGCEvacFailureInjector.inline.hpp rename to src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.inline.hpp index 52582df460936..7c71eb14d52bc 100644 --- a/src/hotspot/share/gc/g1/g1YoungGCEvacFailureInjector.inline.hpp +++ b/src/hotspot/share/gc/g1/g1YoungGCAllocationFailureInjector.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,30 +22,30 @@ * */ -#ifndef SHARE_GC_G1_G1YOUNGGCEVACUATIONFAILUREINJECTOR_INLINE_HPP -#define SHARE_GC_G1_G1YOUNGGCEVACUATIONFAILUREINJECTOR_INLINE_HPP +#ifndef SHARE_GC_G1_G1YOUNGGCALLOCATIONFAILUREINJECTOR_INLINE_HPP +#define SHARE_GC_G1_G1YOUNGGCALLOCATIONFAILUREINJECTOR_INLINE_HPP -#include "gc/g1/g1YoungGCEvacFailureInjector.hpp" +#include "gc/g1/g1YoungGCAllocationFailureInjector.hpp" #include "gc/g1/g1_globals.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" -#if EVAC_FAILURE_INJECTOR +#if ALLOCATION_FAILURE_INJECTOR -inline bool G1YoungGCEvacFailureInjector::evacuation_should_fail(size_t& counter, uint region_idx) { - if (!_inject_evacuation_failure_for_current_gc) { +inline bool G1YoungGCAllocationFailureInjector::allocation_should_fail(size_t& counter, uint region_idx) { + if (!_inject_allocation_failure_for_current_gc) { return false; } - if (!_evac_failure_regions.at(region_idx)) { + if (!_allocation_failure_regions.at(region_idx)) { return false; } - if (++counter < G1EvacuationFailureALotCount) { + if (++counter < G1GCAllocationFailureALotCount) { return false; } counter = 0; return true; } -#endif // #if EVAC_FAILURE_INJECTOR +#endif // #if ALLOCATION_FAILURE_INJECTOR -#endif /* SHARE_GC_G1_G1YOUNGGCEVACUATIONFAILUREINJECTOR_INLINE_HPP */ +#endif /* SHARE_GC_G1_G1YOUNGGCALLOCATIONFAILUREINJECTOR_INLINE_HPP */ diff --git a/src/hotspot/share/gc/g1/g1YoungGCEvacFailureInjector.cpp b/src/hotspot/share/gc/g1/g1YoungGCEvacFailureInjector.cpp deleted file mode 100644 index 7ac935eb59422..0000000000000 --- a/src/hotspot/share/gc/g1/g1YoungGCEvacFailureInjector.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" - -#include "gc/g1/g1CollectedHeap.inline.hpp" -#include "gc/g1/g1YoungGCEvacFailureInjector.inline.hpp" -#include "gc/g1/g1_globals.hpp" - -#if EVAC_FAILURE_INJECTOR - -class SelectEvacFailureRegionClosure : public HeapRegionClosure { - CHeapBitMap& _evac_failure_regions; - size_t _evac_failure_regions_num; - -public: - SelectEvacFailureRegionClosure(CHeapBitMap& evac_failure_regions, size_t cset_length) : - _evac_failure_regions(evac_failure_regions), - _evac_failure_regions_num(cset_length * G1EvacuationFailureALotCSetPercent / 100) { } - - bool do_heap_region(HeapRegion* r) override { - assert(r->in_collection_set(), "must be"); - if (_evac_failure_regions_num > 0) { - _evac_failure_regions.set_bit(r->hrm_index()); - --_evac_failure_regions_num; - } - return _evac_failure_regions_num == 0; - } -}; - -G1YoungGCEvacFailureInjector::G1YoungGCEvacFailureInjector() - : _inject_evacuation_failure_for_current_gc(), - _last_collection_with_evacuation_failure(), - _evac_failure_regions(mtGC) {} - -void G1YoungGCEvacFailureInjector::select_evac_failure_regions() { - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - _evac_failure_regions.reinitialize(g1h->max_reserved_regions()); - SelectEvacFailureRegionClosure closure(_evac_failure_regions, g1h->collection_set()->cur_length()); - g1h->collection_set_iterate_all(&closure); -} - -bool G1YoungGCEvacFailureInjector::arm_if_needed_for_gc_type(bool for_young_only_phase, - bool during_concurrent_start, - bool mark_or_rebuild_in_progress) { - bool res = false; - if (mark_or_rebuild_in_progress) { - res |= G1EvacuationFailureALotDuringConcMark; - } - if (during_concurrent_start) { - res |= G1EvacuationFailureALotDuringConcurrentStart; - } - if (for_young_only_phase) { - res |= G1EvacuationFailureALotDuringYoungGC; - } else { - // GCs are mixed - res |= G1EvacuationFailureALotDuringMixedGC; - } - return res; -} - -void G1YoungGCEvacFailureInjector::arm_if_needed() { - if (G1EvacuationFailureALot) { - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - // Check if we have gone over the interval. - const size_t gc_num = g1h->total_collections(); - const size_t elapsed_gcs = gc_num - _last_collection_with_evacuation_failure; - - _inject_evacuation_failure_for_current_gc = (elapsed_gcs >= G1EvacuationFailureALotInterval); - - // Now check if evacuation failure injection should be enabled for the current GC. - G1CollectorState* collector_state = g1h->collector_state(); - const bool in_young_only_phase = collector_state->in_young_only_phase(); - const bool in_concurrent_start_gc = collector_state->in_concurrent_start_gc(); - const bool mark_or_rebuild_in_progress = collector_state->mark_or_rebuild_in_progress(); - - _inject_evacuation_failure_for_current_gc &= - arm_if_needed_for_gc_type(in_young_only_phase, - in_concurrent_start_gc, - mark_or_rebuild_in_progress); - - if (_inject_evacuation_failure_for_current_gc) { - select_evac_failure_regions(); - } - } -} - -void G1YoungGCEvacFailureInjector::reset() { - _last_collection_with_evacuation_failure = G1CollectedHeap::heap()->total_collections(); - _inject_evacuation_failure_for_current_gc = false; -} - -#endif // #if EVAC_FAILURE_INJECTOR diff --git a/src/hotspot/share/gc/g1/g1YoungGCEvacFailureInjector.hpp b/src/hotspot/share/gc/g1/g1YoungGCEvacFailureInjector.hpp deleted file mode 100644 index f5efd21bcfed2..0000000000000 --- a/src/hotspot/share/gc/g1/g1YoungGCEvacFailureInjector.hpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_GC_G1_G1YOUNGGCEVACUATIONFAILUREINJECTOR_HPP -#define SHARE_GC_G1_G1YOUNGGCEVACUATIONFAILUREINJECTOR_HPP - -#include "gc/g1/g1_globals.hpp" -#include "memory/allStatic.hpp" -#include "utilities/globalDefinitions.hpp" - -#if EVAC_FAILURE_INJECTOR -#define EVAC_FAILURE_INJECTOR_RETURN -#define EVAC_FAILURE_INJECTOR_RETURN_(code) -#define EVAC_FAILURE_INJECTOR_ONLY(code) code -#else -#define EVAC_FAILURE_INJECTOR_RETURN { return; } -#define EVAC_FAILURE_INJECTOR_RETURN_(code) { code } -#define EVAC_FAILURE_INJECTOR_ONLY(code) -#endif // EVAC_FAILURE_INJECTOR - -// Support for injecting evacuation failures based on the G1EvacuationFailureALot* -// flags. Analogous to PromotionFailureALot for the other collectors. -// -// Every G1EvacuationFailureALotInterval collections without evacuation failure -// in between we "arm" the injector to induce evacuation failures after -// G1EvacuationFailureALotCount successful evacuations. -// -// Available only when EVAC_FAILURE_INJECTOR is defined. -class G1YoungGCEvacFailureInjector { -#if EVAC_FAILURE_INJECTOR - // Should we inject evacuation failures in the current GC. - bool _inject_evacuation_failure_for_current_gc; - - // Records the number of the last collection when evacuation failure happened. - // Used to determine whether evacuation failure injection should be in effect - // for the current GC. - size_t _last_collection_with_evacuation_failure; - - // Records the regions that will fail evacuation. - CHeapBitMap _evac_failure_regions; -#endif - - bool arm_if_needed_for_gc_type(bool for_young_only_phase, - bool during_concurrent_start, - bool mark_or_rebuild_in_progress) EVAC_FAILURE_INJECTOR_RETURN_( return false; ); - - // Selects the regions that will fail evacuation by G1EvacuationFailureALotCSetPercent. - void select_evac_failure_regions() EVAC_FAILURE_INJECTOR_RETURN; -public: - - G1YoungGCEvacFailureInjector() EVAC_FAILURE_INJECTOR_RETURN; - - // Arm the evacuation failure injector if needed for the current - // GC (based upon the type of GC and which command line flags are set); - void arm_if_needed() EVAC_FAILURE_INJECTOR_RETURN; - - // Return true if it's time to cause an evacuation failure; the caller - // provides the (preferably thread-local) counter to minimize performance impact. - bool evacuation_should_fail(size_t& counter, uint region_idx) EVAC_FAILURE_INJECTOR_RETURN_( return false; ); - - // Reset the evacuation failure injection counters. Should be called at - // the end of an evacuation pause in which an evacuation failure occurred. - void reset() EVAC_FAILURE_INJECTOR_RETURN; -}; - -#endif /* SHARE_GC_G1_G1YOUNGGCEVACUATIONFAILUREINJECTOR_HPP */ diff --git a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp index d47f0e86c3035..377f5f550d17e 100644 --- a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp +++ b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp @@ -31,7 +31,7 @@ #include "gc/g1/g1CollectionSetCandidates.inline.hpp" #include "gc/g1/g1CollectorState.hpp" #include "gc/g1/g1ConcurrentMark.inline.hpp" -#include "gc/g1/g1EvacFailureRegions.hpp" +#include "gc/g1/g1EvacFailureRegions.inline.hpp" #include "gc/g1/g1EvacInfo.hpp" #include "gc/g1/g1EvacStats.inline.hpp" #include "gc/g1/g1OopClosures.inline.hpp" @@ -67,16 +67,26 @@ class G1PostEvacuateCollectionSetCleanupTask1::MergePssTask : public G1AbstractS class G1PostEvacuateCollectionSetCleanupTask1::RecalculateUsedTask : public G1AbstractSubTask { bool _evacuation_failed; + bool _allocation_failed; public: - RecalculateUsedTask(bool evacuation_failed) : G1AbstractSubTask(G1GCPhaseTimes::RecalculateUsed), _evacuation_failed(evacuation_failed) { } + RecalculateUsedTask(bool evacuation_failed, bool allocation_failed) : + G1AbstractSubTask(G1GCPhaseTimes::RecalculateUsed), + _evacuation_failed(evacuation_failed), + _allocation_failed(allocation_failed) { } double worker_cost() const override { // If there is no evacuation failure, the work to perform is minimal. return _evacuation_failed ? 1.0 : AlmostNoWork; } - void do_work(uint worker_id) override { G1CollectedHeap::heap()->update_used_after_gc(_evacuation_failed); } + void do_work(uint worker_id) override { + G1CollectedHeap::heap()->update_used_after_gc(_evacuation_failed); + if (_allocation_failed) { + // Reset the G1GCAllocationFailureALot counters and flags + G1CollectedHeap::heap()->allocation_failure_injector()->reset(); + } + } }; class G1PostEvacuateCollectionSetCleanupTask1::SampleCollectionSetCandidatesTask : public G1AbstractSubTask { @@ -103,7 +113,7 @@ class G1PostEvacuateCollectionSetCleanupTask1::SampleCollectionSetCandidatesTask } }; -class G1PostEvacuateCollectionSetCleanupTask1::RestoreRetainedRegionsTask : public G1AbstractSubTask { +class G1PostEvacuateCollectionSetCleanupTask1::RestoreEvacFailureRegionsTask : public G1AbstractSubTask { G1CollectedHeap* _g1h; G1ConcurrentMark* _cm; @@ -265,14 +275,14 @@ class G1PostEvacuateCollectionSetCleanupTask1::RestoreRetainedRegionsTask : publ } public: - RestoreRetainedRegionsTask(G1EvacFailureRegions* evac_failure_regions) : - G1AbstractSubTask(G1GCPhaseTimes::RestoreRetainedRegions), + RestoreEvacFailureRegionsTask(G1EvacFailureRegions* evac_failure_regions) : + G1AbstractSubTask(G1GCPhaseTimes::RestoreEvacuationFailedRegions), _g1h(G1CollectedHeap::heap()), _cm(_g1h->concurrent_mark()), _evac_failure_regions(evac_failure_regions), _chunk_bitmap(mtGC) { - _num_evac_fail_regions = _evac_failure_regions->num_regions_failed_evacuation(); + _num_evac_fail_regions = _evac_failure_regions->num_regions_evac_failed(); _num_chunks_per_region = G1CollectedHeap::get_chunks_per_region(); _chunk_size = static_cast(HeapRegion::GrainWords / _num_chunks_per_region); @@ -284,10 +294,10 @@ class G1PostEvacuateCollectionSetCleanupTask1::RestoreRetainedRegionsTask : publ } double worker_cost() const override { - assert(_evac_failure_regions->evacuation_failed(), "Should not call this if not executed"); + assert(_evac_failure_regions->has_regions_evac_failed(), "Should not call this if there were no evacuation failures"); double workers_per_region = (double)G1CollectedHeap::get_chunks_per_region() / G1RestoreRetainedRegionChunksPerWorker; - return workers_per_region * _evac_failure_regions->num_regions_failed_evacuation(); + return workers_per_region * _evac_failure_regions->num_regions_evac_failed(); } void do_work(uint worker_id) override { @@ -308,16 +318,17 @@ G1PostEvacuateCollectionSetCleanupTask1::G1PostEvacuateCollectionSetCleanupTask1 G1EvacFailureRegions* evac_failure_regions) : G1BatchedTask("Post Evacuate Cleanup 1", G1CollectedHeap::heap()->phase_times()) { - bool evacuation_failed = evac_failure_regions->evacuation_failed(); + bool evac_failed = evac_failure_regions->has_regions_evac_failed(); + bool alloc_failed = evac_failure_regions->has_regions_alloc_failed(); add_serial_task(new MergePssTask(per_thread_states)); - add_serial_task(new RecalculateUsedTask(evacuation_failed)); + add_serial_task(new RecalculateUsedTask(evac_failed, alloc_failed)); if (SampleCollectionSetCandidatesTask::should_execute()) { add_serial_task(new SampleCollectionSetCandidatesTask()); } add_parallel_task(G1CollectedHeap::heap()->rem_set()->create_cleanup_after_scan_heap_roots_task()); - if (evacuation_failed) { - add_parallel_task(new RestoreRetainedRegionsTask(evac_failure_regions)); + if (evac_failed) { + add_parallel_task(new RestoreEvacFailureRegionsTask(evac_failure_regions)); } } @@ -569,7 +580,7 @@ class G1PostEvacuateCollectionSetCleanupTask2::ProcessEvacuationFailedRegionsTas } double worker_cost() const override { - return _evac_failure_regions->num_regions_failed_evacuation(); + return _evac_failure_regions->num_regions_evac_failed(); } void do_work(uint worker_id) override { @@ -757,10 +768,10 @@ class FreeCSetClosure : public HeapRegionClosure { G1GCPhaseTimes* p = _g1h->phase_times(); assert(r->in_collection_set(), "Failed evacuation of region %u not in collection set", r->hrm_index()); - p->record_or_add_thread_work_item(G1GCPhaseTimes::RestoreRetainedRegions, + p->record_or_add_thread_work_item(G1GCPhaseTimes::RestoreEvacuationFailedRegions, _worker_id, 1, - G1GCPhaseTimes::RestoreRetainedRegionsFailedNum); + G1GCPhaseTimes::RestoreEvacFailureRegionsEvacFailedNum); bool retain_region = _g1h->policy()->should_retain_evac_failed_region(r); // Update the region state due to the failed evacuation. @@ -844,6 +855,7 @@ class G1PostEvacuateCollectionSetCleanupTask2::FreeCollectionSetTask : public G1 const size_t* _surviving_young_words; uint _active_workers; G1EvacFailureRegions* _evac_failure_regions; + volatile uint _num_retained_regions; FreeCSetStats* worker_stats(uint worker) { return &_worker_stats[worker]; @@ -869,7 +881,8 @@ class G1PostEvacuateCollectionSetCleanupTask2::FreeCollectionSetTask : public G1 _claimer(0), _surviving_young_words(surviving_young_words), _active_workers(0), - _evac_failure_regions(evac_failure_regions) { + _evac_failure_regions(evac_failure_regions), + _num_retained_regions(0) { _g1h->clear_eden(); } @@ -877,10 +890,7 @@ class G1PostEvacuateCollectionSetCleanupTask2::FreeCollectionSetTask : public G1 virtual ~FreeCollectionSetTask() { Ticks serial_time = Ticks::now(); - G1GCPhaseTimes* p = _g1h->phase_times(); - bool has_new_retained_regions = - p->sum_thread_work_items(G1GCPhaseTimes::RestoreRetainedRegions, G1GCPhaseTimes::RestoreRetainedRegionsRetainedNum) != 0; - + bool has_new_retained_regions = Atomic::load(&_num_retained_regions) != 0; if (has_new_retained_regions) { G1CollectionSetCandidates* candidates = _g1h->collection_set()->candidates(); candidates->sort_by_efficiency(); @@ -891,7 +901,10 @@ class G1PostEvacuateCollectionSetCleanupTask2::FreeCollectionSetTask : public G1 _worker_stats[worker].~FreeCSetStats(); } FREE_C_HEAP_ARRAY(FreeCSetStats, _worker_stats); + + G1GCPhaseTimes* p = _g1h->phase_times(); p->record_serial_free_cset_time_ms((Ticks::now() - serial_time).seconds() * 1000.0); + _g1h->clear_collection_set(); } @@ -911,10 +924,8 @@ class G1PostEvacuateCollectionSetCleanupTask2::FreeCollectionSetTask : public G1 _g1h->collection_set_par_iterate_all(&cl, &_claimer, worker_id); // Report per-region type timings. cl.report_timing(); - _g1h->phase_times()->record_or_add_thread_work_item(G1GCPhaseTimes::RestoreRetainedRegions, - worker_id, - cl.num_retained_regions(), - G1GCPhaseTimes::RestoreRetainedRegionsRetainedNum); + + Atomic::add(&_num_retained_regions, cl.num_retained_regions(), memory_order_relaxed); } }; @@ -955,7 +966,7 @@ G1PostEvacuateCollectionSetCleanupTask2::G1PostEvacuateCollectionSetCleanupTask2 add_serial_task(new EagerlyReclaimHumongousObjectsTask()); } - if (evac_failure_regions->evacuation_failed()) { + if (evac_failure_regions->has_regions_evac_failed()) { add_parallel_task(new RestorePreservedMarksTask(per_thread_states->preserved_marks_set())); add_parallel_task(new ProcessEvacuationFailedRegionsTask(evac_failure_regions)); } diff --git a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.hpp b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.hpp index 511eb1b4afbe8..868ab788b534a 100644 --- a/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.hpp +++ b/src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.hpp @@ -39,12 +39,12 @@ class G1ParScanThreadStateSet; // - Recalculate Used (s) // - Sample Collection Set Candidates (s) // - Clear Card Table -// - Restore retained regions (on evacuation failure) +// - Restore evac failure regions (on evacuation failure) class G1PostEvacuateCollectionSetCleanupTask1 : public G1BatchedTask { class MergePssTask; class RecalculateUsedTask; class SampleCollectionSetCandidatesTask; - class RestoreRetainedRegionsTask; + class RestoreEvacFailureRegionsTask; public: G1PostEvacuateCollectionSetCleanupTask1(G1ParScanThreadStateSet* per_thread_states, diff --git a/src/hotspot/share/gc/g1/g1_globals.hpp b/src/hotspot/share/gc/g1/g1_globals.hpp index 9ec0b45d22ae1..5f7f3a27d5b4e 100644 --- a/src/hotspot/share/gc/g1/g1_globals.hpp +++ b/src/hotspot/share/gc/g1/g1_globals.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,18 +27,18 @@ #include "runtime/globals_shared.hpp" -// Enable evacuation failure injector by default in non-product builds. +// Enable allocation failure injector by default in non-product builds. -#ifdef EVAC_FAILURE_INJECTOR -#error "EVAC_FAILURE_INJECTOR already defined" +#ifdef ALLOCATION_FAILURE_INJECTOR +#error "ALLOCATION_FAILURE_INJECTOR already defined" #endif #ifndef PRODUCT -#define EVAC_FAILURE_INJECTOR 1 +#define ALLOCATION_FAILURE_INJECTOR 1 #else -#define EVAC_FAILURE_INJECTOR 0 +#define ALLOCATION_FAILURE_INJECTOR 0 #endif -#if EVAC_FAILURE_INJECTOR +#if ALLOCATION_FAILURE_INJECTOR #define GC_G1_EVACUATION_FAILURE_FLAGS(develop, \ develop_pd, \ product, \ @@ -47,38 +47,38 @@ range, \ constraint) \ \ - product(bool, G1EvacuationFailureALot, false, \ - "Force use of evacuation failure handling during certain " \ - "evacuation pauses") \ + product(bool, G1GCAllocationFailureALot, false, \ + "Force execution of evacuation failure handling by inducing " \ + "allocation failures during certain young collection pauses") \ \ - product(uintx, G1EvacuationFailureALotCount, 1000, \ - "Number of successful evacuations between evacuation failures " \ - "occurring at object copying per thread") \ + product(uintx, G1GCAllocationFailureALotCount, 1000, \ + "Number of successful evacuations between induced allocation " \ + "failures occurring at object copying per thread") \ \ - product(uintx, G1EvacuationFailureALotInterval, 5, \ + product(uintx, G1GCAllocationFailureALotInterval, 5, \ "Total collections between forced triggering of evacuation " \ "failures") \ \ - product(bool, G1EvacuationFailureALotDuringConcMark, true, \ - "Force use of evacuation failure handling during evacuation " \ - "pauses when marking is in progress") \ + product(bool, G1GCAllocationFailureALotDuringConcMark, true, \ + "Trigger evacuation failure handling in collection pauses where " \ + "marking is in progress") \ \ - product(bool, G1EvacuationFailureALotDuringConcurrentStart, true, \ - "Force use of evacuation failure handling during concurrent " \ - "start evacuation pauses") \ + product(bool, G1GCAllocationFailureALotDuringConcurrentStart, true, \ + "Trigger evacuation failure handling during concurrent start " \ + "collection pauses") \ \ - product(bool, G1EvacuationFailureALotDuringYoungGC, true, \ - "Force use of evacuation failure handling during young " \ - "evacuation pauses") \ + product(bool, G1GCAllocationFailureALotDuringYoungGC, true, \ + "Trigger evacuation failure handling during young collection " \ + "pauses") \ \ - product(bool, G1EvacuationFailureALotDuringMixedGC, true, \ + product(bool, G1GCAllocationFailureALotDuringMixedGC, true, \ "Force use of evacuation failure handling during mixed " \ - "evacuation pauses") \ + "collection pauses") \ \ - product(uint, G1EvacuationFailureALotCSetPercent, 100, \ + product(uint, G1GCAllocationFailureALotCSetPercent, 100, \ "The percentage of regions in the collection set starting " \ - "from the beginning where the forced evacuation failure " \ - "injection will be applied.") \ + "from the beginning where the allocation failures are " \ + "injected.") \ range(1, 100) #else #define GC_G1_EVACUATION_FAILURE_FLAGS(develop, \ @@ -113,11 +113,11 @@ "of the optimal occupancy to start marking.") \ range(1, max_intx) \ \ - product(uint, G1ConfidencePercent, 50, \ + product(uint, G1ConfidencePercent, 50, \ "Confidence level for MMU/pause predictions") \ range(0, 100) \ \ - product(intx, G1SummarizeRSetStatsPeriod, 0, DIAGNOSTIC, \ + product(uintx, G1SummarizeRSetStatsPeriod, 0, DIAGNOSTIC, \ "The period (in number of GCs) at which we will generate " \ "update buffer processing info " \ "(0 means do not periodically generate this info); " \ @@ -148,7 +148,7 @@ "Number of entries in an SATB log buffer.") \ constraint(G1SATBBufferSizeConstraintFunc, AtParse) \ \ - develop(intx, G1SATBProcessCompletedThreshold, 20, \ + develop(uintx, G1SATBProcessCompletedThreshold, 20, \ "Number of completed buffers that triggers log processing.") \ range(0, max_jint) \ \ @@ -324,6 +324,10 @@ "retained region restore purposes.") \ range(1, 256) \ \ + product(uint, G1NumCollectionsKeepPinned, 8, DIAGNOSTIC, \ + "After how many GCs a region has been found pinned G1 should " \ + "give up reclaiming it.") \ + \ product(uint, G1NumCardsCostSampleThreshold, 1000, DIAGNOSTIC, \ "Threshold for the number of cards when reporting remembered set "\ "card cost related prediction samples. A sample must involve " \ diff --git a/src/hotspot/share/gc/g1/heapRegion.cpp b/src/hotspot/share/gc/g1/heapRegion.cpp index da11963317ef7..29fe5031a354a 100644 --- a/src/hotspot/share/gc/g1/heapRegion.cpp +++ b/src/hotspot/share/gc/g1/heapRegion.cpp @@ -232,7 +232,8 @@ HeapRegion::HeapRegion(uint hrm_index, _young_index_in_cset(-1), _surv_rate_group(nullptr), _age_index(G1SurvRateGroup::InvalidAgeIndex), - _node_index(G1NUMA::UnknownNodeIndex) + _node_index(G1NUMA::UnknownNodeIndex), + _pinned_object_count(0) { assert(Universe::on_page_boundary(mr.start()) && Universe::on_page_boundary(mr.end()), "invalid space boundaries"); @@ -423,6 +424,7 @@ void HeapRegion::print_on(outputStream* st) const { st->print("|-"); } } + st->print("|%3u", Atomic::load(&_pinned_object_count)); st->print_cr(""); } @@ -726,9 +728,20 @@ void HeapRegion::fill_with_dummy_object(HeapWord* address, size_t word_size, boo void HeapRegion::fill_range_with_dead_objects(HeapWord* start, HeapWord* end) { size_t range_size = pointer_delta(end, start); - // Fill the dead range with objects. G1 might need to create two objects if - // the range is larger than half a region, which is the max_fill_size(). - CollectedHeap::fill_with_objects(start, range_size); + // We must be a bit careful with regions that contain pinned objects. While the + // ranges passed in here corresponding to the space between live objects, it is + // possible that there is a pinned object that is not any more referenced by + // Java code (only by native). + // + // In this case we must not zap contents of such an array but we can overwrite + // the header; since only pinned typearrays are allowed, this fits nicely with + // putting filler arrays into the dead range as the object header sizes match and + // no user data is overwritten. + // + // In particular String Deduplication might change the reference to the character + // array of the j.l.String after native code obtained a raw reference to it (via + // GetStringCritical()). + CollectedHeap::fill_with_objects(start, range_size, !has_pinned_objects()); HeapWord* current = start; do { // Update the BOT if the a threshold is crossed. diff --git a/src/hotspot/share/gc/g1/heapRegion.hpp b/src/hotspot/share/gc/g1/heapRegion.hpp index 45d39924abaf2..2706b814000a5 100644 --- a/src/hotspot/share/gc/g1/heapRegion.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.hpp @@ -256,6 +256,9 @@ class HeapRegion : public CHeapObj { // NUMA node. uint _node_index; + // Number of objects in this region that are currently pinned. + volatile uint _pinned_object_count; + void report_region_type_change(G1HeapRegionTraceType::Type to); template @@ -299,6 +302,9 @@ class HeapRegion : public CHeapObj { static uint LogOfHRGrainBytes; static uint LogCardsPerRegion; + inline void increment_pinned_object_count(); + inline void decrement_pinned_object_count(); + static size_t GrainBytes; static size_t GrainWords; static size_t CardsPerRegion; @@ -402,6 +408,9 @@ class HeapRegion : public CHeapObj { bool is_old_or_humongous() const { return _type.is_old_or_humongous(); } + uint pinned_count() const { return Atomic::load(&_pinned_object_count); } + bool has_pinned_objects() const { return pinned_count() > 0; } + void set_free(); void set_eden(); diff --git a/src/hotspot/share/gc/g1/heapRegion.inline.hpp b/src/hotspot/share/gc/g1/heapRegion.inline.hpp index e7e10ea5ffe6c..ec68407b546bd 100644 --- a/src/hotspot/share/gc/g1/heapRegion.inline.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.inline.hpp @@ -553,4 +553,12 @@ inline void HeapRegion::record_surv_words_in_group(size_t words_survived) { _surv_rate_group->record_surviving_words(age, words_survived); } +inline void HeapRegion::increment_pinned_object_count() { + Atomic::add(&_pinned_object_count, 1u, memory_order_relaxed); +} + +inline void HeapRegion::decrement_pinned_object_count() { + Atomic::sub(&_pinned_object_count, 1u, memory_order_relaxed); +} + #endif // SHARE_GC_G1_HEAPREGION_INLINE_HPP diff --git a/src/hotspot/share/gc/g1/vmStructs_g1.hpp b/src/hotspot/share/gc/g1/vmStructs_g1.hpp index e7df5277e862a..94ade0f387c00 100644 --- a/src/hotspot/share/gc/g1/vmStructs_g1.hpp +++ b/src/hotspot/share/gc/g1/vmStructs_g1.hpp @@ -41,6 +41,7 @@ nonstatic_field(HeapRegion, _bottom, HeapWord* const) \ nonstatic_field(HeapRegion, _top, HeapWord* volatile) \ nonstatic_field(HeapRegion, _end, HeapWord* const) \ + nonstatic_field(HeapRegion, _pinned_object_count, volatile uint) \ \ nonstatic_field(HeapRegionType, _tag, HeapRegionType::Tag volatile) \ \ diff --git a/src/hotspot/share/gc/parallel/objectStartArray.cpp b/src/hotspot/share/gc/parallel/objectStartArray.cpp index 804b936393c45..f55324f5997a0 100644 --- a/src/hotspot/share/gc/parallel/objectStartArray.cpp +++ b/src/hotspot/share/gc/parallel/objectStartArray.cpp @@ -25,32 +25,21 @@ #include "precompiled.hpp" #include "gc/parallel/objectStartArray.inline.hpp" #include "gc/shared/cardTableBarrierSet.hpp" -#include "memory/allocation.inline.hpp" #include "nmt/memTracker.hpp" #include "oops/oop.inline.hpp" #include "runtime/java.hpp" #include "utilities/align.hpp" -uint ObjectStartArray::_card_shift = 0; -uint ObjectStartArray::_card_size = 0; -uint ObjectStartArray::_card_size_in_words = 0; +static size_t num_bytes_required(MemRegion mr) { + assert(CardTable::is_card_aligned(mr.start()), "precondition"); + assert(CardTable::is_card_aligned(mr.end()), "precondition"); -void ObjectStartArray::initialize_block_size(uint card_shift) { - _card_shift = card_shift; - _card_size = 1 << _card_shift; - _card_size_in_words = _card_size / sizeof(HeapWord); + return mr.word_size() / BOTConstants::card_size_in_words(); } void ObjectStartArray::initialize(MemRegion reserved_region) { - // We're based on the assumption that we use the same - // size blocks as the card table. - assert(_card_size == CardTable::card_size(), "Sanity"); - assert(_card_size <= MaxBlockSize, "block_size must be less than or equal to " UINT32_FORMAT, MaxBlockSize); - // Calculate how much space must be reserved - _reserved_region = reserved_region; - - size_t bytes_to_reserve = reserved_region.word_size() / _card_size_in_words; + size_t bytes_to_reserve = num_bytes_required(reserved_region); assert(bytes_to_reserve > 0, "Sanity"); bytes_to_reserve = @@ -62,91 +51,96 @@ void ObjectStartArray::initialize(MemRegion reserved_region) { if (!backing_store.is_reserved()) { vm_exit_during_initialization("Could not reserve space for ObjectStartArray"); } - MemTracker::record_virtual_memory_type((address)backing_store.base(), mtGC); + MemTracker::record_virtual_memory_type(backing_store.base(), mtGC); // We do not commit any memory initially _virtual_space.initialize(backing_store); - _raw_base = (jbyte*)_virtual_space.low_boundary(); - assert(_raw_base != nullptr, "set from the backing_store"); - - _offset_base = _raw_base - (size_t(reserved_region.start()) >> _card_shift); - - _covered_region.set_start(reserved_region.start()); - _covered_region.set_word_size(0); + assert(_virtual_space.low_boundary() != nullptr, "set from the backing_store"); - _blocks_region.set_start((HeapWord*)_raw_base); - _blocks_region.set_word_size(0); + _offset_base = (uint8_t*)(_virtual_space.low_boundary() - (uintptr_t(reserved_region.start()) >> BOTConstants::log_card_size())); } void ObjectStartArray::set_covered_region(MemRegion mr) { - assert(_reserved_region.contains(mr), "MemRegion outside of reserved space"); - assert(_reserved_region.start() == mr.start(), "Attempt to move covered region"); - - HeapWord* low_bound = mr.start(); - HeapWord* high_bound = mr.end(); - assert((uintptr_t(low_bound) & (_card_size - 1)) == 0, "heap must start at block boundary"); - assert((uintptr_t(high_bound) & (_card_size - 1)) == 0, "heap must end at block boundary"); - - size_t requested_blocks_size_in_bytes = mr.word_size() / _card_size_in_words; + DEBUG_ONLY(_covered_region = mr;) + size_t requested_size = num_bytes_required(mr); // Only commit memory in page sized chunks - requested_blocks_size_in_bytes = - align_up(requested_blocks_size_in_bytes, os::vm_page_size()); + requested_size = align_up(requested_size, os::vm_page_size()); - _covered_region = mr; + size_t current_size = _virtual_space.committed_size(); - size_t current_blocks_size_in_bytes = _blocks_region.byte_size(); + if (requested_size == current_size) { + return; + } - if (requested_blocks_size_in_bytes > current_blocks_size_in_bytes) { + if (requested_size > current_size) { // Expand - size_t expand_by = requested_blocks_size_in_bytes - current_blocks_size_in_bytes; + size_t expand_by = requested_size - current_size; if (!_virtual_space.expand_by(expand_by)) { vm_exit_out_of_memory(expand_by, OOM_MMAP_ERROR, "object start array expansion"); } - // Clear *only* the newly allocated region - memset(_blocks_region.end(), clean_block, expand_by); - } - - if (requested_blocks_size_in_bytes < current_blocks_size_in_bytes) { + } else { // Shrink - size_t shrink_by = current_blocks_size_in_bytes - requested_blocks_size_in_bytes; + size_t shrink_by = current_size - requested_size; _virtual_space.shrink_by(shrink_by); } - - _blocks_region.set_word_size(requested_blocks_size_in_bytes / sizeof(HeapWord)); - - assert(requested_blocks_size_in_bytes % sizeof(HeapWord) == 0, "Block table not expanded in word sized increment"); - assert(requested_blocks_size_in_bytes == _blocks_region.byte_size(), "Sanity"); - assert(block_for_addr(low_bound) == &_raw_base[0], "Checking start of map"); - assert(block_for_addr(high_bound-1) <= &_raw_base[_blocks_region.byte_size()-1], "Checking end of map"); } -void ObjectStartArray::reset() { - memset(_blocks_region.start(), clean_block, _blocks_region.byte_size()); +static void fill_range(uint8_t* start, uint8_t* end, uint8_t v) { + // + 1 for inclusive + memset(start, v, pointer_delta(end, start, sizeof(uint8_t)) + 1); } -bool ObjectStartArray::object_starts_in_range(HeapWord* start_addr, - HeapWord* end_addr) const { - assert(start_addr <= end_addr, - "Range is wrong. start_addr (" PTR_FORMAT ") is after end_addr (" PTR_FORMAT ")", - p2i(start_addr), p2i(end_addr)); - - assert(is_aligned(start_addr, _card_size), "precondition"); - - if (start_addr == end_addr) { - // No objects in empty range. - return false; +void ObjectStartArray::update_for_block_work(HeapWord* blk_start, + HeapWord* blk_end) { + HeapWord* const cur_card_boundary = align_up_by_card_size(blk_start); + uint8_t* const offset_entry = entry_for_addr(cur_card_boundary); + + // The first card holds the actual offset. + *offset_entry = checked_cast(pointer_delta(cur_card_boundary, blk_start)); + + // Check if this block spans over other cards. + uint8_t* const end_entry = entry_for_addr(blk_end - 1); + assert(offset_entry <= end_entry, "inv"); + + if (offset_entry != end_entry) { + // Handling remaining entries. + uint8_t* start_entry_for_region = offset_entry + 1; + for (uint i = 0; i < BOTConstants::N_powers; i++) { + // -1 so that the reach ends in this region and not at the start + // of the next. + uint8_t* reach = offset_entry + BOTConstants::power_to_cards_back(i + 1) - 1; + uint8_t value = checked_cast(BOTConstants::card_size_in_words() + i); + + fill_range(start_entry_for_region, MIN2(reach, end_entry), value); + start_entry_for_region = reach + 1; + + if (reach >= end_entry) { + break; + } + } + assert(start_entry_for_region > end_entry, "Sanity check"); } - jbyte* start_block = block_for_addr(start_addr); - jbyte* end_block = block_for_addr(end_addr - 1); + debug_only(verify_for_block(blk_start, blk_end);) +} - for (jbyte* block = start_block; block <= end_block; block++) { - if (*block != clean_block) { - return true; +void ObjectStartArray::verify_for_block(HeapWord* blk_start, HeapWord* blk_end) const { + assert(is_crossing_card_boundary(blk_start, blk_end), "precondition"); + + const uint8_t* const start_entry = entry_for_addr(align_up_by_card_size(blk_start)); + const uint8_t* const end_entry = entry_for_addr(blk_end - 1); + // Check entries in [start_entry, end_entry] + assert(*start_entry < BOTConstants::card_size_in_words(), "offset entry"); + + for (const uint8_t* i = start_entry + 1; i <= end_entry; ++i) { + const uint8_t prev = *(i-1); + const uint8_t value = *i; + if (prev != value) { + assert(value >= prev, "monotonic"); + size_t n_cards_back = BOTConstants::entry_to_cards_back(value); + assert(start_entry == (i - n_cards_back), "inv"); } } - - return false; } diff --git a/src/hotspot/share/gc/parallel/objectStartArray.hpp b/src/hotspot/share/gc/parallel/objectStartArray.hpp index 06005fc007561..cc310997b4e2a 100644 --- a/src/hotspot/share/gc/parallel/objectStartArray.hpp +++ b/src/hotspot/share/gc/parallel/objectStartArray.hpp @@ -26,6 +26,7 @@ #define SHARE_GC_PARALLEL_OBJECTSTARTARRAY_HPP #include "gc/parallel/psVirtualspace.hpp" +#include "gc/shared/blockOffsetTable.hpp" #include "memory/allocation.hpp" #include "memory/memRegion.hpp" #include "oops/oop.hpp" @@ -36,141 +37,65 @@ // class ObjectStartArray : public CHeapObj { - friend class VerifyObjectStartArrayClosure; - - private: - PSVirtualSpace _virtual_space; - MemRegion _reserved_region; // The committed (old-gen heap) virtual space this object-start-array covers. - MemRegion _covered_region; - MemRegion _blocks_region; - jbyte* _raw_base; - jbyte* _offset_base; - - static uint _card_shift; - static uint _card_size; - static uint _card_size_in_words; - - public: - - enum BlockValueConstants { - clean_block = -1 - }; - - // Maximum size an offset table entry can cover. This maximum is derived from that - // we need an extra bit for possible offsets in the byte for backskip values, leaving 2^7 possible offsets. - // Minimum object alignment is 8 bytes (2^3), so we can at most represent 2^10 offsets within a BOT value. - static const uint MaxBlockSize = 1024; - - // Initialize block size based on card size - static void initialize_block_size(uint card_shift); + DEBUG_ONLY(MemRegion _covered_region;) - static uint card_shift() { - return _card_shift; - } - - static uint card_size() { - return _card_size; - } - static uint card_size_in_words() { - return _card_size_in_words; - } + // BOT array + PSVirtualSpace _virtual_space; - protected: + // Biased array-start of BOT array for fast heap-addr / BOT entry translation + uint8_t* _offset_base; // Mapping from address to object start array entry - jbyte* block_for_addr(void* p) const { + uint8_t* entry_for_addr(const void* const p) const { assert(_covered_region.contains(p), "out of bounds access to object start array"); - jbyte* result = &_offset_base[uintptr_t(p) >> _card_shift]; - assert(_blocks_region.contains(result), - "out of bounds result in byte_for"); + uint8_t* result = &_offset_base[uintptr_t(p) >> BOTConstants::log_card_size()]; return result; } // Mapping from object start array entry to address of first word - HeapWord* addr_for_block(jbyte* p) { - assert(_blocks_region.contains(p), - "out of bounds access to object start array"); - size_t delta = pointer_delta(p, _offset_base, sizeof(jbyte)); - HeapWord* result = (HeapWord*) (delta << _card_shift); + HeapWord* addr_for_entry(const uint8_t* const p) const { + size_t delta = pointer_delta(p, _offset_base, sizeof(uint8_t)); + HeapWord* result = (HeapWord*) (delta << BOTConstants::log_card_size()); assert(_covered_region.contains(result), "out of bounds accessor from card marking array"); return result; } - // Mapping that includes the derived offset. - // If the block is clean, returns the last address in the covered region. - // If the block is < index 0, returns the start of the covered region. - HeapWord* offset_addr_for_block(jbyte* p) const { - // We have to do this before the assert - if (p < _raw_base) { - return _covered_region.start(); - } - - assert(_blocks_region.contains(p), - "out of bounds access to object start array"); - - if (*p == clean_block) { - return _covered_region.end(); - } + static HeapWord* align_up_by_card_size(HeapWord* const addr) { + return align_up(addr, BOTConstants::card_size()); + } - size_t delta = pointer_delta(p, _offset_base, sizeof(jbyte)); - HeapWord* result = (HeapWord*) (delta << _card_shift); - result += *p; + void update_for_block_work(HeapWord* blk_start, HeapWord* blk_end); - assert(_covered_region.contains(result), - "out of bounds accessor from card marking array"); - - return result; - } + void verify_for_block(HeapWord* blk_start, HeapWord* blk_end) const; public: - - // This method is in lieu of a constructor, so that this class can be - // embedded inline in other classes. void initialize(MemRegion reserved_region); + // Heap old-gen resizing void set_covered_region(MemRegion mr); - void reset(); - - MemRegion covered_region() { return _covered_region; } - -#define assert_covered_region_contains(addr) \ - assert(_covered_region.contains(addr), \ - #addr " (" PTR_FORMAT ") is not in covered region [" PTR_FORMAT ", " PTR_FORMAT "]", \ - p2i(addr), p2i(_covered_region.start()), p2i(_covered_region.end())) - - void allocate_block(HeapWord* p) { - assert_covered_region_contains(p); - jbyte* block = block_for_addr(p); - HeapWord* block_base = addr_for_block(block); - size_t offset = pointer_delta(p, block_base, sizeof(HeapWord*)); - assert(offset < 128, "Sanity"); - // When doing MT offsets, we can't assert this. - //assert(offset > *block, "Found backwards allocation"); - *block = (jbyte)offset; + static bool is_crossing_card_boundary(HeapWord* const blk_start, + HeapWord* const blk_end) { + HeapWord* cur_card_boundary = align_up_by_card_size(blk_start); + // Strictly greater-than, since we check if this block *crosses* card boundary. + return blk_end > cur_card_boundary; } - // Optimized for finding the first object that crosses into - // a given block. The blocks contain the offset of the last - // object in that block. Scroll backwards by one, and the first - // object hit should be at the beginning of the block - inline HeapWord* object_start(HeapWord* addr) const; + // Returns the address of the start of the block reaching into the card containing + // "addr". + inline HeapWord* block_start_reaching_into_card(HeapWord* const addr) const; - bool is_block_allocated(HeapWord* addr) { - assert_covered_region_contains(addr); - jbyte* block = block_for_addr(addr); - return *block != clean_block; + // [blk_start, blk_end) representing a block of memory in the heap. + void update_for_block(HeapWord* blk_start, HeapWord* blk_end) { + if (is_crossing_card_boundary(blk_start, blk_end)) { + update_for_block_work(blk_start, blk_end); + } } - // Return true iff an object starts in - // [start_addr, end_addr_aligned_up) - // where - // end_addr_aligned_up = align_up(end_addr, _card_size) - // Precondition: start_addr is card-size aligned - bool object_starts_in_range(HeapWord* start_addr, HeapWord* end_addr) const; + inline HeapWord* object_start(HeapWord* const addr) const; }; #endif // SHARE_GC_PARALLEL_OBJECTSTARTARRAY_HPP diff --git a/src/hotspot/share/gc/parallel/objectStartArray.inline.hpp b/src/hotspot/share/gc/parallel/objectStartArray.inline.hpp index 75650a6e1cf0b..3fb6cb61fc1e4 100644 --- a/src/hotspot/share/gc/parallel/objectStartArray.inline.hpp +++ b/src/hotspot/share/gc/parallel/objectStartArray.inline.hpp @@ -27,27 +27,41 @@ #include "gc/parallel/objectStartArray.hpp" -// Optimized for finding the first object that crosses into -// a given block. The blocks contain the offset of the last -// object in that block. Scroll backwards by one, and the first -// object hit should be at the beginning of the block -HeapWord* ObjectStartArray::object_start(HeapWord* addr) const { - assert_covered_region_contains(addr); - jbyte* block = block_for_addr(addr); - HeapWord* scroll_forward = offset_addr_for_block(block--); - while (scroll_forward > addr) { - scroll_forward = offset_addr_for_block(block--); - } +HeapWord* ObjectStartArray::object_start(HeapWord* const addr) const { + HeapWord* cur_block = block_start_reaching_into_card(addr); - HeapWord* next = scroll_forward; - while (next <= addr) { - scroll_forward = next; - next += cast_to_oop(next)->size(); + while (true) { + HeapWord* next_block = cur_block + cast_to_oop(cur_block)->size(); + if (next_block > addr) { + assert(cur_block <= addr, "postcondition"); + return cur_block; + } + // Because the BOT is precise, we should never step into the next card + // (i.e. crossing the card boundary). + assert(!is_crossing_card_boundary(next_block, addr), "must be"); + cur_block = next_block; } - assert(scroll_forward <= addr, "wrong order for current and arg"); - assert(addr <= next, "wrong order for arg and next"); - return scroll_forward; } +HeapWord* ObjectStartArray::block_start_reaching_into_card(HeapWord* const addr) const { + const uint8_t* entry = entry_for_addr(addr); + + uint8_t offset; + while (true) { + offset = *entry; + + if (offset < BOTConstants::card_size_in_words()) { + break; + } + + // The excess of the offset from N_words indicates a power of Base + // to go back by. + size_t n_cards_back = BOTConstants::entry_to_cards_back(offset); + entry -= n_cards_back; + } + + HeapWord* q = addr_for_entry(entry); + return q - offset; +} #endif // SHARE_GC_PARALLEL_OBJECTSTARTARRAY_INLINE_HPP diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index 190e01d96740d..748a5658843b0 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -49,6 +49,7 @@ #include "memory/universe.hpp" #include "nmt/memTracker.hpp" #include "oops/oop.inline.hpp" +#include "runtime/cpuTimeCounters.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/vmThread.hpp" @@ -127,6 +128,9 @@ jint ParallelScavengeHeap::initialize() { return JNI_ENOMEM; } + // Create CPU time counter + CPUTimeCounters::create_counter(CPUTimeGroups::CPUTimeType::gc_parallel_workers); + ParallelInitLogger::print(); return JNI_OK; @@ -192,6 +196,7 @@ void ParallelScavengeHeap::update_counters() { young_gen()->update_counters(); old_gen()->update_counters(); MetaspaceCounters::update_performance_counters(); + update_parallel_worker_threads_cpu_time(); } size_t ParallelScavengeHeap::capacity() const { @@ -884,3 +889,23 @@ void ParallelScavengeHeap::pin_object(JavaThread* thread, oop obj) { void ParallelScavengeHeap::unpin_object(JavaThread* thread, oop obj) { GCLocker::unlock_critical(thread); } + +void ParallelScavengeHeap::update_parallel_worker_threads_cpu_time() { + assert(Thread::current()->is_VM_thread(), + "Must be called from VM thread to avoid races"); + if (!UsePerfData || !os::is_thread_cpu_time_supported()) { + return; + } + + // Ensure ThreadTotalCPUTimeClosure destructor is called before publishing gc + // time. + { + ThreadTotalCPUTimeClosure tttc(CPUTimeGroups::CPUTimeType::gc_parallel_workers); + // Currently parallel worker threads in GCTaskManager never terminate, so it + // is safe for VMThread to read their CPU times. If upstream changes this + // behavior, we should rethink if it is still safe. + gc_threads_do(&tttc); + } + + CPUTimeCounters::publish_gc_total_cpu_time(); +} diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp index abf87b0e01900..d30effd5e5bd4 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp @@ -101,6 +101,8 @@ class ParallelScavengeHeap : public CollectedHeap { // Allocate in oldgen and record the allocation with the size_policy. HeapWord* allocate_old_gen_and_record(size_t word_size); + void update_parallel_worker_threads_cpu_time(); + protected: HeapWord* allocate_new_tlab(size_t min_size, size_t requested_size, size_t* actual_size) override; diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp index 34d6621c82073..3e255c15a4e0a 100644 --- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp +++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp @@ -169,22 +169,6 @@ void PSAdaptiveSizePolicy::major_collection_end(size_t amount_live, _major_timer.start(); } -// If the remaining free space in the old generation is less that -// that expected to be needed by the next collection, do a full -// collection now. -bool PSAdaptiveSizePolicy::should_full_GC(size_t old_free_in_bytes) { - - // A similar test is done in the scavenge's should_attempt_scavenge(). If - // this is changed, decide if that test should also be changed. - bool result = padded_average_promoted_in_bytes() > (float) old_free_in_bytes; - log_trace(gc, ergo)("%s after scavenge average_promoted " SIZE_FORMAT " padded_average_promoted " SIZE_FORMAT " free in old gen " SIZE_FORMAT, - result ? "Full" : "No full", - (size_t) average_promoted_in_bytes(), - (size_t) padded_average_promoted_in_bytes(), - old_free_in_bytes); - return result; -} - void PSAdaptiveSizePolicy::clear_generation_free_space_flags() { AdaptiveSizePolicy::clear_generation_free_space_flags(); diff --git a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp index fb5c30f824ad1..1ffd9a49dcad9 100644 --- a/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp +++ b/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.hpp @@ -116,7 +116,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { private: // Accessors - AdaptivePaddedAverage* avg_major_pause() const { return _avg_major_pause; } double gc_minor_pause_goal_sec() const { return _gc_minor_pause_goal_sec; } void adjust_eden_for_minor_pause_time(bool is_full_gc, @@ -160,7 +159,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { size_t scale_down(size_t change, double part, double total); protected: - // Time accessors // Footprint accessors size_t live_space() const { @@ -226,10 +224,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { size_t calculated_old_free_size_in_bytes() const; - size_t average_old_live_in_bytes() const { - return (size_t) avg_old_live()->average(); - } - size_t average_promoted_in_bytes() const { return (size_t)avg_promoted()->average(); } @@ -252,40 +246,6 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { _change_old_gen_for_min_pauses = v; } - // Return true if the old generation size was changed - // to try to reach a pause time goal. - bool old_gen_changed_for_pauses() { - bool result = _change_old_gen_for_maj_pauses != 0 || - _change_old_gen_for_min_pauses != 0; - return result; - } - - // Return true if the young generation size was changed - // to try to reach a pause time goal. - bool young_gen_changed_for_pauses() { - bool result = _change_young_gen_for_min_pauses != 0 || - _change_young_gen_for_maj_pauses != 0; - return result; - } - // end flags for pause goal - - // Return true if the old generation size was changed - // to try to reach a throughput goal. - bool old_gen_changed_for_throughput() { - bool result = _change_old_gen_for_throughput != 0; - return result; - } - - // Return true if the young generation size was changed - // to try to reach a throughput goal. - bool young_gen_changed_for_throughput() { - bool result = _change_young_gen_for_throughput != 0; - return result; - } - - int decrease_for_footprint() { return _decrease_for_footprint; } - - // Accessors for estimators. The slope of the linear fit is // currently all that is used for making decisions. @@ -293,22 +253,12 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy { return _major_pause_old_estimator; } - LinearLeastSquareFit* major_pause_young_estimator() { - return _major_pause_young_estimator; - } - - virtual void clear_generation_free_space_flags(); double major_pause_old_slope() { return _major_pause_old_estimator->slope(); } double major_pause_young_slope() { return _major_pause_young_estimator->slope(); } - double major_collection_slope() { return _major_collection_estimator->slope();} - - // Given the amount of live data in the heap, should we - // perform a Full GC? - bool should_full_GC(size_t live_in_old_gen); // Calculates optimal (free) space sizes for both the young and old // generations. Stores results in _eden_size and _promo_size. diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.hpp index 65409f5785f04..458d33af74a87 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.hpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.hpp @@ -105,7 +105,8 @@ class ParCompactionManager : public CHeapObj { // Returns true and a valid task if there has not been enough space in the shared // objArray stack, otherwise returns false and the task is invalid. bool publish_or_pop_objarray_tasks(ObjArrayTask& task); - protected: + + ParCompactionManager(); // Array of task queues. Needed by the task terminator. static RegionTaskQueueSet* region_task_queues() { return _region_task_queues; } OopTaskQueue* oop_stack() { return &_oop_stack; } @@ -155,7 +156,6 @@ class ParCompactionManager : public CHeapObj { // Simply use the first compaction manager here. static ParCompactionManager* get_vmthread_cm() { return _manager_array[0]; } - ParCompactionManager(); ParMarkBitMap* mark_bitmap() { return _mark_bitmap; } diff --git a/src/hotspot/share/gc/parallel/psOldGen.cpp b/src/hotspot/share/gc/parallel/psOldGen.cpp index 8124f018b2882..14be4745b153d 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.cpp +++ b/src/hotspot/share/gc/parallel/psOldGen.cpp @@ -92,10 +92,10 @@ void PSOldGen::initialize_work(const char* perf_data_name, int level) { // If this wasn't true, a single card could span more than one generation, // which would cause problems when we commit/uncommit memory, and when we // clear and dirty cards. - guarantee(ct->is_card_aligned(reserved_mr.start()), "generation must be card aligned"); + guarantee(CardTable::is_card_aligned(reserved_mr.start()), "generation must be card aligned"); // Check the heap layout documented at `class ParallelScavengeHeap`. assert(reserved_mr.end() != heap->reserved_region().end(), "invariant"); - guarantee(ct->is_card_aligned(reserved_mr.end()), "generation must be card aligned"); + guarantee(CardTable::is_card_aligned(reserved_mr.end()), "generation must be card aligned"); // // ObjectSpace stuff @@ -133,18 +133,14 @@ size_t PSOldGen::num_iterable_blocks() const { void PSOldGen::object_iterate_block(ObjectClosure* cl, size_t block_index) { size_t block_word_size = IterateBlockSize / HeapWordSize; - assert((block_word_size % (ObjectStartArray::card_size())) == 0, - "Block size not a multiple of start_array block"); + assert((block_word_size % BOTConstants::card_size_in_words()) == 0, + "To ensure fast object_start calls"); MutableSpace *space = object_space(); HeapWord* begin = space->bottom() + block_index * block_word_size; HeapWord* end = MIN2(space->top(), begin + block_word_size); - if (!start_array()->object_starts_in_range(begin, end)) { - return; - } - // Get object starting at or reaching into this block. HeapWord* start = start_array()->object_start(begin); if (start < begin) { @@ -286,8 +282,8 @@ void PSOldGen::shrink(size_t bytes) { void PSOldGen::complete_loaded_archive_space(MemRegion archive_space) { HeapWord* cur = archive_space.start(); while (cur < archive_space.end()) { - _start_array.allocate_block(cur); size_t word_size = cast_to_oop(cur)->size(); + _start_array.update_for_block(cur, cur + word_size); cur += word_size; } } @@ -390,14 +386,13 @@ void PSOldGen::verify() { class VerifyObjectStartArrayClosure : public ObjectClosure { ObjectStartArray* _start_array; - public: +public: VerifyObjectStartArrayClosure(ObjectStartArray* start_array) : _start_array(start_array) { } virtual void do_object(oop obj) { HeapWord* test_addr = cast_from_oop(obj) + 1; guarantee(_start_array->object_start(test_addr) == cast_from_oop(obj), "ObjectStartArray cannot find start of object"); - guarantee(_start_array->is_block_allocated(cast_from_oop(obj)), "ObjectStartArray missing block allocation"); } }; diff --git a/src/hotspot/share/gc/parallel/psOldGen.hpp b/src/hotspot/share/gc/parallel/psOldGen.hpp index c26f251f9a275..4898baa3a4409 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.hpp +++ b/src/hotspot/share/gc/parallel/psOldGen.hpp @@ -51,29 +51,11 @@ class PSOldGen : public CHeapObj { // Block size for parallel iteration static const size_t IterateBlockSize = 1024 * 1024; -#ifdef ASSERT - void assert_block_in_covered_region(MemRegion new_memregion) { - // Explicitly capture current covered_region in a local - MemRegion covered_region = this->start_array()->covered_region(); - assert(covered_region.contains(new_memregion), - "new region is not in covered_region [ " PTR_FORMAT ", " PTR_FORMAT " ], " - "new region [ " PTR_FORMAT ", " PTR_FORMAT " ], " - "object space [ " PTR_FORMAT ", " PTR_FORMAT " ]", - p2i(covered_region.start()), - p2i(covered_region.end()), - p2i(new_memregion.start()), - p2i(new_memregion.end()), - p2i(this->object_space()->used_region().start()), - p2i(this->object_space()->used_region().end())); - } -#endif - HeapWord* cas_allocate_noexpand(size_t word_size) { assert_locked_or_safepoint(Heap_lock); HeapWord* res = object_space()->cas_allocate(word_size); if (res != nullptr) { - DEBUG_ONLY(assert_block_in_covered_region(MemRegion(res, word_size))); - _start_array.allocate_block(res); + _start_array.update_for_block(res, res + word_size); } return res; } diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 496f6dd35295f..09892208c355f 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -42,6 +42,7 @@ #include "gc/parallel/psScavenge.hpp" #include "gc/parallel/psStringDedup.hpp" #include "gc/parallel/psYoungGen.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/gcCause.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcId.hpp" @@ -1024,9 +1025,12 @@ void PSParallelCompact::post_compact() ct->dirty_MemRegion(old_mr); } - // Delete metaspaces for unloaded class loaders and clean up loader_data graph - ClassLoaderDataGraph::purge(/*at_safepoint*/true); - DEBUG_ONLY(MetaspaceUtils::verify();) + { + // Delete metaspaces for unloaded class loaders and clean up loader_data graph + GCTraceTime(Debug, gc, phases) t("Purge Class Loader Data", gc_timer()); + ClassLoaderDataGraph::purge(true /* at_safepoint */); + DEBUG_ONLY(MetaspaceUtils::verify();) + } // Need to clear claim bits for the next mark. ClassLoaderDataGraph::clear_claimed_marks(); @@ -1492,7 +1496,7 @@ void PSParallelCompact::fill_dense_prefix_end(SpaceId id) _mark_bitmap.mark_obj(obj_beg, obj_len); _summary_data.add_obj(obj_beg, obj_len); assert(start_array(id) != nullptr, "sanity"); - start_array(id)->allocate_block(obj_beg); + start_array(id)->update_for_block(obj_beg, obj_beg + obj_len); } } @@ -1764,6 +1768,9 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { ref_processor()->start_discovery(maximum_heap_compaction); + ClassUnloadingContext ctx(1 /* num_nmethod_unlink_workers */, + false /* lock_codeblob_free_separately */); + marking_phase(&_gc_tracer); bool max_on_system_gc = UseMaximumCompactionOnSystemGC @@ -2053,6 +2060,8 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { { GCTraceTime(Debug, gc, phases) tm_m("Class Unloading", &_gc_timer); + ClassUnloadingContext* ctx = ClassUnloadingContext::context(); + bool unloading_occurred; { CodeCache::UnlinkingScope scope(is_alive_closure()); @@ -2064,8 +2073,15 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { CodeCache::do_unloading(unloading_occurred); } - // Release unloaded nmethods's memory. - CodeCache::flush_unlinked_nmethods(); + { + GCTraceTime(Debug, gc, phases) t("Purge Unlinked NMethods", gc_timer()); + // Release unloaded nmethod's memory. + ctx->purge_nmethods(); + } + { + GCTraceTime(Debug, gc, phases) t("Free Code Blobs", gc_timer()); + ctx->free_code_blobs(); + } // Prune dead klasses from subklass/sibling/implementor lists. Klass::clean_weak_klass_links(unloading_occurred); @@ -2446,7 +2462,6 @@ void PSParallelCompact::compact() { ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); PSOldGen* old_gen = heap->old_gen(); - old_gen->start_array()->reset(); uint active_gc_threads = ParallelScavengeHeap::heap()->workers().active_workers(); // for [0..last_space_id) @@ -2518,7 +2533,7 @@ void PSParallelCompact::verify_complete(SpaceId space_id) { #endif // #ifdef ASSERT inline void UpdateOnlyClosure::do_addr(HeapWord* addr) { - _start_array->allocate_block(addr); + _start_array->update_for_block(addr, addr + cast_to_oop(addr)->size()); compaction_manager()->update_contents(cast_to_oop(addr)); } @@ -2611,7 +2626,7 @@ void PSParallelCompact::update_deferred_object(ParCompactionManager* cm, HeapWor const SpaceInfo* const space_info = _space_info + space_id(addr); ObjectStartArray* const start_array = space_info->start_array(); if (start_array != nullptr) { - start_array->allocate_block(addr); + start_array->update_for_block(addr, addr + cast_to_oop(addr)->size()); } cm->update_contents(cast_to_oop(addr)); @@ -3117,7 +3132,7 @@ MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) { // The start_array must be updated even if the object is not moving. if (_start_array != nullptr) { - _start_array->allocate_block(destination()); + _start_array->update_for_block(destination(), destination() + words); } if (copy_destination() != source()) { @@ -3157,7 +3172,6 @@ UpdateOnlyClosure::UpdateOnlyClosure(ParMarkBitMap* mbm, ParCompactionManager* cm, PSParallelCompact::SpaceId space_id) : ParMarkBitMapClosure(mbm, cm), - _space_id(space_id), _start_array(PSParallelCompact::start_array(space_id)) { } @@ -3182,8 +3196,9 @@ FillClosure::do_addr(HeapWord* addr, size_t size) { CollectedHeap::fill_with_objects(addr, size); HeapWord* const end = addr + size; do { - _start_array->allocate_block(addr); - addr += cast_to_oop(addr)->size(); + size_t size = cast_to_oop(addr)->size(); + _start_array->update_for_block(addr, addr + size); + addr += size; } while (addr < end); return ParMarkBitMap::incomplete; } diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.hpp b/src/hotspot/share/gc/parallel/psParallelCompact.hpp index d9644d3ddba79..4cee322a589e4 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.hpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.hpp @@ -176,9 +176,6 @@ class SpaceInfo // Allows new_top to be set. HeapWord** new_top_addr() { return &_new_top; } - // Where the smallest allowable dense prefix ends (used only for perm gen). - HeapWord* min_dense_prefix() const { return _min_dense_prefix; } - // Where the dense prefix ends, or the compacted region begins. HeapWord* dense_prefix() const { return _dense_prefix; } @@ -190,7 +187,6 @@ class SpaceInfo void set_space(MutableSpace* s) { _space = s; } void set_new_top(HeapWord* addr) { _new_top = addr; } - void set_min_dense_prefix(HeapWord* addr) { _min_dense_prefix = addr; } void set_dense_prefix(HeapWord* addr) { _dense_prefix = addr; } void set_start_array(ObjectStartArray* s) { _start_array = s; } @@ -199,7 +195,6 @@ class SpaceInfo private: MutableSpace* _space; HeapWord* _new_top; - HeapWord* _min_dense_prefix; HeapWord* _dense_prefix; ObjectStartArray* _start_array; SplitInfo _split_info; @@ -1373,7 +1368,6 @@ MoveAndUpdateShadowClosure::MoveAndUpdateShadowClosure(ParMarkBitMap *bitmap, class UpdateOnlyClosure: public ParMarkBitMapClosure { private: - const PSParallelCompact::SpaceId _space_id; ObjectStartArray* const _start_array; public: diff --git a/src/hotspot/share/gc/parallel/psPromotionLAB.cpp b/src/hotspot/share/gc/parallel/psPromotionLAB.cpp index 7aa1731fd874c..4c3367cdf9c98 100644 --- a/src/hotspot/share/gc/parallel/psPromotionLAB.cpp +++ b/src/hotspot/share/gc/parallel/psPromotionLAB.cpp @@ -115,7 +115,8 @@ void PSOldPromotionLAB::flush() { assert(_start_array != nullptr, "Sanity"); - _start_array->allocate_block(obj); + // filler obj + _start_array->update_for_block(obj, obj + cast_to_oop(obj)->size()); } #ifdef ASSERT @@ -132,17 +133,11 @@ bool PSYoungPromotionLAB::lab_is_valid(MemRegion lab) { } bool PSOldPromotionLAB::lab_is_valid(MemRegion lab) { - assert(_start_array->covered_region().contains(lab), "Sanity"); - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); PSOldGen* old_gen = heap->old_gen(); MemRegion used = old_gen->object_space()->used_region(); - if (used.contains(lab)) { - return true; - } - - return false; + return used.contains(lab); } #endif /* ASSERT */ diff --git a/src/hotspot/share/gc/parallel/psPromotionLAB.hpp b/src/hotspot/share/gc/parallel/psPromotionLAB.hpp index b3c573ec70429..e8e42d3754b36 100644 --- a/src/hotspot/share/gc/parallel/psPromotionLAB.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionLAB.hpp @@ -120,7 +120,7 @@ class PSOldPromotionLAB : public PSPromotionLAB { set_top(new_top); assert(is_object_aligned(obj) && is_object_aligned(new_top), "checking alignment"); - _start_array->allocate_block(obj); + _start_array->update_for_block(obj, obj + size); return obj; } diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp index 2f114e1e2cecc..a783dfe7155bb 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.cpp +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp @@ -239,8 +239,7 @@ bool PSScavenge::invoke() { IsGCActiveMark mark; const bool scavenge_done = PSScavenge::invoke_no_policy(); - const bool need_full_gc = !scavenge_done || - policy->should_full_GC(heap->old_gen()->free_in_bytes()); + const bool need_full_gc = !scavenge_done; bool full_gc_done = false; if (UsePerfData) { @@ -703,8 +702,6 @@ bool PSScavenge::should_attempt_scavenge() { // Test to see if the scavenge will likely fail. PSAdaptiveSizePolicy* policy = heap->size_policy(); - // A similar test is done in the policy's should_full_GC(). If this is - // changed, decide if that test should also be changed. size_t avg_promoted = (size_t) policy->padded_average_promoted_in_bytes(); size_t promotion_estimate = MIN2(avg_promoted, young_gen->used_in_bytes()); bool result = promotion_estimate < old_gen->free_in_bytes(); diff --git a/src/hotspot/share/gc/serial/cardTableRS.cpp b/src/hotspot/share/gc/serial/cardTableRS.cpp index e6682854b10af..4df9fbad21213 100644 --- a/src/hotspot/share/gc/serial/cardTableRS.cpp +++ b/src/hotspot/share/gc/serial/cardTableRS.cpp @@ -28,273 +28,17 @@ #include "gc/serial/generation.hpp" #include "gc/serial/serialHeap.hpp" #include "gc/shared/space.inline.hpp" -#include "memory/allocation.inline.hpp" #include "memory/iterator.inline.hpp" -#include "oops/access.inline.hpp" -#include "oops/oop.inline.hpp" -#include "runtime/atomic.hpp" -#include "runtime/java.hpp" -#include "runtime/os.hpp" -#include "utilities/macros.hpp" - -// A dirty card to oop closure for contiguous spaces (ContiguousSpace and -// sub-classes). It knows how to filter out objects that are outside of the -// _boundary. -// (Note that because of the imprecise nature of the write barrier, this may -// iterate over oops beyond the region.) -// -// Assumptions: -// 1. That the actual top of any area in a memory region -// contained by the space is bounded by the end of the contiguous -// region of the space. -// 2. That the space is really made up of objects and not just -// blocks. - -class DirtyCardToOopClosure: public MemRegionClosure { -protected: - OopIterateClosure* _cl; - TenuredSpace* _sp; - HeapWord* _min_done; // Need a downwards traversal to compensate - // imprecise write barrier; this is the - // lowest location already done (or, - // alternatively, the lowest address that - // shouldn't be done again. null means infinity.) - NOT_PRODUCT(HeapWord* _last_bottom;) - - // Get the actual top of the area on which the closure will - // operate, given where the top is assumed to be (the end of the - // memory region passed to do_MemRegion) and where the object - // at the top is assumed to start. For example, an object may - // start at the top but actually extend past the assumed top, - // in which case the top becomes the end of the object. - HeapWord* get_actual_top(HeapWord* top, HeapWord* top_obj); - - // Walk the given memory region from bottom to (actual) top - // looking for objects and applying the oop closure (_cl) to - // them. The base implementation of this treats the area as - // blocks, where a block may or may not be an object. Sub- - // classes should override this to provide more accurate - // or possibly more efficient walking. - void walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top); - - // Walk the given memory region, from bottom to top, applying - // the given oop closure to (possibly) all objects found. The - // given oop closure may or may not be the same as the oop - // closure with which this closure was created, as it may - // be a filtering closure which makes use of the _boundary. - // We offer two signatures, so the FilteringClosure static type is - // apparent. - void walk_mem_region_with_cl(MemRegion mr, - HeapWord* bottom, HeapWord* top, - OopIterateClosure* cl); -public: - DirtyCardToOopClosure(TenuredSpace* sp, OopIterateClosure* cl) : - _cl(cl), _sp(sp), _min_done(nullptr) { - NOT_PRODUCT(_last_bottom = nullptr); - } - - void do_MemRegion(MemRegion mr) override; -}; - -HeapWord* DirtyCardToOopClosure::get_actual_top(HeapWord* top, - HeapWord* top_obj) { - if (top_obj != nullptr && top_obj < _sp->top()) { - if (cast_to_oop(top_obj)->is_objArray() || cast_to_oop(top_obj)->is_typeArray()) { - // An arrayOop is starting on the dirty card - since we do exact - // store checks for objArrays we are done. - } else { - // Otherwise, it is possible that the object starting on the dirty - // card spans the entire card, and that the store happened on a - // later card. Figure out where the object ends. - top = top_obj + cast_to_oop(top_obj)->size(); - } - } else { - top = _sp->top(); - } - return top; -} - -void DirtyCardToOopClosure::walk_mem_region(MemRegion mr, - HeapWord* bottom, - HeapWord* top) { - // Note that this assumption won't hold if we have a concurrent - // collector in this space, which may have freed up objects after - // they were dirtied and before the stop-the-world GC that is - // examining cards here. - assert(bottom < top, "ought to be at least one obj on a dirty card."); - - walk_mem_region_with_cl(mr, bottom, top, _cl); -} - -// We get called with "mr" representing the dirty region -// that we want to process. Because of imprecise marking, -// we may need to extend the incoming "mr" to the right, -// and scan more. However, because we may already have -// scanned some of that extended region, we may need to -// trim its right-end back some so we do not scan what -// we (or another worker thread) may already have scanned -// or planning to scan. -void DirtyCardToOopClosure::do_MemRegion(MemRegion mr) { - HeapWord* bottom = mr.start(); - HeapWord* last = mr.last(); - HeapWord* top = mr.end(); - HeapWord* bottom_obj; - HeapWord* top_obj; - - assert(_last_bottom == nullptr || top <= _last_bottom, - "Not decreasing"); - NOT_PRODUCT(_last_bottom = mr.start()); - - bottom_obj = _sp->block_start(bottom); - top_obj = _sp->block_start(last); - - assert(bottom_obj <= bottom, "just checking"); - assert(top_obj <= top, "just checking"); - - // Given what we think is the top of the memory region and - // the start of the object at the top, get the actual - // value of the top. - top = get_actual_top(top, top_obj); - - // If the previous call did some part of this region, don't redo. - if (_min_done != nullptr && _min_done < top) { - top = _min_done; - } - - // Top may have been reset, and in fact may be below bottom, - // e.g. the dirty card region is entirely in a now free object - // -- something that could happen with a concurrent sweeper. - bottom = MIN2(bottom, top); - MemRegion extended_mr = MemRegion(bottom, top); - assert(bottom <= top && - (_min_done == nullptr || top <= _min_done), - "overlap!"); - - // Walk the region if it is not empty; otherwise there is nothing to do. - if (!extended_mr.is_empty()) { - walk_mem_region(extended_mr, bottom_obj, top); - } - - _min_done = bottom; -} - -void DirtyCardToOopClosure::walk_mem_region_with_cl(MemRegion mr, - HeapWord* bottom, - HeapWord* top, - OopIterateClosure* cl) { - bottom += cast_to_oop(bottom)->oop_iterate_size(cl, mr); - if (bottom < top) { - HeapWord* next_obj = bottom + cast_to_oop(bottom)->size(); - while (next_obj < top) { - /* Bottom lies entirely below top, so we can call the */ - /* non-memRegion version of oop_iterate below. */ - cast_to_oop(bottom)->oop_iterate(cl); - bottom = next_obj; - next_obj = bottom + cast_to_oop(bottom)->size(); - } - /* Last object. */ - cast_to_oop(bottom)->oop_iterate(cl, mr); - } -} - -class ClearNoncleanCardWrapper: public MemRegionClosure { - DirtyCardToOopClosure* _dirty_card_closure; - CardTableRS* _ct; - -public: - - typedef CardTable::CardValue CardValue; -private: - // Clears the given card, return true if the corresponding card should be - // processed. - inline bool clear_card(CardValue* entry); - // check alignment of pointer - bool is_word_aligned(CardValue* entry); - -public: - ClearNoncleanCardWrapper(DirtyCardToOopClosure* dirty_card_closure, CardTableRS* ct); - void do_MemRegion(MemRegion mr) override; -}; - -inline bool ClearNoncleanCardWrapper::clear_card(CardValue* entry) { - assert(*entry == CardTableRS::dirty_card_val(), "Only look at dirty cards."); - *entry = CardTableRS::clean_card_val(); - return true; -} - -ClearNoncleanCardWrapper::ClearNoncleanCardWrapper( - DirtyCardToOopClosure* dirty_card_closure, CardTableRS* ct) : - _dirty_card_closure(dirty_card_closure), _ct(ct) { -} - -bool ClearNoncleanCardWrapper::is_word_aligned(CardTable::CardValue* entry) { - return (((intptr_t)entry) & (BytesPerWord-1)) == 0; -} - -// The regions are visited in *decreasing* address order. -// This order aids with imprecise card marking, where a dirty -// card may cause scanning, and summarization marking, of objects -// that extend onto subsequent cards. -void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) { - assert(mr.word_size() > 0, "Error"); - assert(_ct->is_aligned(mr.start()), "mr.start() should be card aligned"); - // mr.end() may not necessarily be card aligned. - CardValue* cur_entry = _ct->byte_for(mr.last()); - const CardValue* limit = _ct->byte_for(mr.start()); - HeapWord* end_of_non_clean = mr.end(); - HeapWord* start_of_non_clean = end_of_non_clean; - while (cur_entry >= limit) { - HeapWord* cur_hw = _ct->addr_for(cur_entry); - if ((*cur_entry != CardTableRS::clean_card_val()) && clear_card(cur_entry)) { - // Continue the dirty range by opening the - // dirty window one card to the left. - start_of_non_clean = cur_hw; - } else { - // We hit a "clean" card; process any non-empty - // "dirty" range accumulated so far. - if (start_of_non_clean < end_of_non_clean) { - const MemRegion mrd(start_of_non_clean, end_of_non_clean); - _dirty_card_closure->do_MemRegion(mrd); - } - - // fast forward through potential continuous whole-word range of clean cards beginning at a word-boundary - if (is_word_aligned(cur_entry)) { - CardValue* cur_row = cur_entry - BytesPerWord; - while (cur_row >= limit && *((intptr_t*)cur_row) == CardTableRS::clean_card_row_val()) { - cur_row -= BytesPerWord; - } - cur_entry = cur_row + BytesPerWord; - cur_hw = _ct->addr_for(cur_entry); - } - - // Reset the dirty window, while continuing to look - // for the next dirty card that will start a - // new dirty window. - end_of_non_clean = cur_hw; - start_of_non_clean = cur_hw; - } - // Note that "cur_entry" leads "start_of_non_clean" in - // its leftward excursion after this point - // in the loop and, when we hit the left end of "mr", - // will point off of the left end of the card-table - // for "mr". - cur_entry--; - } - // If the first card of "mr" was dirty, we will have - // been left with a dirty window, co-initial with "mr", - // which we now process. - if (start_of_non_clean < end_of_non_clean) { - const MemRegion mrd(start_of_non_clean, end_of_non_clean); - _dirty_card_closure->do_MemRegion(mrd); - } -} +#include "utilities/align.hpp" void CardTableRS::younger_refs_in_space_iterate(TenuredSpace* sp, OopIterateClosure* cl) { verify_used_region_at_save_marks(sp); const MemRegion urasm = sp->used_region_at_save_marks(); - non_clean_card_iterate(sp, urasm, cl, this); + if (!urasm.is_empty()) { + non_clean_card_iterate(sp, urasm, cl, this); + } } #ifdef ASSERT @@ -601,20 +345,196 @@ void CardTableRS::verify() { CardTableRS::CardTableRS(MemRegion whole_heap) : CardTable(whole_heap) { } +// Implemented word-iteration to skip long consecutive clean cards. +CardTable::CardValue* CardTableRS::find_first_dirty_card(CardValue* const start_card, + CardValue* const end_card) { + using Word = uintptr_t; + + CardValue* current_card = start_card; + + while (!is_aligned(current_card, sizeof(Word))) { + if (current_card >= end_card) { + return end_card; + } + if (is_dirty(current_card)) { + return current_card; + } + ++current_card; + } + + // Word comparison + while (current_card + sizeof(Word) <= end_card) { + Word* current_word = reinterpret_cast(current_card); + if (*current_word != (Word)clean_card_row_val()) { + // Found a dirty card in this word; fall back to per-CardValue comparison. + break; + } + current_card += sizeof(Word); + } + + // Per-CardValue comparison. + for (/* empty */; current_card < end_card; ++current_card) { + if (is_dirty(current_card)) { + return current_card; + } + } + + return end_card; +} + +// Because non-objArray objs can be imprecisely-marked (only obj-start card is +// dirty instead of the part containing old-to-young pointers), if the +// obj-start of a non-objArray is dirty, all cards that obj completely resides +// on are considered as dirty, since that obj will be iterated (scanned for +// old-to-young pointers) as a whole. +template +CardTable::CardValue* CardTableRS::find_first_clean_card(CardValue* const start_card, + CardValue* const end_card, + CardTableRS* ct, + Func& object_start) { + + // end_card might be just beyond the heap, so need to use the _raw variant. + HeapWord* end_address = ct->addr_for_raw(end_card); + + for (CardValue* current_card = start_card; current_card < end_card; /* empty */) { + if (is_dirty(current_card)) { + current_card++; + continue; + } + + // A potential candidate. + HeapWord* addr = ct->addr_for(current_card); + HeapWord* obj_start_addr = object_start(addr); + + if (obj_start_addr == addr) { + return current_card; + } + + // Final obj in dirty-chunk crosses card-boundary. + oop obj = cast_to_oop(obj_start_addr); + if (obj->is_objArray()) { + // ObjArrays are always precisely-marked so we are not allowed to jump to + // the end of the current object. + return current_card; + } + + // This might be the last object in this area, avoid trying to access the + // card beyond the allowed area. + HeapWord* next_address = obj_start_addr + obj->size(); + if (next_address >= end_address) { + break; + } + + // Card occupied by next obj. + CardValue* next_obj_card = ct->byte_for(next_address); + if (is_clean(next_obj_card)) { + return next_obj_card; + } + + // Continue the search after this known-dirty card... + current_card = next_obj_card + 1; + } + + return end_card; +} + +void CardTableRS::clear_cards(CardValue* start, CardValue* end) { + size_t num_cards = pointer_delta(end, start, sizeof(CardValue)); + memset(start, clean_card_val(), num_cards); +} + +static void prefetch_write(void *p) { + if (PrefetchScanIntervalInBytes >= 0) { + Prefetch::write(p, PrefetchScanIntervalInBytes); + } +} + +static void scan_obj_with_limit(oop obj, + OopIterateClosure* cl, + HeapWord* start, + HeapWord* end) { + if (!obj->is_typeArray()) { + prefetch_write(start); + obj->oop_iterate(cl, MemRegion(start, end)); + } +} + void CardTableRS::non_clean_card_iterate(TenuredSpace* sp, MemRegion mr, OopIterateClosure* cl, - CardTableRS* ct) -{ - if (mr.is_empty()) { - return; - } - // clear_cl finds contiguous dirty ranges of cards to process and clear. + CardTableRS* ct) { + struct { + HeapWord* start_addr; + HeapWord* end_addr; + } cached_obj { nullptr, mr.start() }; + + auto object_start = [&] (const HeapWord* const addr) { + if (addr < cached_obj.end_addr) { + assert(cached_obj.start_addr != nullptr, "inv"); + return cached_obj.start_addr; + } + HeapWord* result = sp->block_start_const(addr); + + cached_obj.start_addr = result; + cached_obj.end_addr = result + cast_to_oop(result)->size(); + + return result; + }; - DirtyCardToOopClosure dcto_cl{sp, cl}; - ClearNoncleanCardWrapper clear_cl(&dcto_cl, ct); + CardValue* const start_card = ct->byte_for(mr.start()); + CardValue* const end_card = ct->byte_for(mr.last()) + 1; - clear_cl.do_MemRegion(mr); + // if mr.end() is not card-aligned, that final card should not be cleared + // because it can be annotated dirty due to old-to-young pointers in + // newly-promoted objs on that card. + CardValue* const clear_limit_card = is_card_aligned(mr.end()) ? end_card - 1 + : end_card - 2; + + for (CardValue* current_card = start_card; current_card < end_card; /* empty */) { + CardValue* const dirty_l = find_first_dirty_card(current_card, end_card); + + if (dirty_l == end_card) { + // No dirty cards to iterate. + return; + } + + HeapWord* const addr_l = ct->addr_for(dirty_l); + HeapWord* obj_addr = object_start(addr_l); + + CardValue* const dirty_r = find_first_clean_card(dirty_l + 1, + end_card, + ct, + object_start); + assert(dirty_l < dirty_r, "inv"); + HeapWord* const addr_r = dirty_r == end_card ? mr.end() + : ct->addr_for(dirty_r); + + clear_cards(MIN2(dirty_l, clear_limit_card), + MIN2(dirty_r, clear_limit_card)); + + while (true) { + assert(obj_addr < addr_r, "inv"); + + oop obj = cast_to_oop(obj_addr); + const bool is_obj_array = obj->is_objArray(); + HeapWord* const obj_end_addr = obj_addr + obj->size(); + + if (is_obj_array) { + // ObjArrays are always precise-marked. + scan_obj_with_limit(obj, cl, addr_l, addr_r); + } else { + scan_obj_with_limit(obj, cl, addr_l, obj_end_addr); + } + + if (obj_end_addr >= addr_r) { + current_card = dirty_r + 1; + break; + } + + // Move to next obj inside this dirty chunk. + obj_addr = obj_end_addr; + } + } } bool CardTableRS::is_in_young(const void* p) const { diff --git a/src/hotspot/share/gc/serial/cardTableRS.hpp b/src/hotspot/share/gc/serial/cardTableRS.hpp index 822914fcf79f6..a4f333803a0ce 100644 --- a/src/hotspot/share/gc/serial/cardTableRS.hpp +++ b/src/hotspot/share/gc/serial/cardTableRS.hpp @@ -29,7 +29,6 @@ #include "memory/memRegion.hpp" #include "oops/oop.hpp" -class DirtyCardToOopClosure; class Generation; class Space; class TenuredSpace; @@ -41,10 +40,28 @@ class CardTableRS : public CardTable { friend class VMStructs; // Below are private classes used in impl. friend class VerifyCTSpaceClosure; - friend class ClearNoncleanCardWrapper; void verify_space(Space* s, HeapWord* gen_start); + static bool is_dirty(const CardValue* const v) { + return !is_clean(v); + } + + static bool is_clean(const CardValue* const v) { + return *v == clean_card_val(); + } + + static void clear_cards(CardValue* start, CardValue* end); + + static CardValue* find_first_dirty_card(CardValue* start_card, + CardValue* end_card); + + template + CardValue* find_first_clean_card(CardValue* start_card, + CardValue* end_card, + CardTableRS* ct, + Func& object_start); + public: CardTableRS(MemRegion whole_heap); @@ -57,10 +74,6 @@ class CardTableRS : public CardTable { *byte = dirty_card_val(); } - bool is_aligned(HeapWord* addr) { - return is_card_aligned(addr); - } - void verify(); // Update old gen cards to maintain old-to-young-pointer invariant: Clear diff --git a/src/hotspot/share/gc/serial/genMarkSweep.cpp b/src/hotspot/share/gc/serial/genMarkSweep.cpp index 6eb3da6892d30..0defffdb824ad 100644 --- a/src/hotspot/share/gc/serial/genMarkSweep.cpp +++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp @@ -38,6 +38,7 @@ #include "gc/serial/genMarkSweep.hpp" #include "gc/serial/serialGcRefProcProxyTask.hpp" #include "gc/serial/serialHeap.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/gcTimer.hpp" @@ -200,6 +201,8 @@ void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { { GCTraceTime(Debug, gc, phases) tm_m("Class Unloading", gc_timer()); + ClassUnloadingContext* ctx = ClassUnloadingContext::context(); + bool unloading_occurred; { CodeCache::UnlinkingScope scope(&is_alive); @@ -211,8 +214,15 @@ void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { CodeCache::do_unloading(unloading_occurred); } - // Release unloaded nmethod's memory. - CodeCache::flush_unlinked_nmethods(); + { + GCTraceTime(Debug, gc, phases) t("Purge Unlinked NMethods", gc_timer()); + // Release unloaded nmethod's memory. + ctx->purge_nmethods(); + } + { + GCTraceTime(Debug, gc, phases) t("Free Code Blobs", gc_timer()); + ctx->free_code_blobs(); + } // Prune dead klasses from subklass/sibling/implementor lists. Klass::clean_weak_klass_links(unloading_occurred); diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.cpp b/src/hotspot/share/gc/serial/tenuredGeneration.cpp index 7ab95e1229d5e..ad5fda3aeabb8 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.cpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.cpp @@ -303,12 +303,8 @@ TenuredGeneration::TenuredGeneration(ReservedSpace rs, // If this wasn't true, a single card could span more than on generation, // which would cause problems when we commit/uncommit memory, and when we // clear and dirty cards. - guarantee(_rs->is_aligned(reserved_mr.start()), "generation must be card aligned"); - if (reserved_mr.end() != SerialHeap::heap()->reserved_region().end()) { - // Don't check at the very end of the heap as we'll assert that we're probing off - // the end if we try. - guarantee(_rs->is_aligned(reserved_mr.end()), "generation must be card aligned"); - } + guarantee(CardTable::is_card_aligned(reserved_mr.start()), "generation must be card aligned"); + guarantee(CardTable::is_card_aligned(reserved_mr.end()), "generation must be card aligned"); _min_heap_delta_bytes = MinHeapDeltaBytes; _capacity_at_prologue = initial_byte_size; _used_at_prologue = 0; diff --git a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp index ca5458cd49cd8..09e452c2d4997 100644 --- a/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp +++ b/src/hotspot/share/gc/shared/adaptiveSizePolicy.hpp @@ -344,17 +344,11 @@ class AdaptiveSizePolicy : public CHeapObj { AdaptiveWeightedAverage* avg_eden_live() const { return _avg_eden_live; } AdaptiveWeightedAverage* avg_old_live() const { return _avg_old_live; } - AdaptivePaddedAverage* avg_survived() const { return _avg_survived; } - AdaptivePaddedNoZeroDevAverage* avg_pretenured() { return _avg_pretenured; } - // Methods indicating events of interest to the adaptive size policy, // called by GC algorithms. It is the responsibility of users of this // policy to call these methods at the correct times! virtual void minor_collection_begin(); virtual void minor_collection_end(GCCause::Cause gc_cause); - virtual LinearLeastSquareFit* minor_pause_old_estimator() const { - return _minor_pause_old_estimator; - } LinearLeastSquareFit* minor_pause_young_estimator() { return _minor_pause_young_estimator; @@ -404,10 +398,6 @@ class AdaptiveSizePolicy : public CHeapObj { _overhead_checker.set_gc_overhead_limit_exceeded(v); } - bool gc_overhead_limit_near() { - return _overhead_checker.gc_overhead_limit_near(); - } - void reset_gc_overhead_limit_count() { _overhead_checker.reset_gc_overhead_limit_count(); } diff --git a/src/hotspot/share/gc/shared/cardTable.cpp b/src/hotspot/share/gc/shared/cardTable.cpp index a5025a4e5a211..fdf6dcf3ece34 100644 --- a/src/hotspot/share/gc/shared/cardTable.cpp +++ b/src/hotspot/share/gc/shared/cardTable.cpp @@ -54,11 +54,6 @@ void CardTable::initialize_card_size() { // Set blockOffsetTable size based on card table entry size BOTConstants::initialize_bot_size(_card_shift); -#if INCLUDE_PARALLELGC - // Set ObjectStartArray block size based on card table entry size - ObjectStartArray::initialize_block_size(_card_shift); -#endif - log_info_p(gc, init)("CardTable entry size: " UINT32_FORMAT, _card_size); } diff --git a/src/hotspot/share/gc/shared/cardTable.hpp b/src/hotspot/share/gc/shared/cardTable.hpp index f66c5b7c5087d..61858075ca58c 100644 --- a/src/hotspot/share/gc/shared/cardTable.hpp +++ b/src/hotspot/share/gc/shared/cardTable.hpp @@ -83,6 +83,14 @@ class CardTable: public CHeapObj { return cards_required(_whole_heap.word_size()) - 1; } + // Mapping from card marking array entry to address of first word without checks. + HeapWord* addr_for_raw(const CardValue* p) const { + // As _byte_map_base may be "negative" (the card table has been allocated before + // the heap in memory), do not use pointer_delta() to avoid the assertion failure. + size_t delta = p - _byte_map_base; + return (HeapWord*) (delta << _card_shift); + } + private: void initialize_covered_region(void* region0_start, void* region1_start); @@ -111,9 +119,8 @@ class CardTable: public CHeapObj { void clear_MemRegion(MemRegion mr); // Return true if "p" is at the start of a card. - bool is_card_aligned(HeapWord* p) { - CardValue* pcard = byte_for(p); - return (addr_for(pcard) == p); + static bool is_card_aligned(HeapWord* p) { + return is_aligned(p, card_size()); } // Mapping from address to card marking array entry @@ -145,16 +152,13 @@ class CardTable: public CHeapObj { return byte_after(p); } - // Mapping from card marking array entry to address of first word + // Mapping from card marking array entry to address of first word. HeapWord* addr_for(const CardValue* p) const { assert(p >= _byte_map && p < _byte_map + _byte_map_size, "out of bounds access to card marking array. p: " PTR_FORMAT " _byte_map: " PTR_FORMAT " _byte_map + _byte_map_size: " PTR_FORMAT, p2i(p), p2i(_byte_map), p2i(_byte_map + _byte_map_size)); - // As _byte_map_base may be "negative" (the card table has been allocated before - // the heap in memory), do not use pointer_delta() to avoid the assertion failure. - size_t delta = p - _byte_map_base; - HeapWord* result = (HeapWord*) (delta << _card_shift); + HeapWord* result = addr_for_raw(p); assert(_whole_heap.contains(result), "Returning result = " PTR_FORMAT " out of bounds of " " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")", @@ -196,7 +200,7 @@ class CardTable: public CHeapObj { static constexpr CardValue clean_card_val() { return clean_card; } static constexpr CardValue dirty_card_val() { return dirty_card; } - static intptr_t clean_card_row_val() { return clean_card_row; } + static constexpr intptr_t clean_card_row_val() { return clean_card_row; } // Initialize card size static void initialize_card_size(); diff --git a/src/hotspot/share/gc/shared/classUnloadingContext.cpp b/src/hotspot/share/gc/shared/classUnloadingContext.cpp new file mode 100644 index 0000000000000..f624eaa6e448e --- /dev/null +++ b/src/hotspot/share/gc/shared/classUnloadingContext.cpp @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" + +#include "classfile/classLoaderData.inline.hpp" +#include "code/nmethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" +#include "runtime/mutexLocker.hpp" +#include "utilities/growableArray.hpp" + +ClassUnloadingContext* ClassUnloadingContext::_context = nullptr; + +ClassUnloadingContext::ClassUnloadingContext(uint num_workers, bool lock_codeblob_free_separately) : + _cld_head(nullptr), + _num_nmethod_unlink_workers(num_workers), + _unlinked_nmethods(nullptr), + _lock_codeblob_free_separately(lock_codeblob_free_separately) { + + assert(_context == nullptr, "context already set"); + _context = this; + + assert(num_workers > 0, "must be"); + + _unlinked_nmethods = NEW_C_HEAP_ARRAY(NMethodSet*, num_workers, mtGC); + for (uint i = 0; i < num_workers; ++i) { + _unlinked_nmethods[i] = new NMethodSet(); + } +} + +ClassUnloadingContext::~ClassUnloadingContext() { + for (uint i = 0; i < _num_nmethod_unlink_workers; ++i) { + delete _unlinked_nmethods[i]; + } + FREE_C_HEAP_ARRAY(NMethodSet*, _unlinked_nmethods); + + assert(_context == this, "context not set correctly"); + _context = nullptr; +} + +bool ClassUnloadingContext::has_unloaded_classes() const { + return _cld_head != nullptr; +} + +void ClassUnloadingContext::register_unloading_class_loader_data(ClassLoaderData* cld) { + assert_locked_or_safepoint(ClassLoaderDataGraph_lock); + + cld->unload(); + + cld->set_unloading_next(_cld_head); + _cld_head = cld; +} + +void ClassUnloadingContext::purge_class_loader_data() { + for (ClassLoaderData* cld = _cld_head; cld != nullptr;) { + assert(cld->is_unloading(), "invariant"); + + ClassLoaderData* next = cld->unloading_next(); + delete cld; + cld = next; + } +} + +void ClassUnloadingContext::classes_unloading_do(void f(Klass* const)) { + assert_locked_or_safepoint(ClassLoaderDataGraph_lock); + for (ClassLoaderData* cld = _cld_head; cld != nullptr; cld = cld->unloading_next()) { + assert(cld->is_unloading(), "invariant"); + cld->classes_do(f); + } +} + +void ClassUnloadingContext::register_unlinked_nmethod(nmethod* nm) { + assert(_context != nullptr, "no context set"); + + assert(!nm->is_unlinked(), "Only register for unloading once"); + assert(_num_nmethod_unlink_workers == 1 || Thread::current()->is_Worker_thread(), "must be worker thread if parallel"); + + uint worker_id = _num_nmethod_unlink_workers == 1 ? 0 : WorkerThread::worker_id(); + assert(worker_id < _num_nmethod_unlink_workers, "larger than expected worker id %u", worker_id); + + _unlinked_nmethods[worker_id]->append(nm); + + nm->set_is_unlinked(); +} + +void ClassUnloadingContext::purge_nmethods() { + assert(_context != nullptr, "no context set"); + + size_t freed_memory = 0; + + for (uint i = 0; i < _num_nmethod_unlink_workers; ++i) { + NMethodSet* set = _unlinked_nmethods[i]; + for (nmethod* nm : *set) { + freed_memory += nm->size(); + nm->purge(false /* free_code_cache_data */); + } + } + + CodeCache::maybe_restart_compiler(freed_memory); +} + +void ClassUnloadingContext::free_code_blobs() { + assert(_context != nullptr, "no context set"); + + // Sort nmethods before freeing to benefit from optimizations. If Nmethods were + // collected in parallel, use a new temporary buffer for the result, otherwise + // sort in-place. + NMethodSet* nmethod_set = nullptr; + + bool is_parallel = _num_nmethod_unlink_workers > 1; + + // Merge all collected nmethods into a huge array. + if (is_parallel) { + int num_nmethods = 0; + + for (uint i = 0; i < _num_nmethod_unlink_workers; ++i) { + num_nmethods += _unlinked_nmethods[i]->length(); + } + nmethod_set = new NMethodSet(num_nmethods); + for (uint i = 0; i < _num_nmethod_unlink_workers; ++i) { + nmethod_set->appendAll(_unlinked_nmethods[i]); + } + } else { + nmethod_set = _unlinked_nmethods[0]; + } + + // Sort by ascending address. + auto sort_nmethods = [] (nmethod** a, nmethod** b) -> int { + uintptr_t u_a = (uintptr_t)*a; + uintptr_t u_b = (uintptr_t)*b; + if (u_a == u_b) return 0; + if (u_a < u_b) return -1; + return 1; + }; + nmethod_set->sort(sort_nmethods); + + // And free. Duplicate loop for clarity depending on where we want the locking. + if (_lock_codeblob_free_separately) { + for (nmethod* nm : *nmethod_set) { + MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag); + CodeCache::free(nm); + } + } else { + MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag); + for (nmethod* nm : *nmethod_set) { + CodeCache::free(nm); + } + } + + if (is_parallel) { + delete nmethod_set; + } +} diff --git a/src/hotspot/share/gc/shared/classUnloadingContext.hpp b/src/hotspot/share/gc/shared/classUnloadingContext.hpp new file mode 100644 index 0000000000000..42a8f764fa46e --- /dev/null +++ b/src/hotspot/share/gc/shared/classUnloadingContext.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHARED_CLASSUNLOADINGCONTEXT_HPP +#define SHARE_GC_SHARED_CLASSUNLOADINGCONTEXT_HPP + +#include "memory/allocation.hpp" +#include "utilities/growableArray.hpp" + +class ClassLoaderData; +class Klass; +class nmethod; + +class ClassUnloadingContext : public CHeapObj { + static ClassUnloadingContext* _context; + + ClassLoaderData* volatile _cld_head; + + const uint _num_nmethod_unlink_workers; + + using NMethodSet = GrowableArrayCHeap; + NMethodSet** _unlinked_nmethods; + + bool _lock_codeblob_free_separately; + +public: + static ClassUnloadingContext* context() { assert(_context != nullptr, "context not set"); return _context; } + + // Num_nmethod_unlink_workers configures the maximum numbers of threads unlinking + // nmethods. + // lock_codeblob_free_separately determines whether freeing the code blobs takes + // the CodeCache_lock during the whole operation (=false) or per code blob + // free operation (=true). + ClassUnloadingContext(uint num_nmethod_unlink_workers, + bool lock_codeblob_free_separately); + ~ClassUnloadingContext(); + + bool has_unloaded_classes() const; + + void register_unloading_class_loader_data(ClassLoaderData* cld); + void purge_class_loader_data(); + + void classes_unloading_do(void f(Klass* const)); + + // Register unloading nmethods, potentially in parallel. + void register_unlinked_nmethod(nmethod* nm); + void purge_nmethods(); + void free_code_blobs(); + + void purge_and_free_nmethods() { + purge_nmethods(); + free_code_blobs(); + } +}; + +#endif // SHARE_GC_SHARED_CLASSUNLOADINGCONTEXT_HPP diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp index 19923ca9bc413..cccc7b168832a 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.hpp +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp @@ -165,8 +165,10 @@ class CollectedHeap : public CHeapObj { // Filler object utilities. static inline size_t filler_array_hdr_size(); - static inline size_t filler_array_min_size(); + static size_t filler_array_min_size(); + +protected: static inline void zap_filler_array_with(HeapWord* start, size_t words, juint value); DEBUG_ONLY(static void fill_args_check(HeapWord* start, size_t words);) DEBUG_ONLY(static void zap_filler_array(HeapWord* start, size_t words, bool zap = true);) diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.cpp b/src/hotspot/share/gc/shared/genCollectedHeap.cpp index 54946d75bc9de..b81ce4b778218 100644 --- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp +++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp @@ -36,6 +36,7 @@ #include "gc/serial/markSweep.hpp" #include "gc/serial/tenuredGeneration.hpp" #include "gc/shared/cardTableBarrierSet.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/collectorCounters.hpp" #include "gc/shared/continuationGCSupport.inline.hpp" @@ -522,6 +523,9 @@ void GenCollectedHeap::do_collection(bool full, CodeCache::on_gc_marking_cycle_start(); + ClassUnloadingContext ctx(1 /* num_nmethod_unlink_workers */, + false /* lock_codeblob_free_separately */); + collect_generation(_old_gen, full, size, @@ -537,7 +541,7 @@ void GenCollectedHeap::do_collection(bool full, _young_gen->compute_new_size(); // Delete metaspaces for unloaded class loaders and clean up loader_data graph - ClassLoaderDataGraph::purge(/*at_safepoint*/true); + ClassLoaderDataGraph::purge(true /* at_safepoint */); DEBUG_ONLY(MetaspaceUtils::verify();) // Need to clear claim bits for the next mark. diff --git a/src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.cpp b/src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.cpp index 163800e9abf97..23311a2868d02 100644 --- a/src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.cpp +++ b/src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.cpp @@ -38,6 +38,7 @@ #include "memory/iterator.hpp" #include "oops/access.inline.hpp" #include "runtime/atomic.hpp" +#include "runtime/cpuTimeCounters.hpp" #include "runtime/interfaceSupport.inline.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/debug.hpp" @@ -64,6 +65,7 @@ StringDedup::Processor::Processor() : _thread(nullptr) {} void StringDedup::Processor::initialize() { _processor = new Processor(); + CPUTimeCounters::create_counter(CPUTimeGroups::CPUTimeType::conc_dedup); } void StringDedup::Processor::wait_for_requests() const { @@ -187,6 +189,10 @@ void StringDedup::Processor::run(JavaThread* thread) { cleanup_table(false /* grow_only */, StringDeduplicationResizeALot /* force */); _cur_stat.report_active_end(); log_statistics(); + if (UsePerfData && os::is_thread_cpu_time_supported()) { + ThreadTotalCPUTimeClosure tttc(CPUTimeGroups::CPUTimeType::conc_dedup); + tttc.do_thread(thread); + } } } diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp index 4e041eaffe20c..d0de328a7b82d 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp @@ -50,21 +50,18 @@ bool ShenandoahBarrierC2Support::expand(Compile* C, PhaseIterGVN& igvn) { state->load_reference_barriers_count()) > 0) { assert(C->post_loop_opts_phase(), "no loop opts allowed"); C->reset_post_loop_opts_phase(); // ... but we know what we are doing - bool attempt_more_loopopts = ShenandoahLoopOptsAfterExpansion; C->clear_major_progress(); PhaseIdealLoop::optimize(igvn, LoopOptsShenandoahExpand); if (C->failing()) return false; - PhaseIdealLoop::verify(igvn); - if (attempt_more_loopopts) { - C->set_major_progress(); - if (!C->optimize_loops(igvn, LoopOptsShenandoahPostExpand)) { - return false; - } - C->clear_major_progress(); - C->process_for_post_loop_opts_igvn(igvn); - if (C->failing()) return false; + C->set_major_progress(); + if (!C->optimize_loops(igvn, LoopOptsShenandoahPostExpand)) { + return false; } + C->clear_major_progress(); + C->process_for_post_loop_opts_igvn(igvn); + if (C->failing()) return false; + C->set_post_loop_opts_phase(); // now for real! } return true; @@ -1392,11 +1389,9 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) { Node* result_mem = nullptr; Node* addr; - if (ShenandoahSelfFixing) { + { VectorSet visited; addr = get_load_addr(phase, visited, lrb); - } else { - addr = phase->igvn().zerocon(T_OBJECT); } if (addr->Opcode() == Op_AddP) { Node* orig_base = addr->in(AddPNode::Base); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp index 396b6ee89666a..fa6b3e67fee82 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp @@ -38,12 +38,6 @@ ShenandoahAggressiveHeuristics::ShenandoahAggressiveHeuristics(ShenandoahSpaceIn // Aggressive evacuates everything, so it needs as much evac space as it can get SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahEvacReserveOverflow); - - // If class unloading is globally enabled, aggressive does unloading even with - // concurrent cycles. - if (ClassUnloading) { - SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahUnloadClassesFrequency, 1); - } } void ShenandoahAggressiveHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset, @@ -63,7 +57,7 @@ bool ShenandoahAggressiveHeuristics::should_start_gc() { } bool ShenandoahAggressiveHeuristics::should_unload_classes() { - if (!can_unload_classes_normal()) return false; + if (!can_unload_classes()) return false; if (has_metaspace_oom()) return true; // Randomly unload classes with 50% chance. return (os::random() & 1) == 1; diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp index 2a18ae95a7bfc..c2620a228115f 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp @@ -54,11 +54,6 @@ ShenandoahHeuristics::ShenandoahHeuristics(ShenandoahSpaceInfo* space_info) : _gc_time_history(new TruncatedSeq(10, ShenandoahAdaptiveDecayFactor)), _metaspace_oom() { - // No unloading during concurrent mark? Communicate that to heuristics - if (!ClassUnloadingWithConcurrentMark) { - FLAG_SET_DEFAULT(ShenandoahUnloadClassesFrequency, 0); - } - size_t num_regions = ShenandoahHeap::heap()->num_regions(); assert(num_regions > 0, "Sanity"); @@ -263,23 +258,10 @@ bool ShenandoahHeuristics::can_unload_classes() { return true; } -bool ShenandoahHeuristics::can_unload_classes_normal() { - if (!can_unload_classes()) return false; - if (has_metaspace_oom()) return true; - if (!ClassUnloadingWithConcurrentMark) return false; - if (ShenandoahUnloadClassesFrequency == 0) return false; - return true; -} - bool ShenandoahHeuristics::should_unload_classes() { - if (!can_unload_classes_normal()) return false; + if (!can_unload_classes()) return false; if (has_metaspace_oom()) return true; - size_t cycle = ShenandoahHeap::heap()->shenandoah_policy()->cycle_counter(); - // Unload classes every Nth GC cycle. - // This should not happen in the same cycle as process_references to amortize costs. - // Offsetting by one is enough to break the rendezvous when periods are equal. - // When periods are not equal, offsetting by one is just as good as any other guess. - return (cycle + 1) % ShenandoahUnloadClassesFrequency == 0; + return ClassUnloadingWithConcurrentMark; } void ShenandoahHeuristics::initialize() { diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp index 4deb134a4b5fa..bc6d2dc40c54c 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp @@ -130,7 +130,6 @@ class ShenandoahHeuristics : public CHeapObj { virtual void choose_collection_set(ShenandoahCollectionSet* collection_set); virtual bool can_unload_classes(); - virtual bool can_unload_classes_normal(); virtual bool should_unload_classes(); virtual const char* name() = 0; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp index 7d31ff02e1add..d9b28c1bb4d3c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp @@ -113,6 +113,16 @@ void ShenandoahArguments::initialize() { } } + // Disable support for dynamic number of GC threads. We do not let the runtime + // heuristics to misjudge how many threads we need during the heavy concurrent phase + // or a GC pause. + if (UseDynamicNumberOfGCThreads) { + if (FLAG_IS_CMDLINE(UseDynamicNumberOfGCThreads)) { + warning("Shenandoah does not support UseDynamicNumberOfGCThreads, disabling"); + } + FLAG_SET_DEFAULT(UseDynamicNumberOfGCThreads, false); + } + if (ShenandoahRegionSampling && FLAG_IS_DEFAULT(PerfDataMemorySize)) { // When sampling is enabled, max out the PerfData memory to get more // Shenandoah data in, including Matrix. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp index 413dfe10faad9..b8da50dd6e109 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp @@ -123,7 +123,7 @@ inline oop ShenandoahBarrierSet::load_reference_barrier(DecoratorSet decorators, } oop fwd = load_reference_barrier(obj); - if (ShenandoahSelfFixing && load_addr != nullptr && fwd != obj) { + if (load_addr != nullptr && fwd != obj) { // Since we are here and we know the load address, update the reference. ShenandoahHeap::atomic_update_oop(fwd, load_addr, obj); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp index 92d447258f2a8..c5b6d787b95a8 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp @@ -26,6 +26,7 @@ #include "code/codeCache.hpp" #include "code/icBuffer.hpp" #include "code/nmethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shenandoah/shenandoahClosures.inline.hpp" #include "gc/shenandoah/shenandoahEvacOOMHandler.inline.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" @@ -235,7 +236,7 @@ void ShenandoahCodeRoots::unlink(WorkerThreads* workers, bool unloading_occurred void ShenandoahCodeRoots::purge() { assert(ShenandoahHeap::heap()->unload_classes(), "Only when running concurrent class unloading"); - CodeCache::flush_unlinked_nmethods(); + ClassUnloadingContext::context()->purge_and_free_nmethods(); } ShenandoahCodeRootsIterator::ShenandoahCodeRootsIterator() : diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp index e04c55d362d00..f3c72dfc0b10a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp @@ -57,7 +57,7 @@ class ShenandoahConcurrentMarkingTask : public WorkerTask { void work(uint worker_id) { ShenandoahHeap* heap = ShenandoahHeap::heap(); ShenandoahConcurrentWorkerSession worker_session(worker_id); - ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers); + ShenandoahSuspendibleThreadSetJoiner stsj; ShenandoahReferenceProcessor* rp = heap->ref_processor(); assert(rp != nullptr, "need reference processor"); StringDedup::Requests requests; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp index c0d6b007a270b..72a3f411ea09c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp @@ -154,7 +154,7 @@ HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, Shenandoah HeapWord* result = nullptr; size_t size = req.size(); - if (ShenandoahElasticTLAB && req.is_lab_alloc()) { + if (req.is_lab_alloc()) { size_t free = align_down(r->free() >> LogHeapWordSize, MinObjAlignment); if (size > free) { size = free; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 3426aba9d94ad..67d7f0eb4fafa 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -27,6 +27,7 @@ #include "memory/allocation.hpp" #include "memory/universe.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/gcArguments.hpp" #include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTraceTime.inline.hpp" @@ -1022,7 +1023,7 @@ class ShenandoahEvacuationTask : public WorkerTask { void work(uint worker_id) { if (_concurrent) { ShenandoahConcurrentWorkerSession worker_session(worker_id); - ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers); + ShenandoahSuspendibleThreadSetJoiner stsj; ShenandoahEvacOOMScope oom_evac_scope; do_work(); } else { @@ -1186,13 +1187,9 @@ void ShenandoahHeap::gclabs_retire(bool resize) { // Returns size in bytes size_t ShenandoahHeap::unsafe_max_tlab_alloc(Thread *thread) const { - if (ShenandoahElasticTLAB) { - // With Elastic TLABs, return the max allowed size, and let the allocation path - // figure out the safe size for current allocation. - return ShenandoahHeapRegion::max_tlab_size_bytes(); - } else { - return MIN2(_free_set->unsafe_peek_free(), ShenandoahHeapRegion::max_tlab_size_bytes()); - } + // Return the max allowed size, and let the allocation path + // figure out the safe size for current allocation. + return ShenandoahHeapRegion::max_tlab_size_bytes(); } size_t ShenandoahHeap::max_tlab_size() const { @@ -1824,6 +1821,9 @@ void ShenandoahHeap::stop() { void ShenandoahHeap::stw_unload_classes(bool full_gc) { if (!unload_classes()) return; + ClassUnloadingContext ctx(_workers->active_workers(), + false /* lock_codeblob_free_separately */); + // Unload classes and purge SystemDictionary. { ShenandoahPhaseTimings::Phase phase = full_gc ? @@ -1841,14 +1841,14 @@ void ShenandoahHeap::stw_unload_classes(bool full_gc) { _workers->run_task(&unlink_task); } // Release unloaded nmethods's memory. - CodeCache::flush_unlinked_nmethods(); + ClassUnloadingContext::context()->purge_and_free_nmethods(); } { ShenandoahGCPhase phase(full_gc ? ShenandoahPhaseTimings::full_gc_purge_cldg : ShenandoahPhaseTimings::degen_gc_purge_cldg); - ClassLoaderDataGraph::purge(/*at_safepoint*/true); + ClassLoaderDataGraph::purge(true /* at_safepoint */); } // Resize and verify metaspace MetaspaceGC::compute_new_size(); @@ -2018,19 +2018,13 @@ void ShenandoahHeap::assert_gc_workers(uint nworkers) { assert(nworkers > 0 && nworkers <= max_workers(), "Sanity"); if (ShenandoahSafepoint::is_at_shenandoah_safepoint()) { - if (UseDynamicNumberOfGCThreads) { - assert(nworkers <= ParallelGCThreads, "Cannot use more than it has"); - } else { - // Use ParallelGCThreads inside safepoints - assert(nworkers == ParallelGCThreads, "Use ParallelGCThreads within safepoints"); - } + // Use ParallelGCThreads inside safepoints + assert(nworkers == ParallelGCThreads, "Use ParallelGCThreads (%u) within safepoint, not %u", + ParallelGCThreads, nworkers); } else { - if (UseDynamicNumberOfGCThreads) { - assert(nworkers <= ConcGCThreads, "Cannot use more than it has"); - } else { - // Use ConcGCThreads outside safepoints - assert(nworkers == ConcGCThreads, "Use ConcGCThreads outside safepoints"); - } + // Use ConcGCThreads outside safepoints + assert(nworkers == ConcGCThreads, "Use ConcGCThreads (%u) outside safepoints, %u", + ConcGCThreads, nworkers); } } #endif @@ -2056,7 +2050,7 @@ class ShenandoahUpdateHeapRefsTask : public WorkerTask { void work(uint worker_id) { if (CONCURRENT) { ShenandoahConcurrentWorkerSession worker_session(worker_id); - ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers); + ShenandoahSuspendibleThreadSetJoiner stsj; do_work(); } else { ShenandoahParallelWorkerSession worker_session(worker_id); @@ -2238,15 +2232,11 @@ bool ShenandoahHeap::uncommit_bitmap_slice(ShenandoahHeapRegion *r) { } void ShenandoahHeap::safepoint_synchronize_begin() { - if (ShenandoahSuspendibleWorkers) { - SuspendibleThreadSet::synchronize(); - } + SuspendibleThreadSet::synchronize(); } void ShenandoahHeap::safepoint_synchronize_end() { - if (ShenandoahSuspendibleWorkers) { - SuspendibleThreadSet::desynchronize(); - } + SuspendibleThreadSet::desynchronize(); } void ShenandoahHeap::entry_uncommit(double shrink_before, size_t shrink_until) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp index 0c21fdd486b02..87c3ea50ba66f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp @@ -256,7 +256,7 @@ inline bool ShenandoahHeap::cancelled_gc() const { } inline bool ShenandoahHeap::check_cancelled_gc_and_yield(bool sts_active) { - if (sts_active && ShenandoahSuspendibleWorkers && !cancelled_gc()) { + if (sts_active && !cancelled_gc()) { if (SuspendibleThreadSet::should_yield()) { SuspendibleThreadSet::yield(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp index 6cac61f848a00..a46c7edc3482a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp @@ -607,26 +607,8 @@ size_t ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) { HumongousThresholdBytes = HumongousThresholdWords * HeapWordSize; assert (HumongousThresholdBytes <= RegionSizeBytes, "sanity"); - // The rationale for trimming the TLAB sizes has to do with the raciness in - // TLAB allocation machinery. It may happen that TLAB sizing policy polls Shenandoah - // about next free size, gets the answer for region #N, goes away for a while, then - // tries to allocate in region #N, and fail because some other thread have claimed part - // of the region #N, and then the freeset allocation code has to retire the region #N, - // before moving the allocation to region #N+1. - // - // The worst case realizes when "answer" is "region size", which means it could - // prematurely retire an entire region. Having smaller TLABs does not fix that - // completely, but reduces the probability of too wasteful region retirement. - // With current divisor, we will waste no more than 1/8 of region size in the worst - // case. This also has a secondary effect on collection set selection: even under - // the race, the regions would be at least 7/8 used, which allows relying on - // "used" - "live" for cset selection. Otherwise, we can get the fragmented region - // below the garbage threshold that would never be considered for collection. - // - // The whole thing is mitigated if Elastic TLABs are enabled. - // guarantee(MaxTLABSizeWords == 0, "we should only set it once"); - MaxTLABSizeWords = MIN2(ShenandoahElasticTLAB ? RegionSizeWords : (RegionSizeWords / 8), HumongousThresholdWords); + MaxTLABSizeWords = MIN2(RegionSizeWords, HumongousThresholdWords); MaxTLABSizeWords = align_down(MaxTLABSizeWords, MinObjAlignment); guarantee(MaxTLABSizeBytes == 0, "we should only set it once"); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp index ffae4f068bc4b..4725b8c3dfae7 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp @@ -185,7 +185,7 @@ void ShenandoahMark::mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint w if (work == 0) { // No work encountered in current stride, try to terminate. // Need to leave the STS here otherwise it might block safepoints. - ShenandoahSuspendibleThreadSetLeaver stsl(CANCELLABLE && ShenandoahSuspendibleWorkers); + ShenandoahSuspendibleThreadSetLeaver stsl(CANCELLABLE); ShenandoahTerminatorTerminator tt(heap); if (terminator->offer_termination(&tt)) return; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp index afd10efdfdd9b..81eee97f25fb3 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp @@ -30,6 +30,7 @@ #include "code/codeCache.hpp" #include "code/dependencyContext.hpp" #include "gc/shared/gcBehaviours.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/shenandoah/shenandoahNMethod.inline.hpp" #include "gc/shenandoah/shenandoahLock.hpp" @@ -138,6 +139,9 @@ void ShenandoahUnload::unload() { assert(ClassUnloading, "Filtered by caller"); assert(heap->is_concurrent_weak_root_in_progress(), "Filtered by caller"); + ClassUnloadingContext ctx(heap->workers()->active_workers(), + true /* lock_codeblob_free_separately */); + // Unlink stale metadata and nmethods { ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_unlink); @@ -181,7 +185,7 @@ void ShenandoahUnload::unload() { { ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_purge_cldg); - ClassLoaderDataGraph::purge(/*at_safepoint*/false); + ClassLoaderDataGraph::purge(false /* at_safepoint */); } { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp index 5c06bdbf9b420..3d0945ff95191 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp @@ -25,131 +25,48 @@ #include "precompiled.hpp" #include "gc/shared/gc_globals.hpp" -#include "gc/shared/workerPolicy.hpp" #include "gc/shenandoah/shenandoahWorkerPolicy.hpp" -#include "runtime/javaThread.hpp" -#include "runtime/threads.hpp" - -uint ShenandoahWorkerPolicy::_prev_par_marking = 0; -uint ShenandoahWorkerPolicy::_prev_conc_marking = 0; -uint ShenandoahWorkerPolicy::_prev_conc_evac = 0; -uint ShenandoahWorkerPolicy::_prev_conc_root_proc = 0; -uint ShenandoahWorkerPolicy::_prev_conc_refs_proc = 0; -uint ShenandoahWorkerPolicy::_prev_fullgc = 0; -uint ShenandoahWorkerPolicy::_prev_degengc = 0; -uint ShenandoahWorkerPolicy::_prev_conc_update_ref = 0; -uint ShenandoahWorkerPolicy::_prev_par_update_ref = 0; -uint ShenandoahWorkerPolicy::_prev_conc_cleanup = 0; -uint ShenandoahWorkerPolicy::_prev_conc_reset = 0; uint ShenandoahWorkerPolicy::calc_workers_for_init_marking() { - uint active_workers = (_prev_par_marking == 0) ? ParallelGCThreads : _prev_par_marking; - - _prev_par_marking = - WorkerPolicy::calc_active_workers(ParallelGCThreads, - active_workers, - Threads::number_of_non_daemon_threads()); - return _prev_par_marking; + return ParallelGCThreads; } uint ShenandoahWorkerPolicy::calc_workers_for_conc_marking() { - uint active_workers = (_prev_conc_marking == 0) ? ConcGCThreads : _prev_conc_marking; - _prev_conc_marking = - WorkerPolicy::calc_active_conc_workers(ConcGCThreads, - active_workers, - Threads::number_of_non_daemon_threads()); - return _prev_conc_marking; + return ConcGCThreads; } -// Reuse the calculation result from init marking uint ShenandoahWorkerPolicy::calc_workers_for_final_marking() { - return _prev_par_marking; + return ParallelGCThreads; } -// Calculate workers for concurrent refs processing uint ShenandoahWorkerPolicy::calc_workers_for_conc_refs_processing() { - uint active_workers = (_prev_conc_refs_proc == 0) ? ConcGCThreads : _prev_conc_refs_proc; - _prev_conc_refs_proc = - WorkerPolicy::calc_active_conc_workers(ConcGCThreads, - active_workers, - Threads::number_of_non_daemon_threads()); - return _prev_conc_refs_proc; + return ConcGCThreads; } -// Calculate workers for concurrent root processing uint ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing() { - uint active_workers = (_prev_conc_root_proc == 0) ? ConcGCThreads : _prev_conc_root_proc; - _prev_conc_root_proc = - WorkerPolicy::calc_active_conc_workers(ConcGCThreads, - active_workers, - Threads::number_of_non_daemon_threads()); - return _prev_conc_root_proc; + return ConcGCThreads; } -// Calculate workers for concurrent evacuation (concurrent GC) uint ShenandoahWorkerPolicy::calc_workers_for_conc_evac() { - uint active_workers = (_prev_conc_evac == 0) ? ConcGCThreads : _prev_conc_evac; - _prev_conc_evac = - WorkerPolicy::calc_active_conc_workers(ConcGCThreads, - active_workers, - Threads::number_of_non_daemon_threads()); - return _prev_conc_evac; + return ConcGCThreads; } -// Calculate workers for parallel fullgc uint ShenandoahWorkerPolicy::calc_workers_for_fullgc() { - uint active_workers = (_prev_fullgc == 0) ? ParallelGCThreads : _prev_fullgc; - _prev_fullgc = - WorkerPolicy::calc_active_workers(ParallelGCThreads, - active_workers, - Threads::number_of_non_daemon_threads()); - return _prev_fullgc; + return ParallelGCThreads; } -// Calculate workers for parallel degenerated gc uint ShenandoahWorkerPolicy::calc_workers_for_stw_degenerated() { - uint active_workers = (_prev_degengc == 0) ? ParallelGCThreads : _prev_degengc; - _prev_degengc = - WorkerPolicy::calc_active_workers(ParallelGCThreads, - active_workers, - Threads::number_of_non_daemon_threads()); - return _prev_degengc; + return ParallelGCThreads; } -// Calculate workers for concurrent reference update uint ShenandoahWorkerPolicy::calc_workers_for_conc_update_ref() { - uint active_workers = (_prev_conc_update_ref == 0) ? ConcGCThreads : _prev_conc_update_ref; - _prev_conc_update_ref = - WorkerPolicy::calc_active_conc_workers(ConcGCThreads, - active_workers, - Threads::number_of_non_daemon_threads()); - return _prev_conc_update_ref; + return ConcGCThreads; } -// Calculate workers for parallel reference update uint ShenandoahWorkerPolicy::calc_workers_for_final_update_ref() { - uint active_workers = (_prev_par_update_ref == 0) ? ParallelGCThreads : _prev_par_update_ref; - _prev_par_update_ref = - WorkerPolicy::calc_active_workers(ParallelGCThreads, - active_workers, - Threads::number_of_non_daemon_threads()); - return _prev_par_update_ref; -} - -uint ShenandoahWorkerPolicy::calc_workers_for_conc_cleanup() { - uint active_workers = (_prev_conc_cleanup == 0) ? ConcGCThreads : _prev_conc_cleanup; - _prev_conc_cleanup = - WorkerPolicy::calc_active_conc_workers(ConcGCThreads, - active_workers, - Threads::number_of_non_daemon_threads()); - return _prev_conc_cleanup; + return ParallelGCThreads; } uint ShenandoahWorkerPolicy::calc_workers_for_conc_reset() { - uint active_workers = (_prev_conc_reset == 0) ? ConcGCThreads : _prev_conc_reset; - _prev_conc_reset = - WorkerPolicy::calc_active_conc_workers(ConcGCThreads, - active_workers, - Threads::number_of_non_daemon_threads()); - return _prev_conc_reset; + return ConcGCThreads; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp index 3f47822f2200b..c1e07d41d53f9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp @@ -28,19 +28,6 @@ #include "memory/allStatic.hpp" class ShenandoahWorkerPolicy : AllStatic { -private: - static uint _prev_par_marking; - static uint _prev_conc_marking; - static uint _prev_conc_root_proc; - static uint _prev_conc_refs_proc; - static uint _prev_conc_evac; - static uint _prev_fullgc; - static uint _prev_degengc; - static uint _prev_conc_update_ref; - static uint _prev_par_update_ref; - static uint _prev_conc_cleanup; - static uint _prev_conc_reset; - public: // Calculate the number of workers for initial marking static uint calc_workers_for_init_marking(); @@ -72,9 +59,6 @@ class ShenandoahWorkerPolicy : AllStatic { // Calculate workers for parallel/final reference update static uint calc_workers_for_final_update_ref(); - // Calculate workers for concurrent cleanup - static uint calc_workers_for_conc_cleanup(); - // Calculate workers for concurrent reset static uint calc_workers_for_conc_reset(); }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp index 1ac9047706dc3..1d22eae207951 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp @@ -76,11 +76,6 @@ " compact - run GC more frequently and with deeper targets to " \ "free up more memory.") \ \ - product(uintx, ShenandoahUnloadClassesFrequency, 1, EXPERIMENTAL, \ - "Unload the classes every Nth cycle. Normally affects concurrent "\ - "GC cycles, as degenerated and full GCs would try to unload " \ - "classes regardless. Set to zero to disable class unloading.") \ - \ product(uintx, ShenandoahGarbageThreshold, 25, EXPERIMENTAL, \ "How much garbage a region has to contain before it would be " \ "taken for collection. This a guideline only, as GC heuristics " \ @@ -220,9 +215,6 @@ " 3 = previous level, plus all reachable objects; " \ " 4 = previous level, plus all marked objects") \ \ - product(bool, ShenandoahElasticTLAB, true, DIAGNOSTIC, \ - "Use Elastic TLABs with Shenandoah") \ - \ product(uintx, ShenandoahEvacReserve, 5, EXPERIMENTAL, \ "How much of heap to reserve for evacuations. Larger values make "\ "GC evacuate more live objects on every cycle, while leaving " \ @@ -339,9 +331,6 @@ "How many times to maximum attempt to flush SATB buffers at the " \ "end of concurrent marking.") \ \ - product(bool, ShenandoahSuspendibleWorkers, true, EXPERIMENTAL, \ - "Suspend concurrent GC worker threads at safepoints") \ - \ product(bool, ShenandoahSATBBarrier, true, DIAGNOSTIC, \ "Turn on/off SATB barriers in Shenandoah") \ \ @@ -360,15 +349,9 @@ product(bool, ShenandoahStackWatermarkBarrier, true, DIAGNOSTIC, \ "Turn on/off stack watermark barriers in Shenandoah") \ \ - develop(bool, ShenandoahVerifyOptoBarriers, false, \ + develop(bool, ShenandoahVerifyOptoBarriers, trueInDebug, \ "Verify no missing barriers in C2.") \ \ - product(bool, ShenandoahLoopOptsAfterExpansion, true, DIAGNOSTIC, \ - "Attempt more loop opts after barrier expansion.") \ - \ - product(bool, ShenandoahSelfFixing, true, DIAGNOSTIC, \ - "Fix references with load reference barrier. Disabling this " \ - "might degrade performance.") // end of GC_SHENANDOAH_FLAGS diff --git a/src/hotspot/share/gc/x/xHeap.cpp b/src/hotspot/share/gc/x/xHeap.cpp index a242a8063be1c..65da4e1c98327 100644 --- a/src/hotspot/share/gc/x/xHeap.cpp +++ b/src/hotspot/share/gc/x/xHeap.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "gc/shared/gc_globals.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/locationPrinter.hpp" #include "gc/shared/tlab_globals.hpp" #include "gc/x/xAddress.inline.hpp" @@ -320,6 +321,9 @@ void XHeap::process_non_strong_references() { // Process weak roots _weak_roots_processor.process_weak_roots(); + ClassUnloadingContext ctx(_workers.active_workers(), + true /* lock_codeblob_free_separately */); + // Unlink stale metadata and nmethods _unload.unlink(); diff --git a/src/hotspot/share/gc/x/xNMethod.cpp b/src/hotspot/share/gc/x/xNMethod.cpp index d86828aa8477b..613e190850225 100644 --- a/src/hotspot/share/gc/x/xNMethod.cpp +++ b/src/hotspot/share/gc/x/xNMethod.cpp @@ -27,6 +27,7 @@ #include "code/icBuffer.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetNMethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/x/xBarrier.inline.hpp" #include "gc/x/xGlobals.hpp" @@ -362,5 +363,5 @@ void XNMethod::unlink(XWorkers* workers, bool unloading_occurred) { } void XNMethod::purge() { - CodeCache::flush_unlinked_nmethods(); + ClassUnloadingContext::context()->purge_and_free_nmethods(); } diff --git a/src/hotspot/share/gc/z/zGeneration.cpp b/src/hotspot/share/gc/z/zGeneration.cpp index 0ee5ce7a6c89e..4621101eb8832 100644 --- a/src/hotspot/share/gc/z/zGeneration.cpp +++ b/src/hotspot/share/gc/z/zGeneration.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "code/nmethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/gcLocker.hpp" #include "gc/shared/gcVMOperations.hpp" #include "gc/shared/isGCActiveMark.hpp" @@ -1316,6 +1317,9 @@ void ZGenerationOld::process_non_strong_references() { // Process weak roots _weak_roots_processor.process_weak_roots(); + ClassUnloadingContext ctx(_workers.active_workers(), + true /* lock_codeblob_free_separately */); + // Unlink stale metadata and nmethods _unload.unlink(); diff --git a/src/hotspot/share/gc/z/zLargePages.cpp b/src/hotspot/share/gc/z/zLargePages.cpp index 88656d1538115..a65bf3b10ebad 100644 --- a/src/hotspot/share/gc/z/zLargePages.cpp +++ b/src/hotspot/share/gc/z/zLargePages.cpp @@ -27,6 +27,7 @@ #include "runtime/os.hpp" ZLargePages::State ZLargePages::_state; +bool ZLargePages::_os_enforced_transparent_mode; void ZLargePages::initialize() { pd_initialize(); @@ -41,9 +42,17 @@ const char* ZLargePages::to_string() { return "Enabled (Explicit)"; case Transparent: - return "Enabled (Transparent)"; + if (_os_enforced_transparent_mode) { + return "Enabled (Transparent, OS enforced)"; + } else { + return "Enabled (Transparent)"; + } default: - return "Disabled"; + if (_os_enforced_transparent_mode) { + return "Disabled (OS enforced)"; + } else { + return "Disabled"; + } } } diff --git a/src/hotspot/share/gc/z/zLargePages.hpp b/src/hotspot/share/gc/z/zLargePages.hpp index 9f7c8310e50f4..72b9e85095c78 100644 --- a/src/hotspot/share/gc/z/zLargePages.hpp +++ b/src/hotspot/share/gc/z/zLargePages.hpp @@ -35,6 +35,7 @@ class ZLargePages : public AllStatic { }; static State _state; + static bool _os_enforced_transparent_mode; static void pd_initialize(); diff --git a/src/hotspot/share/gc/z/zNMethod.cpp b/src/hotspot/share/gc/z/zNMethod.cpp index e4c24660365ad..71d514face15a 100644 --- a/src/hotspot/share/gc/z/zNMethod.cpp +++ b/src/hotspot/share/gc/z/zNMethod.cpp @@ -28,6 +28,7 @@ #include "code/icBuffer.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetNMethod.hpp" +#include "gc/shared/classUnloadingContext.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/z/zAddress.hpp" #include "gc/z/zArray.inline.hpp" @@ -443,5 +444,5 @@ void ZNMethod::unlink(ZWorkers* workers, bool unloading_occurred) { } void ZNMethod::purge() { - CodeCache::flush_unlinked_nmethods(); + ClassUnloadingContext::context()->purge_and_free_nmethods(); } diff --git a/src/hotspot/share/jfr/instrumentation/jfrResolution.cpp b/src/hotspot/share/jfr/instrumentation/jfrResolution.cpp deleted file mode 100644 index 6385433560993..0000000000000 --- a/src/hotspot/share/jfr/instrumentation/jfrResolution.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "ci/ciKlass.hpp" -#include "ci/ciMethod.hpp" -#include "classfile/vmSymbols.hpp" -#include "interpreter/linkResolver.hpp" -#include "jfr/instrumentation/jfrResolution.hpp" -#include "jfr/recorder/checkpoint/types/traceid/jfrTraceIdMacros.hpp" -#include "oops/method.inline.hpp" -#include "runtime/javaThread.hpp" -#include "runtime/vframe.inline.hpp" -#ifdef COMPILER1 -#include "c1/c1_GraphBuilder.hpp" -#endif -#ifdef COMPILER2 -#include "opto/parse.hpp" -#endif - -static const char* const link_error_msg = "illegal access linking method 'jdk.jfr.internal.event.EventWriterFactory.getEventWriter(long)'"; - -static const Method* ljf_sender_method(JavaThread* jt) { - assert(jt != nullptr, "invariant"); - if (!jt->has_last_Java_frame()) { - return nullptr; - } - const vframeStream ljf(jt, false, false); - return ljf.method(); -} - -void JfrResolution::on_runtime_resolution(const CallInfo & info, TRAPS) { - assert(info.selected_method() != nullptr, "invariant"); - assert(info.resolved_klass() != nullptr, "invariant"); - static const Symbol* const event_writer_method_name = vmSymbols::getEventWriter_name(); - assert(event_writer_method_name != nullptr, "invariant"); - // Fast path - if (info.selected_method()->name() != event_writer_method_name) { - return; - } - static const Symbol* const event_writer_factory_klass_name = vmSymbols::jdk_jfr_internal_event_EventWriterFactory(); - assert(event_writer_factory_klass_name != nullptr, "invariant"); - if (info.resolved_klass()->name() != event_writer_factory_klass_name) { - return; - } - // Attempting to link against jdk.jfr.internal.event.EventWriterFactory.getEventWriter(). - // The sender, i.e. the method attempting to link, is in the ljf (if one exists). - const Method* const sender = ljf_sender_method(THREAD); - if (sender == nullptr) { - // A compiler thread is doing linktime resolution but there is no information about the sender available. - // For the compiler threads, the sender is instead found as part of bytecode parsing. - return; - } - // Is the sender method blessed for linkage? - if (IS_METHOD_BLESSED(sender)) { - return; - } -#if INCLUDE_JVMCI - // JVMCI compiler is doing linktime resolution - if (sender->method_holder()->name() == vmSymbols::jdk_vm_ci_hotspot_CompilerToVM()) { - if (sender->name()->equals("lookupMethodInPool")) { - return; - } - } -#endif - THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), link_error_msg); -} - -static inline bool is_compiler_linking_event_writer(const Symbol* holder, const Symbol* name) { - static const Symbol* const event_writer_factory_klass_name = vmSymbols::jdk_jfr_internal_event_EventWriterFactory(); - assert(event_writer_factory_klass_name != nullptr, "invariant"); - if (holder != event_writer_factory_klass_name) { - return false; - } - static const Symbol* const event_writer_method_name = vmSymbols::getEventWriter_name(); - assert(event_writer_method_name != nullptr, "invariant"); - return name == event_writer_method_name; -} - -static inline bool is_compiler_linking_event_writer(const ciKlass * holder, const ciMethod * target) { - assert(holder != nullptr, "invariant"); - assert(target != nullptr, "invariant"); - return is_compiler_linking_event_writer(holder->name()->get_symbol(), target->name()->get_symbol()); -} - -#ifdef COMPILER1 -// C1 -void JfrResolution::on_c1_resolution(const GraphBuilder * builder, const ciKlass * holder, const ciMethod * target) { - if (is_compiler_linking_event_writer(holder, target) && !IS_METHOD_BLESSED(builder->method()->get_Method())) { - builder->bailout(link_error_msg); - } -} -#endif - -#ifdef COMPILER2 -// C2 -void JfrResolution::on_c2_resolution(const Parse * parse, const ciKlass * holder, const ciMethod * target) { - if (is_compiler_linking_event_writer(holder, target) && !IS_METHOD_BLESSED(parse->method()->get_Method())) { - parse->C->record_failure(link_error_msg); - } -} -#endif - -#if INCLUDE_JVMCI -// JVMCI -void JfrResolution::on_jvmci_resolution(const Method* caller, const Method* target, TRAPS) { - if (is_compiler_linking_event_writer(target->method_holder()->name(), target->name())) { - if (caller == nullptr || !IS_METHOD_BLESSED(caller)) { - THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), link_error_msg); - } - } -} -#endif diff --git a/src/hotspot/share/jfr/jfr.cpp b/src/hotspot/share/jfr/jfr.cpp index 99faa108bfd9f..45848fb024311 100644 --- a/src/hotspot/share/jfr/jfr.cpp +++ b/src/hotspot/share/jfr/jfr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ */ #include "precompiled.hpp" -#include "jfr/instrumentation/jfrResolution.hpp" #include "jfr/jfr.hpp" #include "jfr/jni/jfrJavaSupport.hpp" #include "jfr/leakprofiler/leakProfiler.hpp" @@ -33,6 +32,7 @@ #include "jfr/recorder/service/jfrOptionSet.hpp" #include "jfr/recorder/service/jfrOptionSet.hpp" #include "jfr/recorder/repository/jfrRepository.hpp" +#include "jfr/support/jfrResolution.hpp" #include "jfr/support/jfrThreadLocal.hpp" #include "runtime/java.hpp" @@ -67,9 +67,7 @@ void Jfr::on_create_vm_3() { } void Jfr::on_unloading_classes() { - if (JfrRecorder::is_created()) { - JfrCheckpointManager::on_unloading_classes(); - } + JfrCheckpointManager::on_unloading_classes(); } bool Jfr::is_excluded(Thread* t) { @@ -104,6 +102,10 @@ void Jfr::on_resolution(const CallInfo& info, TRAPS) { JfrResolution::on_runtime_resolution(info, THREAD); } +void Jfr::on_backpatching(const Method* callee_method, JavaThread* jt) { + JfrResolution::on_backpatching(callee_method, jt); +} + #ifdef COMPILER1 void Jfr::on_resolution(const GraphBuilder* builder, const ciKlass* holder, const ciMethod* target) { JfrResolution::on_c1_resolution(builder, holder, target); diff --git a/src/hotspot/share/jfr/jfr.hpp b/src/hotspot/share/jfr/jfr.hpp index 89ecf5bc7982b..af492f85123c9 100644 --- a/src/hotspot/share/jfr/jfr.hpp +++ b/src/hotspot/share/jfr/jfr.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,6 +70,7 @@ class Jfr : AllStatic { static void on_vm_error_report(outputStream* st); static bool on_flight_recorder_option(const JavaVMOption** option, char* delimiter); static bool on_start_flight_recording_option(const JavaVMOption** option, char* delimiter); + static void on_backpatching(const Method* callee_method, JavaThread* jt); }; #endif // SHARE_JFR_JFR_HPP diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp index 82f26d7bdd062..db534b6df3c43 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp @@ -45,6 +45,7 @@ #include "jfr/instrumentation/jfrEventClassTransformer.hpp" #include "jfr/instrumentation/jfrJvmtiAgent.hpp" #include "jfr/leakprofiler/leakProfiler.hpp" +#include "jfr/support/jfrDeprecationManager.hpp" #include "jfr/support/jfrJdkJfrEvent.hpp" #include "jfr/support/jfrKlassUnloading.hpp" #include "jfr/utilities/jfrJavaLog.hpp" @@ -159,15 +160,19 @@ NO_TRANSITION(jdouble, jfr_time_conv_factor(JNIEnv* env, jclass jvm)) return (jdouble)JfrTimeConverter::nano_to_counter_multiplier(); NO_TRANSITION_END -NO_TRANSITION(jboolean, jfr_set_cutoff(JNIEnv* env, jclass jvm, jlong event_type_id, jlong cutoff_ticks)) - return JfrEventSetting::set_cutoff(event_type_id, cutoff_ticks) ? JNI_TRUE : JNI_FALSE; -NO_TRANSITION_END - NO_TRANSITION(jboolean, jfr_set_throttle(JNIEnv* env, jclass jvm, jlong event_type_id, jlong event_sample_size, jlong period_ms)) JfrEventThrottler::configure(static_cast(event_type_id), event_sample_size, period_ms); return JNI_TRUE; NO_TRANSITION_END +NO_TRANSITION(void, jfr_set_miscellaneous(JNIEnv* env, jobject jvm, jlong event_type_id, jlong value)) + JfrEventSetting::set_miscellaneous(event_type_id, value); + const JfrEventId typed_event_id = (JfrEventId)event_type_id; + if (EventDeprecatedInvocation::eventId == typed_event_id) { + JfrDeprecationManager::on_level_setting_update(value); + } +NO_TRANSITION_END + NO_TRANSITION(jboolean, jfr_should_rotate_disk(JNIEnv* env, jclass jvm)) return JfrChunkRotation::should_rotate() ? JNI_TRUE : JNI_FALSE; NO_TRANSITION_END diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp index b37841aeac297..c75a4c9721913 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp @@ -127,10 +127,10 @@ void JNICALL jfr_set_force_instrumentation(JNIEnv* env, jclass jvm, jboolean for jlong JNICALL jfr_get_unloaded_event_classes_count(JNIEnv* env, jclass jvm); -jboolean JNICALL jfr_set_cutoff(JNIEnv* env, jclass jvm, jlong event_type_id, jlong cutoff_ticks); - jboolean JNICALL jfr_set_throttle(JNIEnv* env, jclass jvm, jlong event_type_id, jlong event_sample_size, jlong period_ms); +void JNICALL jfr_set_miscellaneous(JNIEnv* env, jobject jvm, jlong id, jlong value); + void JNICALL jfr_emit_old_object_samples(JNIEnv* env, jclass jvm, jlong cutoff_ticks, jboolean, jboolean); jboolean JNICALL jfr_should_rotate_disk(JNIEnv* env, jclass jvm); diff --git a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp index f8475881ff8ad..338f63fbc4f37 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp @@ -82,7 +82,7 @@ JfrJniMethodRegistration::JfrJniMethodRegistration(JNIEnv* env) { (char*)"uncaughtException", (char*)"(Ljava/lang/Thread;Ljava/lang/Throwable;)V", (void*)jfr_uncaught_exception, (char*)"setForceInstrumentation", (char*)"(Z)V", (void*)jfr_set_force_instrumentation, (char*)"getUnloadedEventClassCount", (char*)"()J", (void*)jfr_get_unloaded_event_classes_count, - (char*)"setCutoff", (char*)"(JJ)Z", (void*)jfr_set_cutoff, + (char*)"setMiscellaneous", (char*)"(JJ)V", (void*)jfr_set_miscellaneous, (char*)"setThrottle", (char*)"(JJJ)Z", (void*)jfr_set_throttle, (char*)"emitOldObjectSamples", (char*)"(JZZ)V", (void*)jfr_emit_old_object_samples, (char*)"shouldRotateDisk", (char*)"()Z", (void*)jfr_should_rotate_disk, diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp index ffd973696f150..9f6679c93ebfc 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp @@ -416,9 +416,9 @@ static void install_type_set_blobs() { iterate_samples(installer); } -static void save_type_set_blob(JfrCheckpointWriter& writer, bool copy = false) { +static void save_type_set_blob(JfrCheckpointWriter& writer) { assert(writer.has_data(), "invariant"); - const JfrBlobHandle blob = copy ? writer.copy() : writer.move(); + const JfrBlobHandle blob = writer.copy(); if (saved_type_set_blobs.valid()) { saved_type_set_blobs->set_next(blob); } else { @@ -438,9 +438,8 @@ void ObjectSampleCheckpoint::on_type_set(JfrCheckpointWriter& writer) { } void ObjectSampleCheckpoint::on_type_set_unload(JfrCheckpointWriter& writer) { - assert_locked_or_safepoint(ClassLoaderDataGraph_lock); assert(LeakProfiler::is_running(), "invariant"); if (writer.has_data() && ObjectSampler::sampler()->last() != nullptr) { - save_type_set_blob(writer, true); + save_type_set_blob(writer); } } diff --git a/src/hotspot/share/jfr/metadata/metadata.xml b/src/hotspot/share/jfr/metadata/metadata.xml index 7977b732eef3a..c1f626a819201 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xml +++ b/src/hotspot/share/jfr/metadata/metadata.xml @@ -1252,6 +1252,13 @@ + + + + + + diff --git a/src/hotspot/share/jfr/metadata/metadata.xsd b/src/hotspot/share/jfr/metadata/metadata.xsd index ffef3d932e3c2..9d6cdd3d7449e 100644 --- a/src/hotspot/share/jfr/metadata/metadata.xsd +++ b/src/hotspot/share/jfr/metadata/metadata.xsd @@ -1,7 +1,7 @@ - - - - - AcceleratorTest - - - -

AcceleratorTest
Bug ID:

- -

See the dialog box (usually in upper left corner) for instructions

- - - - diff --git a/test/jdk/java/awt/event/KeyEvent/AcceleratorTest/AcceleratorTest.java b/test/jdk/java/awt/event/KeyEvent/AcceleratorTest/AcceleratorTest.java index 8d983461d7453..1d9635d58caa1 100644 --- a/test/jdk/java/awt/event/KeyEvent/AcceleratorTest/AcceleratorTest.java +++ b/test/jdk/java/awt/event/KeyEvent/AcceleratorTest/AcceleratorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,307 +22,170 @@ */ /* - test - @bug 6680988 - @summary verify that various shortcuts and accelerators work - @author yuri.nesterenko : area=awt.keyboard - @run applet/manual=yesno AcceleratorTest.html -*/ - -/** - * AcceleratorTest.java - * - * summary: + * @test + * @bug 6680988 + * @key headful + * @summary verify that various shortcuts and accelerators work + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual AcceleratorTest */ -//import java.applet.Applet; -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; import java.util.Hashtable; - - -public class AcceleratorTest extends JApplet -{ - //Declare things used in the test, like buttons and labels here - static int pressed = 0; - Hashtable cmdHash = new Hashtable(); - String[] CMD = { - "\u042E, keep me in focus", - "Item Cyrl Be", - "Item English Period", - "Item English N", - "\u0436" +import javax.swing.AbstractAction; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JTextArea; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; + +public class AcceleratorTest { + static JFrame output; + static JTextArea text; + static JFrame jfr; + static Hashtable cmdHash = new Hashtable(); + static String[] CMD = { + "\u042E, keep me in focus", + "Item Ctrl Be", + "Item Ctrl English Period", + "Item Ctrl English N", + "\u0436" }; - JFrame jfr; - - public void init() - { - //Create instructions for the user here, as well as set up - // the environment -- set the layout manager, add buttons, - // etc. - this.setLayout (new BorderLayout ()); - - String[] instructions = - { - " Ensure you have Russian keyboard layout as a currently active.", - "(1) Press Ctrl+\u0411 (a key with \",<\" on it) ", - "(2) Find a . (period) in this layout (perhaps \"/?\" or \"7&\" key).", - "Press Ctrl+.", - "(3) Press Crtl+ regular English . (period) key (on \".>\" )", - "(4) Press Ctrl+ key with English N.", - "(5) Press Alt+\u042E (key with \".>\")", - "(6) Press Alt+\u0436 (key with \";:\")", - "If all expected commands will be fired, look for message", - "\"All tests passed\"" - }; - Sysout.createDialogWithInstructions( instructions ); - for(int i = 0; i < CMD.length; i++) { + public static void main(String[] args) throws Exception { + String instructions = + "Ensure you have Russian keyboard layout as a currently active.\n" + + "(1) Press Ctrl + \u0411 (a key with \",<\" on it) \n" + + "(2) Find a . (period) in this layout (perhaps \"/?\" or \"7&\" key). " + + "Press Ctrl + .\n" + + "(3) Press Ctrl + regular English . (period) key (on \".>\" )\n" + + "(4) Press Ctrl + key with English N.\n" + + "(5) Press Alt + \u042E (key with \".>\")\n" + + "(6) Press Alt + \u0436 (key with \";:\")\n" + + "If all expected commands will be fired, look for message\n" + + "\"All tests passed\""; + + for (int i = 0; i < CMD.length; i++) { cmdHash.put(CMD[i], 0); } - jfr = new JFrame(); - JButton jbu; - jfr.add((jbu = new JButton(CMD[0]))); - jbu.setMnemonic(java.awt.event.KeyEvent.getExtendedKeyCodeForChar('\u042E')); - jbu.addActionListener( new ALi(CMD[0])); - - - JMenuBar menuBar = new JMenuBar(); - jfr.setJMenuBar(menuBar); - JMenu menu = new JMenu("Menu"); - menuBar.add(menu); + PassFailJFrame testFrame = new PassFailJFrame.Builder() + .title("Test Instructions Frame") + .instructions(instructions) + .testTimeOut(10) + .rows(10) + .columns(45) + .build(); + + SwingUtilities.invokeAndWait(() -> { + output = new JFrame("output"); + text = new JTextArea(); + output.getContentPane().add(text); + + jfr = new JFrame("AcceleratorTest"); + jfr.setLayout(new BorderLayout()); + JButton jbu; + jfr.add((jbu = new JButton(CMD[0]))); + jbu.setMnemonic(java.awt.event.KeyEvent.getExtendedKeyCodeForChar('\u042E')); + jbu.addActionListener(new ALi(CMD[0])); + + JMenuBar menuBar = new JMenuBar(); + jfr.setJMenuBar(menuBar); + JMenu menu = new JMenu("Menu"); + menuBar.add(menu); + + JMenuItem menuItem = new JMenuItem(CMD[1]); + menuItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent + .getExtendedKeyCodeForChar('\u0431'), InputEvent.CTRL_DOWN_MASK)); + + JMenuItem menuItemEnglish = new JMenuItem(CMD[2]); + menuItemEnglish.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_PERIOD, + InputEvent.CTRL_DOWN_MASK)); + + JMenuItem menuItemE1 = new JMenuItem(CMD[3]); + menuItemE1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, + InputEvent.CTRL_DOWN_MASK)); + + menuItem.addActionListener(new ALi(CMD[1])); + menuItemEnglish.addActionListener(new ALi(CMD[2])); + menuItemE1.addActionListener(new ALi(CMD[3])); + + menu.add(menuItem); + menu.add(menuItemEnglish); + menu.add(menuItemE1); + + KeyStroke ks; + InputMap im = new InputMap(); + ks = KeyStroke.getKeyStroke(KeyEvent.getExtendedKeyCodeForChar('\u0436'), + java.awt.event.InputEvent.ALT_DOWN_MASK); + im.put(ks, "pushAction"); + im.setParent(jbu.getInputMap(JComponent.WHEN_FOCUSED)); + jbu.setInputMap(JComponent.WHEN_FOCUSED, im); + + jbu.getActionMap().put("pushAction", + new AbstractAction("pushAction") { + public void actionPerformed(ActionEvent evt) { + if (evt.getActionCommand().equals(CMD[4])) { + cmdHash.put(CMD[4], 1); + } + boolean notYet = false; + for (int i = 0; i < CMD.length; i++) { + if (cmdHash.get(CMD[i]) == 0) notYet = true; + } + text.append(evt.getActionCommand() + " FIRED\n"); + if (!notYet) { + text.append("All tests passed."); + } + } + } + ); + }); + + testFrame.addTestWindow(jfr); + testFrame.addTestWindow(output); + + PassFailJFrame.positionTestWindow(jfr, PassFailJFrame.Position.HORIZONTAL); + jfr.setSize(200, 200); + + PassFailJFrame.positionTestWindow(output, PassFailJFrame.Position.HORIZONTAL); + output.setSize(200, 200); - JMenuItem menuItem = new JMenuItem(CMD[1]); - menuItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.getExtendedKeyCodeForChar('\u0431'), - InputEvent.CTRL_DOWN_MASK)); - - JMenuItem menuItemEnglish = new JMenuItem(CMD[2]); - menuItemEnglish.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_PERIOD, - InputEvent.CTRL_DOWN_MASK)); - JMenuItem menuItemE1 = new JMenuItem(CMD[3]); - menuItemE1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, - InputEvent.CTRL_DOWN_MASK)); - menuItem.addActionListener( new ALi(CMD[1])); - menuItemEnglish.addActionListener( new ALi(CMD[2])); - menuItemE1.addActionListener( new ALi(CMD[3])); - menu.add(menuItem); - menu.add(menuItemEnglish); - menu.add(menuItemE1); - - KeyStroke ks; - InputMap im = new InputMap(); - ks = KeyStroke.getKeyStroke(KeyEvent.getExtendedKeyCodeForChar('\u0436'), java.awt.event.InputEvent.ALT_DOWN_MASK); - im.put(ks, "pushAction"); - im.setParent(jbu.getInputMap(JComponent.WHEN_FOCUSED)); - jbu.setInputMap(JComponent.WHEN_FOCUSED, im); - - jbu.getActionMap().put("pushAction", - new AbstractAction("pushAction") { - public void actionPerformed(ActionEvent evt) { - if( evt.getActionCommand().equals(CMD[4])) { - cmdHash.put(CMD[4], 1); - } - boolean notYet = false; - for(int i = 0; i < CMD.length; i++) { - if(cmdHash.get(CMD[i]) == 0 ) notYet = true; - } - Sysout.println("Fired"); - if( !notYet ) { - Sysout.println("All tests passed."); - } - } - } - ); - - - jfr.setBounds(650,0,200,200); jfr.setVisible(true); + output.setVisible(true); - }//End init() - - public void start () - { - //Get things going. Request focus, set size, et cetera - setSize (200,200); - setVisible(true); - validate(); + testFrame.awaitAndCheck(); + } - }// start() - public class ALi implements ActionListener { + public static class ALi implements ActionListener { String expectedCmd; - public ALi( String eCmd ) { + + public ALi(String eCmd) { expectedCmd = eCmd; } + public void actionPerformed(ActionEvent ae) { - if( cmdHash.containsKey(ae.getActionCommand()) ) { + if (cmdHash.containsKey(ae.getActionCommand())) { cmdHash.put(expectedCmd, 1); } boolean notYet = false; - for(int i = 0; i < CMD.length; i++) { - if(cmdHash.get(CMD[i]) == 0 ) notYet = true; - //Sysout.println(CMD[i]+":"+cmdHash.get(CMD[i])); + for (int i = 0; i < CMD.length; i++) { + if (cmdHash.get(CMD[i]) == 0) notYet = true; + //text.append(CMD[i]+":"+cmdHash.get(CMD[i])); } - Sysout.println("FIRED"); - if( !notYet ) { - Sysout.println("All tests passed."); + text.append(ae.getActionCommand() + " FIRED\n"); + if (!notYet) { + text.append("All tests passed.\n"); } } } - - -}// class AcceleratorTest - -/* Place other classes related to the test after this line */ - - - - - -/**************************************************** - Standard Test Machinery - DO NOT modify anything below -- it's a standard - chunk of code whose purpose is to make user - interaction uniform, and thereby make it simpler - to read and understand someone else's test. - ****************************************************/ - -/** - This is part of the standard test machinery. - It creates a dialog (with the instructions), and is the interface - for sending text messages to the user. - To print the instructions, send an array of strings to Sysout.createDialog - WithInstructions method. Put one line of instructions per array entry. - To display a message for the tester to see, simply call Sysout.println - with the string to be displayed. - This mimics System.out.println but works within the test harness as well - as standalone. - */ - -class Sysout -{ - private static TestDialog dialog; - private static boolean numbering = false; - private static int messageNumber = 0; - - public static void createDialogWithInstructions( String[] instructions ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - dialog.printInstructions( instructions ); - dialog.setVisible(true); - println( "Any messages for the tester will display here." ); - } - - public static void createDialog( ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - String[] defInstr = { "Instructions will appear here. ", "" } ; - dialog.printInstructions( defInstr ); - dialog.setVisible(true); - println( "Any messages for the tester will display here." ); - } - - /* Enables message counting for the tester. */ - public static void enableNumbering(boolean enable){ - numbering = enable; - } - - public static void printInstructions( String[] instructions ) - { - dialog.printInstructions( instructions ); - } - - - public static void println( String messageIn ) - { - if (numbering) { - messageIn = "" + messageNumber + " " + messageIn; - messageNumber++; - } - dialog.displayMessage( messageIn ); - } - -}// Sysout class - -/** - This is part of the standard test machinery. It provides a place for the - test instructions to be displayed, and a place for interactive messages - to the user to be displayed. - To have the test instructions displayed, see Sysout. - To have a message to the user be displayed, see Sysout. - Do not call anything in this dialog directly. - */ -class TestDialog extends Dialog -{ - - TextArea instructionsText; - TextArea messageText; - int maxStringLength = 80; - - //DO NOT call this directly, go through Sysout - public TestDialog( Frame frame, String name ) - { - super( frame, name ); - int scrollBoth = TextArea.SCROLLBARS_BOTH; - instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); - add( "North", instructionsText ); - - messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); - add("Center", messageText); - - pack(); - - setVisible(true); - }// TestDialog() - - //DO NOT call this directly, go through Sysout - public void printInstructions( String[] instructions ) - { - //Clear out any current instructions - instructionsText.setText( "" ); - - //Go down array of instruction strings - - String printStr, remainingStr; - for( int i=0; i < instructions.length; i++ ) - { - //chop up each into pieces maxSringLength long - remainingStr = instructions[ i ]; - while( remainingStr.length() > 0 ) - { - //if longer than max then chop off first max chars to print - if( remainingStr.length() >= maxStringLength ) - { - //Try to chop on a word boundary - int posOfSpace = remainingStr. - lastIndexOf( ' ', maxStringLength - 1 ); - - if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; - - printStr = remainingStr.substring( 0, posOfSpace + 1 ); - remainingStr = remainingStr.substring( posOfSpace + 1 ); - } - //else just print - else - { - printStr = remainingStr; - remainingStr = ""; - } - - instructionsText.append( printStr + "\n" ); - - }// while - - }// for - - }//printInstructions() - - //DO NOT call this directly, go through Sysout - public void displayMessage( String messageIn ) - { - messageText.append( messageIn + "\n" ); - System.out.println(messageIn); - } - -}// TestDialog class +} diff --git a/test/jdk/java/awt/print/Dialog/DestinationTest.java b/test/jdk/java/awt/print/Dialog/DestinationTest.java index 8bb9403b566b4..933fba3042b07 100644 --- a/test/jdk/java/awt/print/Dialog/DestinationTest.java +++ b/test/jdk/java/awt/print/Dialog/DestinationTest.java @@ -24,6 +24,7 @@ /** * @test * @bug 4846344 4851365 4851321 4851316 4863656 5046198 6293139 + * @key printer * @summary Confirm that cancelling the dialog will not prompt for file. * @run main/manual DestinationTest */ diff --git a/test/jdk/java/awt/print/Dialog/DialogCopies.java b/test/jdk/java/awt/print/Dialog/DialogCopies.java index 39d15461de8d1..1fb874a9d57da 100644 --- a/test/jdk/java/awt/print/Dialog/DialogCopies.java +++ b/test/jdk/java/awt/print/Dialog/DialogCopies.java @@ -24,6 +24,7 @@ /* * @test * @bug 6357858 + * @key printer * @summary Job must reports the number of copies set in the dialog. * @run main/manual DialogCopies */ diff --git a/test/jdk/java/awt/print/Dialog/DialogOrient.java b/test/jdk/java/awt/print/Dialog/DialogOrient.java index c8009d742d737..6650ced64f46e 100644 --- a/test/jdk/java/awt/print/Dialog/DialogOrient.java +++ b/test/jdk/java/awt/print/Dialog/DialogOrient.java @@ -24,6 +24,7 @@ /* @test @bug 6594374 + @key printer @summary Confirm that the orientation is as specified. @run main/manual DialogOrient */ diff --git a/test/jdk/java/awt/print/Dialog/DialogOwnerTest.java b/test/jdk/java/awt/print/Dialog/DialogOwnerTest.java index b4fbc7c3d37f8..dc4064466caca 100644 --- a/test/jdk/java/awt/print/Dialog/DialogOwnerTest.java +++ b/test/jdk/java/awt/print/Dialog/DialogOwnerTest.java @@ -23,6 +23,7 @@ /* @test @bug 8203796 + @key printer @run main/manual DialogOwnerTest @summary Test DialogOwner API */ diff --git a/test/jdk/java/awt/print/Dialog/DialogType.java b/test/jdk/java/awt/print/Dialog/DialogType.java index 00b07930cf07c..472b89e44f213 100644 --- a/test/jdk/java/awt/print/Dialog/DialogType.java +++ b/test/jdk/java/awt/print/Dialog/DialogType.java @@ -24,6 +24,7 @@ /** * @test * @bug 6568874 + * @key printer * @summary Verify the native dialog works with attribute sets. * @run main/manual=yesno DialogType */ diff --git a/test/jdk/java/awt/print/Dialog/MediaInPrintable.java b/test/jdk/java/awt/print/Dialog/MediaInPrintable.java index a800f69c74da2..cb74cb140f55c 100644 --- a/test/jdk/java/awt/print/Dialog/MediaInPrintable.java +++ b/test/jdk/java/awt/print/Dialog/MediaInPrintable.java @@ -24,6 +24,7 @@ /** * @test * @bug 4869575 6361766 + * @key printer * @summary Setting orientation in the page format does not have any effect on the printout. To test 6361766, the application must exit. * @run main/manual MediaInPrintable */ diff --git a/test/jdk/java/awt/print/Dialog/PaperSizeError.java b/test/jdk/java/awt/print/Dialog/PaperSizeError.java index 970c7df2fcc23..fea7bb85af873 100644 --- a/test/jdk/java/awt/print/Dialog/PaperSizeError.java +++ b/test/jdk/java/awt/print/Dialog/PaperSizeError.java @@ -24,6 +24,7 @@ /** * @test * @bug 6360339 + * @key printer * @summary Test for fp error in paper size calculations. * @run main/manual PaperSizeError */ diff --git a/test/jdk/java/awt/print/Dialog/PrintApplet.java b/test/jdk/java/awt/print/Dialog/PrintApplet.java index ecd9920571c6a..c8a3cd955feed 100644 --- a/test/jdk/java/awt/print/Dialog/PrintApplet.java +++ b/test/jdk/java/awt/print/Dialog/PrintApplet.java @@ -24,6 +24,7 @@ /* @test @bug 5024549 + @key printer @summary Pass if dialogs are modal. @run applet/manual PrintApplet.html */ diff --git a/test/jdk/java/awt/print/Dialog/PrintDialog.java b/test/jdk/java/awt/print/Dialog/PrintDialog.java index 870db01a98574..c81ebfbc45246 100644 --- a/test/jdk/java/awt/print/Dialog/PrintDialog.java +++ b/test/jdk/java/awt/print/Dialog/PrintDialog.java @@ -24,6 +24,7 @@ /* @test @bug 6342748 + @key printer @summary Pass if dialogs display correctly @run main/manual PrintDialog */ diff --git a/test/jdk/java/awt/print/Dialog/PrintDlgPageable.java b/test/jdk/java/awt/print/Dialog/PrintDlgPageable.java index d447874f72aeb..eadd3cf9cb6bc 100644 --- a/test/jdk/java/awt/print/Dialog/PrintDlgPageable.java +++ b/test/jdk/java/awt/print/Dialog/PrintDlgPageable.java @@ -24,6 +24,7 @@ /** * @test * @bug 4869502 4869539 + * @key printer * @summary Confirm that ToPage is populated for argument =2. Range is disabled for argument = 0. * @run main/manual PrintDlgPageable */ diff --git a/test/jdk/java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.java b/test/jdk/java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.java index 8d29dbb58490f..2d2e00f2ed7a8 100644 --- a/test/jdk/java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.java +++ b/test/jdk/java/awt/print/Dialog/RestoreActiveWindowTest/RestoreActiveWindowTest.java @@ -24,6 +24,7 @@ /* * @test * @bug 6365992 6379599 8137137 + * @key printer * @summary REG: Showing and disposing a native print dialog makes the main * frame inactive, Win32 * @run main/manual RestoreActiveWindowTest diff --git a/test/jdk/java/awt/print/Headless/HeadlessPrinterJob.java b/test/jdk/java/awt/print/Headless/HeadlessPrinterJob.java index ff7a22ec8a3e2..143c898e32ace 100644 --- a/test/jdk/java/awt/print/Headless/HeadlessPrinterJob.java +++ b/test/jdk/java/awt/print/Headless/HeadlessPrinterJob.java @@ -31,6 +31,7 @@ /* * @test + * @key printer * @summary Check that PrinterJob constructor and methods do not throw unexpected * exceptions in headless mode * @run main/othervm -Djava.awt.headless=true HeadlessPrinterJob diff --git a/test/jdk/java/awt/print/MissedFontFamilyName/PrintFontWithMissedFontFamilyTest.java b/test/jdk/java/awt/print/MissedFontFamilyName/PrintFontWithMissedFontFamilyTest.java index a6808282f37aa..af655f2d69e84 100644 --- a/test/jdk/java/awt/print/MissedFontFamilyName/PrintFontWithMissedFontFamilyTest.java +++ b/test/jdk/java/awt/print/MissedFontFamilyName/PrintFontWithMissedFontFamilyTest.java @@ -25,6 +25,7 @@ /** * @test * @bug 8265761 + * @key printer * @requires (os.family == "windows") * @summary Font with missed font family name is not properly printed on Windows * @run main/othervm/manual PrintFontWithMissedFontFamilyTest diff --git a/test/jdk/java/awt/print/PageFormat/CustomPaper.java b/test/jdk/java/awt/print/PageFormat/CustomPaper.java index 3b8e83d5c1b22..1976a20c01f12 100644 --- a/test/jdk/java/awt/print/PageFormat/CustomPaper.java +++ b/test/jdk/java/awt/print/PageFormat/CustomPaper.java @@ -25,7 +25,7 @@ * @test * @bug 4355514 * @bug 4385157 - * @author Jennifer Godinez + * @key printer * @summary Prints a rectangle to show the imageable area of a * 12in x 14in custom paper size. * @run main/manual CustomPaper diff --git a/test/jdk/java/awt/print/PageFormat/ImageableAreaTest.java b/test/jdk/java/awt/print/PageFormat/ImageableAreaTest.java index 7bf37415e6e7d..07f458704a53a 100644 --- a/test/jdk/java/awt/print/PageFormat/ImageableAreaTest.java +++ b/test/jdk/java/awt/print/PageFormat/ImageableAreaTest.java @@ -47,7 +47,7 @@ * @test * @bug 8044444 8081491 * @summary The output's 'Page-n' footer does not show completely - * @author Alexandr Scherbatiy + * @key printer * @run main/manual ImageableAreaTest */ public class ImageableAreaTest { diff --git a/test/jdk/java/awt/print/PageFormat/NullPaper.java b/test/jdk/java/awt/print/PageFormat/NullPaper.java index 0bae3aa95921d..1a9000b61350c 100644 --- a/test/jdk/java/awt/print/PageFormat/NullPaper.java +++ b/test/jdk/java/awt/print/PageFormat/NullPaper.java @@ -23,13 +23,11 @@ /* @test - @key headful @bug 4199506 @summary java.awt.print.PageFormat.setpaper(Paper paper) assertion test fails by not throwing NullPointerException when a null paper instance is passed as argument and this is specified in the doc. - @author rbi: area=PageFormat @run main NullPaper */ @@ -46,9 +44,6 @@ */ -import java.awt.*; -import java.awt.event.*; -import java.awt.geom.*; import java.awt.print.*; // This test is a "main" test as applets would need Runtime permission @@ -154,7 +149,6 @@ public static synchronized void setTimeoutTo( int seconds ) public static synchronized void pass() { System.out.println( "The test passed." ); - System.out.println( "The test is over, hit Ctl-C to stop Java VM" ); //first check if this is executing in main thread if ( mainThread == Thread.currentThread() ) { @@ -180,7 +174,6 @@ public static synchronized void fail() public static synchronized void fail( String whyFailed ) { System.out.println( "The test failed: " + whyFailed ); - System.out.println( "The test is over, hit Ctl-C to stop Java VM" ); //check if this called from main thread if ( mainThread == Thread.currentThread() ) { diff --git a/test/jdk/java/awt/print/PageFormat/Orient.java b/test/jdk/java/awt/print/PageFormat/Orient.java index ac3bb1ed84054..ea6facaf57042 100644 --- a/test/jdk/java/awt/print/PageFormat/Orient.java +++ b/test/jdk/java/awt/print/PageFormat/Orient.java @@ -27,7 +27,7 @@ @summary Confirm that the you get three pages of output, one each in portrait, landscape, and reverse landscape orientations. - @author rbi: area=PageFormat + @key printer @run main/manual Orient */ diff --git a/test/jdk/java/awt/print/PageFormat/PageFormatFromAttributes.java b/test/jdk/java/awt/print/PageFormat/PageFormatFromAttributes.java index e552db507de93..b5ac83969f2b3 100644 --- a/test/jdk/java/awt/print/PageFormat/PageFormatFromAttributes.java +++ b/test/jdk/java/awt/print/PageFormat/PageFormatFromAttributes.java @@ -25,6 +25,7 @@ * @test * @bug 4500750 6848799 8028584 * @summary Tests creating page format from attributes + * @key printer * @run main PageFormatFromAttributes */ import java.awt.print.*; diff --git a/test/jdk/java/awt/print/PageFormat/PageSetupDialog.java b/test/jdk/java/awt/print/PageFormat/PageSetupDialog.java index 98da138ac2239..5284793ef0153 100644 --- a/test/jdk/java/awt/print/PageFormat/PageSetupDialog.java +++ b/test/jdk/java/awt/print/PageFormat/PageSetupDialog.java @@ -28,7 +28,7 @@ * @bug 6358747 * @bug 6574633 * @summary Page setup dialog settings - * @author prr + * @key printer * @run main/manual PageSetupDialog */ diff --git a/test/jdk/java/awt/print/PageFormat/PrintContentCutOffTest.java b/test/jdk/java/awt/print/PageFormat/PrintContentCutOffTest.java index d2362cdc81536..df07741c9076d 100644 --- a/test/jdk/java/awt/print/PageFormat/PrintContentCutOffTest.java +++ b/test/jdk/java/awt/print/PageFormat/PrintContentCutOffTest.java @@ -24,6 +24,7 @@ /** * @test + * @key printer * @bug 8295737 * @summary macOS: Print content cut off when width > height with portrait orientation * @run main/othervm/manual PrintContentCutOffTest diff --git a/test/jdk/java/awt/print/PageFormat/ReverseLandscapeTest.java b/test/jdk/java/awt/print/PageFormat/ReverseLandscapeTest.java index 2c6544f4af178..850123aa9a8af 100644 --- a/test/jdk/java/awt/print/PageFormat/ReverseLandscapeTest.java +++ b/test/jdk/java/awt/print/PageFormat/ReverseLandscapeTest.java @@ -23,7 +23,7 @@ /* * @test - * @key headful + * @key headful printer * @bug 4254954 * @summary PageFormat would fail on solaris when setting orientation */ diff --git a/test/jdk/java/awt/print/PageFormat/SetOrient.html b/test/jdk/java/awt/print/PageFormat/SetOrient.html index e500872ff0548..422d64e4610f1 100644 --- a/test/jdk/java/awt/print/PageFormat/SetOrient.html +++ b/test/jdk/java/awt/print/PageFormat/SetOrient.html @@ -27,6 +27,7 @@ @bug 4186119 @summary Confirm that the clip and transform of the Graphics2D is affected by the landscape orientation of the PageFormat. + @key printer @run applet/manual=yesno SetOrient.html --> diff --git a/test/jdk/java/awt/print/PageFormat/SmallPaperPrinting.java b/test/jdk/java/awt/print/PageFormat/SmallPaperPrinting.java index e03e9f283b270..e936cd047de7b 100644 --- a/test/jdk/java/awt/print/PageFormat/SmallPaperPrinting.java +++ b/test/jdk/java/awt/print/PageFormat/SmallPaperPrinting.java @@ -21,43 +21,56 @@ * questions. */ - import java.awt.*; - import java.awt.print.*; +import java.awt.Graphics; +import java.awt.print.PageFormat; +import java.awt.print.Paper; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; - public class SmallPaperPrinting - { - public static void main(String args[]) - { - System.out.println("----------------- Instructions --------------------"); - System.out.println("Arguments: (none) - paper width=1, height=.0001"); - System.out.println(" 1 - paper width=.0001, height=1"); - System.out.println(" 2 - paper width=-1, height=1"); - System.out.println("A passing test should catch a PrinterException"); - System.out.println("and should display \"Print error: (exception msg)\"."); - System.out.println("---------------------------------------------------\n"); - PrinterJob job = PrinterJob.getPrinterJob(); - PageFormat format = job.defaultPage(); - Paper paper = format.getPaper(); +/* + * @test + * @key printer + * @run main/othervm SmallPaperPrinting + * @run main/othervm SmallPaperPrinting 1 + * @run main/othervm SmallPaperPrinting 2 + */ + +public class SmallPaperPrinting +{ + public static void main(String args[]) { + System.out.println("----------------- Instructions --------------------"); + System.out.println("Arguments: (none) - paper width=1, height=.0001"); + System.out.println(" 1 - paper width=.0001, height=1"); + System.out.println(" 2 - paper width=-1, height=1"); + System.out.println("A passing test should catch a PrinterException"); + System.out.println("and should display \"Print error: (exception msg)\"."); + System.out.println("---------------------------------------------------\n"); + PrinterJob job = PrinterJob.getPrinterJob(); + PageFormat format = job.defaultPage(); + Paper paper = format.getPaper(); - double w = 1, h = .0001; // Generates ArithmeticException: / by zero. - if(args.length > 0 && args[0].equals("1")) { - w = .0001; h = 1; } // Generates IllegalArgumentException. - else if(args.length > 0 && args[0].equals("2")) { - w = -1; h = 1; } // Generates NegativeArraySizeException. - paper.setSize(w, h); - paper.setImageableArea(0, 0, w, h); - format.setPaper(paper); - job.setPrintable( - new Printable() { - public int print(Graphics g, PageFormat page_format, int page) { - return NO_SUCH_PAGE; - } - }, format); + double w = 1, h = .0001; // Generates ArithmeticException: / by zero. + if (args.length > 0 && args[0].equals("1")) { + w = .0001; h = 1; + } // Generates IllegalArgumentException. + else if (args.length > 0 && args[0].equals("2")) { + w = -1; h = 1; + } // Generates NegativeArraySizeException. + paper.setSize(w, h); + paper.setImageableArea(0, 0, w, h); + format.setPaper(paper); + job.setPrintable( + new Printable() { + public int print(Graphics g, PageFormat page_format, int page) { + return NO_SUCH_PAGE; + } + }, format); - try { - job.print(); } - catch(PrinterException e) { - System.err.println("Print error:\n" + e.getMessage()); // Passing test! - } + try { + job.print(); + } catch (PrinterException e) { + System.err.println("Print error:\n" + e.getMessage()); // Passing test! } } +} diff --git a/test/jdk/java/awt/print/PageFormat/ValidateCustom.java b/test/jdk/java/awt/print/PageFormat/ValidateCustom.java index e15eebf9bc42d..2521609ee4faf 100644 --- a/test/jdk/java/awt/print/PageFormat/ValidateCustom.java +++ b/test/jdk/java/awt/print/PageFormat/ValidateCustom.java @@ -24,7 +24,7 @@ /* * @test * @bug 4414987 - * @author Jennifer Godinez + * @key printer * @summary Displays width & height of validated custom paper size * @run main/manual ValidateCustom */ diff --git a/test/jdk/java/awt/print/PageFormat/WrongPaperForBookPrintingTest.java b/test/jdk/java/awt/print/PageFormat/WrongPaperForBookPrintingTest.java index 5c4410e0ee440..1015fab4ed6ec 100644 --- a/test/jdk/java/awt/print/PageFormat/WrongPaperForBookPrintingTest.java +++ b/test/jdk/java/awt/print/PageFormat/WrongPaperForBookPrintingTest.java @@ -22,7 +22,7 @@ */ /* @test - @key headful + @key printer @bug 8201818 @summary Printing attributes break page size set via "java.awt.print.Book" object diff --git a/test/jdk/java/awt/print/PageFormat/WrongPaperPrintingTest.java b/test/jdk/java/awt/print/PageFormat/WrongPaperPrintingTest.java index 77b46031487d4..d96d4a4c33626 100644 --- a/test/jdk/java/awt/print/PageFormat/WrongPaperPrintingTest.java +++ b/test/jdk/java/awt/print/PageFormat/WrongPaperPrintingTest.java @@ -23,6 +23,7 @@ /* @test @bug 8167102 8181659 + @key printer @summary PrintRequestAttributeSet breaks page size set using PageFormat @run main/manual WrongPaperPrintingTest */ diff --git a/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorShapeTest.java b/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorShapeTest.java index 3b90d1e2068f3..9a626eae36474 100644 --- a/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorShapeTest.java +++ b/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorShapeTest.java @@ -25,6 +25,7 @@ /** * @test * @bug 8262470 + * @key printer * @requires (os.family == "windows") * @summary Check thay shapes are properly painted with the precision scale factor * @run main/othervm/manual PathPrecisionScaleFactorShapeTest diff --git a/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorTextTest.java b/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorTextTest.java index 9b20ab4748a22..f959ec9ca7c58 100644 --- a/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorTextTest.java +++ b/test/jdk/java/awt/print/PathPrecisionScaleFactor/PathPrecisionScaleFactorTextTest.java @@ -25,6 +25,7 @@ /** * @test * @bug 8262470 + * @key printer * @requires (os.family == "windows") * @summary Check that a GlyphVector outline is printed with good quility on low dpi printers * @run main/othervm/manual PathPrecisionScaleFactorTextTest diff --git a/test/jdk/java/awt/print/PrinterJob/BannerTest.java b/test/jdk/java/awt/print/PrinterJob/BannerTest.java index e061e24040064..e98bfaaf8d669 100644 --- a/test/jdk/java/awt/print/PrinterJob/BannerTest.java +++ b/test/jdk/java/awt/print/PrinterJob/BannerTest.java @@ -23,6 +23,7 @@ /* * @test * @bug 6575247 8170579 + * @key printer * @summary Verifies if Banner page is printed * @requires os.family == "solaris" * @run main/manual BannerTest diff --git a/test/jdk/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java b/test/jdk/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java index 0ad27cb5a53ea..20197224f56d5 100644 --- a/test/jdk/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java +++ b/test/jdk/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java @@ -25,7 +25,7 @@ * @test * @bug 4245280 * @summary PrinterJob not cancelled when PrinterJob.cancel() is used - * @author prr + * @key printer * @run main/manual PrinterJobCancel */ diff --git a/test/jdk/java/awt/print/PrinterJob/Collate2DPrintingTest.java b/test/jdk/java/awt/print/PrinterJob/Collate2DPrintingTest.java index 8d08da6a4a595..754030c4e9e6c 100644 --- a/test/jdk/java/awt/print/PrinterJob/Collate2DPrintingTest.java +++ b/test/jdk/java/awt/print/PrinterJob/Collate2DPrintingTest.java @@ -25,6 +25,7 @@ * @test * @bug 6362683 8012381 * @summary Collation should work. + * @key printer * @run main/manual Collate2DPrintingTest */ import java.awt.*; diff --git a/test/jdk/java/awt/print/PrinterJob/CompareImageable.java b/test/jdk/java/awt/print/PrinterJob/CompareImageable.java index 79a78c3b5a880..aec27d09d931a 100644 --- a/test/jdk/java/awt/print/PrinterJob/CompareImageable.java +++ b/test/jdk/java/awt/print/PrinterJob/CompareImageable.java @@ -24,6 +24,7 @@ /* @test @bug 4748055 + @key printer @summary PASS if the values are same in both cases (2 and 3) below. @run main/manual CompareImageable */ diff --git a/test/jdk/java/awt/print/PrinterJob/CustomFont/CustomFont.java b/test/jdk/java/awt/print/PrinterJob/CustomFont/CustomFont.java index 2b6c91fc0532b..e12b7fe16890c 100644 --- a/test/jdk/java/awt/print/PrinterJob/CustomFont/CustomFont.java +++ b/test/jdk/java/awt/print/PrinterJob/CustomFont/CustomFont.java @@ -25,7 +25,7 @@ @test @bug 4386025 8231243 @summary fonts not in win32 font directory print incorrectly. - @author prr: area=PrinterJob + @key printer @run main/manual CustomFont */ import java.io.*; diff --git a/test/jdk/java/awt/print/PrinterJob/CustomPrintService/PrintDialog.java b/test/jdk/java/awt/print/PrinterJob/CustomPrintService/PrintDialog.java index d18ee86878de6..cf37cf0cfa758 100644 --- a/test/jdk/java/awt/print/PrinterJob/CustomPrintService/PrintDialog.java +++ b/test/jdk/java/awt/print/PrinterJob/CustomPrintService/PrintDialog.java @@ -30,7 +30,6 @@ * @bug 6870661 * @summary Verify that no native dialog is opened for a custom PrintService * @run main/manual PrintDialog - * @author reinhapa */ public class PrintDialog { diff --git a/test/jdk/java/awt/print/PrinterJob/CustomPrintService/SetPrintServiceTest.java b/test/jdk/java/awt/print/PrinterJob/CustomPrintService/SetPrintServiceTest.java index 9c3ebe7d9217e..5a7fb526e9d6b 100644 --- a/test/jdk/java/awt/print/PrinterJob/CustomPrintService/SetPrintServiceTest.java +++ b/test/jdk/java/awt/print/PrinterJob/CustomPrintService/SetPrintServiceTest.java @@ -28,7 +28,6 @@ * @test * @bug 6870661 * @summary tests setPrintService() with a custom implementation - * @author reinhapa */ public class SetPrintServiceTest { diff --git a/test/jdk/java/awt/print/PrinterJob/DeviceScale.java b/test/jdk/java/awt/print/PrinterJob/DeviceScale.java index 7320eda70c911..008b5d2f0fa9f 100644 --- a/test/jdk/java/awt/print/PrinterJob/DeviceScale.java +++ b/test/jdk/java/awt/print/PrinterJob/DeviceScale.java @@ -21,7 +21,7 @@ * questions. */ -/* @test 1.2 02/05/15 +/* @test @bug 4810363 4924441 @key printer @run main DeviceScale diff --git a/test/jdk/java/awt/print/PrinterJob/DlgAttrsBug.java b/test/jdk/java/awt/print/PrinterJob/DlgAttrsBug.java index dc31ffda1fdf2..93fecd486a312 100644 --- a/test/jdk/java/awt/print/PrinterJob/DlgAttrsBug.java +++ b/test/jdk/java/awt/print/PrinterJob/DlgAttrsBug.java @@ -23,6 +23,7 @@ /* * @test * @bug 8061258 + * @key printer * @summary PrinterJob's native Print Dialog does not reflect * specified Copies or Page Ranges * @run main/manual DlgAttrsBug diff --git a/test/jdk/java/awt/print/PrinterJob/DrawImage.java b/test/jdk/java/awt/print/PrinterJob/DrawImage.java index 977dc946a9248..2fcc710719cd3 100644 --- a/test/jdk/java/awt/print/PrinterJob/DrawImage.java +++ b/test/jdk/java/awt/print/PrinterJob/DrawImage.java @@ -24,8 +24,8 @@ /** * @test * @bug 4329866 + * @key printer * @summary Confirm that no printing exception is generated. - * @author jgodinez * @run main/manual DrawImage */ diff --git a/test/jdk/java/awt/print/PrinterJob/DrawStringMethods.java b/test/jdk/java/awt/print/PrinterJob/DrawStringMethods.java index 37bb3e045a558..f5417ebae4d17 100644 --- a/test/jdk/java/awt/print/PrinterJob/DrawStringMethods.java +++ b/test/jdk/java/awt/print/PrinterJob/DrawStringMethods.java @@ -24,6 +24,7 @@ /** * @test * @bug 4185019 + * @key printer * @summary Confirm that all of the drawString methods on Graphics2D * work for printer graphics objects. * @run main/manual DrawStringMethods diff --git a/test/jdk/java/awt/print/PrinterJob/EmptyFill.java b/test/jdk/java/awt/print/PrinterJob/EmptyFill.java index ddf8ebb0150c9..3da1689bc3d2d 100644 --- a/test/jdk/java/awt/print/PrinterJob/EmptyFill.java +++ b/test/jdk/java/awt/print/PrinterJob/EmptyFill.java @@ -66,11 +66,11 @@ public static void main(String arg[]) throws Exception { } ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); StreamPrintService svc = spfs[0].getPrintService(baos); - - PrinterJob pj = PrinterJob.getPrinterJob(); if (svc == null) { - return; + throw new RuntimeException("Could not create postscript stream"); } + + PrinterJob pj = PrinterJob.getPrinterJob(); pj.setPrintService(svc); pj.setPrintable(new EmptyFill()); pj.print(); diff --git a/test/jdk/java/awt/print/PrinterJob/GetMediasTest.java b/test/jdk/java/awt/print/PrinterJob/GetMediasTest.java index c70d377c6ef2e..f4ff1643b0018 100644 --- a/test/jdk/java/awt/print/PrinterJob/GetMediasTest.java +++ b/test/jdk/java/awt/print/PrinterJob/GetMediasTest.java @@ -24,6 +24,7 @@ /** * @test * @bug 6653384 + * @key printer * @summary No exception should be thrown. * @run main GetMediasTest */ diff --git a/test/jdk/java/awt/print/PrinterJob/ImagePrinting/ImageTypes.java b/test/jdk/java/awt/print/PrinterJob/ImagePrinting/ImageTypes.java index c33dc0f6718c5..af655b75d3644 100644 --- a/test/jdk/java/awt/print/PrinterJob/ImagePrinting/ImageTypes.java +++ b/test/jdk/java/awt/print/PrinterJob/ImagePrinting/ImageTypes.java @@ -25,7 +25,7 @@ * @test * @bug 4521945 7006865 * @summary Test printing images of different types. - * @author prr + * @key printer * @run main/manual ImageTypes */ diff --git a/test/jdk/java/awt/print/PrinterJob/ImagePrinting/PrintARGBImage.java b/test/jdk/java/awt/print/PrinterJob/ImagePrinting/PrintARGBImage.java index 4bef1cce0f5af..e16dc17c24f7d 100644 --- a/test/jdk/java/awt/print/PrinterJob/ImagePrinting/PrintARGBImage.java +++ b/test/jdk/java/awt/print/PrinterJob/ImagePrinting/PrintARGBImage.java @@ -34,6 +34,7 @@ /* * @test * @bug 6581756 + * @key printer * @library ../../../regtesthelpers * @build PassFailJFrame * @summary Test printing of images which need to have src area clipped diff --git a/test/jdk/java/awt/print/PrinterJob/InitToBlack.java b/test/jdk/java/awt/print/PrinterJob/InitToBlack.java index a4d7dd0a9589c..7ca5846fd4722 100644 --- a/test/jdk/java/awt/print/PrinterJob/InitToBlack.java +++ b/test/jdk/java/awt/print/PrinterJob/InitToBlack.java @@ -24,6 +24,7 @@ /** * @test * @bug 4184565 + * @key printer * @summary Confirm that the default foreground color on a printer * graphics object is black so that rendering will appear * without having to execute setColor first. diff --git a/test/jdk/java/awt/print/PrinterJob/InvalidPage.java b/test/jdk/java/awt/print/PrinterJob/InvalidPage.java index f84bd2c0d7858..fd0130320523a 100644 --- a/test/jdk/java/awt/print/PrinterJob/InvalidPage.java +++ b/test/jdk/java/awt/print/PrinterJob/InvalidPage.java @@ -25,7 +25,7 @@ * @test InvalidPage.java * @bug 4671634 6506286 * @summary Invalid page format can crash win32 JRE - * @author prr + * @key printer * @run main/manual InvalidPage */ diff --git a/test/jdk/java/awt/print/PrinterJob/JobName/PrinterJobName.java b/test/jdk/java/awt/print/PrinterJob/JobName/PrinterJobName.java index a6c6544591258..f1b99487788c4 100644 --- a/test/jdk/java/awt/print/PrinterJob/JobName/PrinterJobName.java +++ b/test/jdk/java/awt/print/PrinterJob/JobName/PrinterJobName.java @@ -25,7 +25,7 @@ * @test * @bug 4205601 * @summary setJobName should be used by PrinterJob - * @author prr + * @key printer * @run main/manual PrinterJobName */ diff --git a/test/jdk/java/awt/print/PrinterJob/LandscapeStackOverflow.java b/test/jdk/java/awt/print/PrinterJob/LandscapeStackOverflow.java index fc65dc9ddab1e..398939d125d91 100644 --- a/test/jdk/java/awt/print/PrinterJob/LandscapeStackOverflow.java +++ b/test/jdk/java/awt/print/PrinterJob/LandscapeStackOverflow.java @@ -22,7 +22,7 @@ */ /* * @test - * @key headful printer + * @key printer * @bug 6842011 8158758 * @summary Test if StackOverflowError occurs during printing landscape with * scale and transform. diff --git a/test/jdk/java/awt/print/PrinterJob/Legal/PrintTest.java b/test/jdk/java/awt/print/PrinterJob/Legal/PrintTest.java index b4c708e27857a..f5ee1c4d65a79 100644 --- a/test/jdk/java/awt/print/PrinterJob/Legal/PrintTest.java +++ b/test/jdk/java/awt/print/PrinterJob/Legal/PrintTest.java @@ -24,6 +24,7 @@ /** * @test * @bug 4886069 8023045 + * @key printer * @summary Confirm that printer recognizes the Legal selection either by * prompting the user to put Legal paper or automatically selecting * the tray containing Legal Paper. The printout image should not diff --git a/test/jdk/java/awt/print/PrinterJob/LinearGradientPrintingTest.java b/test/jdk/java/awt/print/PrinterJob/LinearGradientPrintingTest.java index ab1ab17aa7fea..456b77614a3e2 100644 --- a/test/jdk/java/awt/print/PrinterJob/LinearGradientPrintingTest.java +++ b/test/jdk/java/awt/print/PrinterJob/LinearGradientPrintingTest.java @@ -24,6 +24,7 @@ * @test * @bug 8162796 * @summary Verifies if LinearGradientPaint is printed in osx + * @key printer * @run main/manual LinearGradientPrintingTest */ import java.awt.BorderLayout; diff --git a/test/jdk/java/awt/print/PrinterJob/MultiMonPrintDlgTest.java b/test/jdk/java/awt/print/PrinterJob/MultiMonPrintDlgTest.java index 4086f663a5c86..9da6e64fedcf9 100644 --- a/test/jdk/java/awt/print/PrinterJob/MultiMonPrintDlgTest.java +++ b/test/jdk/java/awt/print/PrinterJob/MultiMonPrintDlgTest.java @@ -37,6 +37,7 @@ /** * @test * @bug 8138749 + * @key printer multimon * @summary PrinterJob.printDialog() does not support multi-mon, * always displayed on primary * @run main/manual MultiMonPrintDlgTest diff --git a/test/jdk/java/awt/print/PrinterJob/MultiThread/MultiThreadTest.java b/test/jdk/java/awt/print/PrinterJob/MultiThread/MultiThreadTest.java index 8282a052ee18b..609cc6f988b60 100644 --- a/test/jdk/java/awt/print/PrinterJob/MultiThread/MultiThreadTest.java +++ b/test/jdk/java/awt/print/PrinterJob/MultiThread/MultiThreadTest.java @@ -24,6 +24,7 @@ /** * @test * @bug 4922036 + * @key printer * @summary Confirm that no Exception is thrown and 2 identical output is produced. * @run main/manual MultiThreadTest */ diff --git a/test/jdk/java/awt/print/PrinterJob/NumCopies.java b/test/jdk/java/awt/print/PrinterJob/NumCopies.java index c851e2403d0f9..119bcab6f7a1a 100644 --- a/test/jdk/java/awt/print/PrinterJob/NumCopies.java +++ b/test/jdk/java/awt/print/PrinterJob/NumCopies.java @@ -25,7 +25,7 @@ * @test * @bug 4258003 * @summary Checks the right number of copies are printed - * @author prr + * @key printer * @run main/manual NumCopies */ diff --git a/test/jdk/java/awt/print/PrinterJob/PageDialogMarginTest.java b/test/jdk/java/awt/print/PrinterJob/PageDialogMarginTest.java index de47e70f63920..1931de988d14e 100644 --- a/test/jdk/java/awt/print/PrinterJob/PageDialogMarginTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PageDialogMarginTest.java @@ -24,6 +24,7 @@ /* * @test * @bug 6801613 + * @key printer * @summary Verifies if cross-platform pageDialog and printDialog top margin * entry is working * @run main/manual PageDialogMarginTest diff --git a/test/jdk/java/awt/print/PrinterJob/PageDialogMarginValidation.java b/test/jdk/java/awt/print/PrinterJob/PageDialogMarginValidation.java index d71f84f18793c..674266e7fc8ec 100644 --- a/test/jdk/java/awt/print/PrinterJob/PageDialogMarginValidation.java +++ b/test/jdk/java/awt/print/PrinterJob/PageDialogMarginValidation.java @@ -23,6 +23,7 @@ /* * @test * @bug 6509729 + * @key printer * @summary Verifies pageDialog margin validation is correct * @run main/manual PageDialogMarginValidation */ diff --git a/test/jdk/java/awt/print/PrinterJob/PageDialogTest.java b/test/jdk/java/awt/print/PrinterJob/PageDialogTest.java index 8a8f9839ddf39..eea118733de4f 100644 --- a/test/jdk/java/awt/print/PrinterJob/PageDialogTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PageDialogTest.java @@ -24,6 +24,7 @@ /* @test @bug 6302514 + @key printer @run main/manual PageDialogTest @summary A toolkit modal dialog should not be blocked by Page/Print dialog. */ diff --git a/test/jdk/java/awt/print/PrinterJob/PageDlgApp.java b/test/jdk/java/awt/print/PrinterJob/PageDlgApp.java index e07e8ffd6cfc0..96d5f64486def 100644 --- a/test/jdk/java/awt/print/PrinterJob/PageDlgApp.java +++ b/test/jdk/java/awt/print/PrinterJob/PageDlgApp.java @@ -31,6 +31,7 @@ /** * @test * @bug 8067059 + * @key printer * @run main/manual PageDlgApp * @summary Test if cancelling dialog returns null when * PrinterJob.pageDialog() with DialogSelectionType.NATIVE is called diff --git a/test/jdk/java/awt/print/PrinterJob/PageDlgPrnButton.java b/test/jdk/java/awt/print/PrinterJob/PageDlgPrnButton.java index 45a1c71a44a67..6c000dc7f5fb6 100644 --- a/test/jdk/java/awt/print/PrinterJob/PageDlgPrnButton.java +++ b/test/jdk/java/awt/print/PrinterJob/PageDlgPrnButton.java @@ -24,6 +24,7 @@ /** * @test * @bug 4956397 + * @key printer * @run main/manual PageDlgPrnButton */ diff --git a/test/jdk/java/awt/print/PrinterJob/PageDlgStackOverflowTest.java b/test/jdk/java/awt/print/PrinterJob/PageDlgStackOverflowTest.java index ffe695d6f487e..048b81f273d63 100644 --- a/test/jdk/java/awt/print/PrinterJob/PageDlgStackOverflowTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PageDlgStackOverflowTest.java @@ -28,6 +28,7 @@ /** * @test * @bug 8039412 + * @key printer * @run main/manual PageDlgStackOverflowTest * @summary Calling pageDialog() after printDialog with * DialogTypeSelection.NATIVE should not result in StackOverflowError diff --git a/test/jdk/java/awt/print/PrinterJob/PageFormatChange.java b/test/jdk/java/awt/print/PrinterJob/PageFormatChange.java index 2515e11e9ecbb..10aaaea89f1ff 100644 --- a/test/jdk/java/awt/print/PrinterJob/PageFormatChange.java +++ b/test/jdk/java/awt/print/PrinterJob/PageFormatChange.java @@ -24,6 +24,7 @@ /** * @test * @bug 6359283 + * @key printer * @summary pagedialog needs to update based on change of printer. * @run main/manual PageFormatChange */ diff --git a/test/jdk/java/awt/print/PrinterJob/PageRanges.java b/test/jdk/java/awt/print/PrinterJob/PageRanges.java index 9bfd79eacce49..accde99ae9565 100644 --- a/test/jdk/java/awt/print/PrinterJob/PageRanges.java +++ b/test/jdk/java/awt/print/PrinterJob/PageRanges.java @@ -24,6 +24,7 @@ /** * @test * @bug 6575331 + * @key printer * @summary The specified pages should be printed. * @run main/manual=yesno PageRanges */ diff --git a/test/jdk/java/awt/print/PrinterJob/PolylinePrintingTest.java b/test/jdk/java/awt/print/PrinterJob/PolylinePrintingTest.java index 14a04d5542f49..7d8568c01f98c 100644 --- a/test/jdk/java/awt/print/PrinterJob/PolylinePrintingTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PolylinePrintingTest.java @@ -23,6 +23,7 @@ /** * @bug 8041902 + * @key printer * @summary Test printing of wide poly lines. * @run main/manual=yesno PolylinePrintingTest */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintAWTImage.java b/test/jdk/java/awt/print/PrinterJob/PrintAWTImage.java index 2612ca6bdadd4..2397931b4fc9f 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintAWTImage.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintAWTImage.java @@ -23,6 +23,7 @@ /** * @test * @bug 4257262 6708509 + * @key printer * @summary Image should be sent to printer. * @run main/manual PrintAWTImage */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintAllFonts.java b/test/jdk/java/awt/print/PrinterJob/PrintAllFonts.java index 59ebf21ee5bac..0c9f8afb7696c 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintAllFonts.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintAllFonts.java @@ -23,9 +23,11 @@ /** * + * test * @bug 4884389 7183516 + * @key printer * @summary Font specified with face name loses style on printing - * @run main/manual PrintRotatedText + * @run main/manual PrintAllFonts */ import java.awt.*; diff --git a/test/jdk/java/awt/print/PrinterJob/PrintAttributeUpdateTest.java b/test/jdk/java/awt/print/PrinterJob/PrintAttributeUpdateTest.java index 1b69e0b8b365b..fd92f5deda89b 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintAttributeUpdateTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintAttributeUpdateTest.java @@ -24,6 +24,7 @@ /* @test @bug 8042713 8170578 + @key printer @summary Print Dialog does not update attribute set with page range @run main/manual PrintAttributeUpdateTest */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintBadImage.java b/test/jdk/java/awt/print/PrinterJob/PrintBadImage.java index ad3b3fd5d83cb..48e4503db7041 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintBadImage.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintBadImage.java @@ -25,7 +25,7 @@ * @test * @bug 4398853 * @summary Printing shouldn't hang on bad images - * @author prr + * @key printer * @run main/manual PrintBadImage */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintCompoundString.java b/test/jdk/java/awt/print/PrinterJob/PrintCompoundString.java index 82560d8964bf1..95cebd9976565 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintCompoundString.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintCompoundString.java @@ -25,7 +25,7 @@ * @test * @bug 4396835 * @summary Compound font string not printing. - * @author prr + * @key printer * @run main/manual PrintCompoundString */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintDialog.java b/test/jdk/java/awt/print/PrinterJob/PrintDialog.java index 9ab5d63f641c9..fa9569e1aa74e 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintDialog.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintDialog.java @@ -25,7 +25,7 @@ @test PrintDialog.java @bug 4257903 @summary Confirm that the you see the print dialog. - @author prr: area=PrinterJob + @key printer @run main/manual PrintDialog */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintDialogCancel.java b/test/jdk/java/awt/print/PrinterJob/PrintDialogCancel.java index 4fe3d29fe5bcc..b2d3d3a223075 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintDialogCancel.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintDialogCancel.java @@ -25,7 +25,7 @@ @test @bug 4398231 @summary Confirm that the print dialog returns false when cancelled. - @author prr: area=PrinterJob + @key printer @run main/manual PrintDialogCancel */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintDlgPageable.java b/test/jdk/java/awt/print/PrinterJob/PrintDlgPageable.java index f6a74f9f965cb..6d1d8bcf6dfb6 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintDlgPageable.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintDlgPageable.java @@ -23,6 +23,7 @@ /* * @test * @bug 4885375 + * @key printer * @summary Verifies if PageRanges To Field is populated based on Pageable * for COMMON print dialog * @run main/manual PrintDlgPageable diff --git a/test/jdk/java/awt/print/PrinterJob/PrintDlgSelectionAttribTest.java b/test/jdk/java/awt/print/PrinterJob/PrintDlgSelectionAttribTest.java index 9858547862667..65adee3f4f9f9 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintDlgSelectionAttribTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintDlgSelectionAttribTest.java @@ -23,6 +23,7 @@ /* * @test * @bug 6529030 8159134 + * @key printer * @summary Verifies if Java Printing: Selection radiobutton gets enabled. * @requires (os.family == "windows") * @run main/manual PrintDlgSelectionAttribTest diff --git a/test/jdk/java/awt/print/PrinterJob/PrintFontStyle.java b/test/jdk/java/awt/print/PrinterJob/PrintFontStyle.java index 3d67246eac23d..f9997d443a2da 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintFontStyle.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintFontStyle.java @@ -21,6 +21,13 @@ * questions. */ +/* + * Not enabled as a test. Needs some work. + * test + * @key printer + * @run main/manual PrintFontStyle + */ + import java.awt.*; import java.awt.print.*; import java.awt.GraphicsEnvironment; diff --git a/test/jdk/java/awt/print/PrinterJob/PrintGlyphVectorTest.java b/test/jdk/java/awt/print/PrinterJob/PrintGlyphVectorTest.java index bd921b5162df6..696cf1b74454e 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintGlyphVectorTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintGlyphVectorTest.java @@ -24,6 +24,7 @@ /* * @test * @bug 8029204 + * @key printer * @library ../../regtesthelpers * @build PassFailJFrame * @summary Tests GlyphVector is printed in the correct location diff --git a/test/jdk/java/awt/print/PrinterJob/PrintImage.java b/test/jdk/java/awt/print/PrinterJob/PrintImage.java index 7f632bfa94ccb..7eed8c2c276f8 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintImage.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintImage.java @@ -25,7 +25,7 @@ * @test %I %W * @bug 4298489 * @summary Confirm that output is same as screen. - * @author jgodinez + * @key printer * @run main/manual PrintImage */ import java.awt.*; diff --git a/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java b/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java index f6221aa57064b..5ffb34540ced4 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintLatinCJKTest.java @@ -27,6 +27,7 @@ * @library ../../regtesthelpers * @build PassFailJFrame * @summary JDK7 Printing: CJK and Latin Text in string overlap + * @key printer * @run main/manual PrintLatinCJKTest */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintNullString.java b/test/jdk/java/awt/print/PrinterJob/PrintNullString.java index 7e3101c6b30e1..b46db6a1447ba 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintNullString.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintNullString.java @@ -25,7 +25,7 @@ * @test * @bug 4223328 * @summary Printer graphics must behave the same as screen graphics - * @author prr + * @key printer * @run main/manual PrintNullString */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintParenString.java b/test/jdk/java/awt/print/PrinterJob/PrintParenString.java index dc6d544d12645..f3ed7ec1f3ea4 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintParenString.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintParenString.java @@ -25,7 +25,7 @@ * @test * @bug 4399442 * @summary Brackets should be quoted in Postscript output - * @author prr + * @key printer * @run main/manual PrintParenString */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintRotatedText.java b/test/jdk/java/awt/print/PrinterJob/PrintRotatedText.java index 5f5a6fa69d65e..deabc0e69991c 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintRotatedText.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintRotatedText.java @@ -26,7 +26,7 @@ * @bug 4271596 * @bug 4460699 * @summary Rotated text printing - * @author prr + * @key printer * @run main/manual PrintRotatedText */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintTest.java b/test/jdk/java/awt/print/PrinterJob/PrintTest.java index 3c3febe414c83..321293877aba5 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintTest.java @@ -23,6 +23,7 @@ /* * @test * @bug 8151590 + * @key printer * @summary All radio button should be selected when we call * setDefaultSelection(JobAttributes.DefaultSelectionType.ALL); * @run main/manual PrintTest diff --git a/test/jdk/java/awt/print/PrinterJob/PrintTestLexmarkIQ.java b/test/jdk/java/awt/print/PrinterJob/PrintTestLexmarkIQ.java index cb82100efb00e..a5c7110c5d5a1 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintTestLexmarkIQ.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintTestLexmarkIQ.java @@ -25,6 +25,7 @@ * @bug 6966350 8160882 * @summary Verifies if Empty pages are printed on Lexmark E352dn PS3 * with "1200 IQ" setting + * @key printer * @run main/manual PrintTestLexmarkIQ */ import java.awt.BorderLayout; diff --git a/test/jdk/java/awt/print/PrinterJob/PrintTextLayout.java b/test/jdk/java/awt/print/PrinterJob/PrintTextLayout.java index 2dfd10ccd3202..9560c6b86ff73 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintTextLayout.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintTextLayout.java @@ -25,7 +25,7 @@ * @test * @bug 4480930 * @summary TextLayout prints as filled shapes - * @author prr + * @key printer * @run main/manual PrintTextLayout */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintTextTest.java b/test/jdk/java/awt/print/PrinterJob/PrintTextTest.java index c7d9c984b64c5..95bf177aa2f11 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintTextTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintTextTest.java @@ -24,6 +24,7 @@ /** * @test * @bug 6425068 7157659 8132890 + * @key printer * @summary Confirm that text prints where we expect to the length we expect. * @run main/manual=yesno PrintTextTest */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintTranslatedFont.java b/test/jdk/java/awt/print/PrinterJob/PrintTranslatedFont.java index fefa737990bac..51ff6ce57a7dd 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintTranslatedFont.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintTranslatedFont.java @@ -24,8 +24,8 @@ /** * @test * @bug 6359734 + * @key printer * @summary Test that fonts with a translation print where they should. - * @author prr * @run main/manual PrintTranslatedFont */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrintVolatileImage.java b/test/jdk/java/awt/print/PrinterJob/PrintVolatileImage.java index 82a7c9ed83d6e..d594b5a31dd8f 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintVolatileImage.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintVolatileImage.java @@ -25,7 +25,7 @@ * @test * @bug 4511023 * @summary Image should be sent to printer, no exceptions thrown - * @author prr + * @key printer * @run main/manual PrintVolatileImage */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrinterDevice.java b/test/jdk/java/awt/print/PrinterJob/PrinterDevice.java index 418076105881e..8e1b30aaf94c9 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrinterDevice.java +++ b/test/jdk/java/awt/print/PrinterJob/PrinterDevice.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,22 +23,34 @@ /* * - * @bug 4276227 + * @test + * @bug 4276227 8320443 + * @key printer * @summary Checks that the PrinterGraphics is for a Printer GraphicsDevice. * Test doesn't run unless there's a printer on the system. - * @author prr * @run main/othervm PrinterDevice */ -import java.awt.*; -import java.awt.geom.*; -import java.awt.print.*; -import java.io.*; -import javax.print.attribute.*; -import javax.print.attribute.standard.*; +import java.io.File; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.Destination; +import javax.print.attribute.standard.OrientationRequested; public class PrinterDevice implements Printable { + static volatile boolean failed = false; + public static void main(String args[]) throws PrinterException { System.setProperty("java.awt.headless", "true"); @@ -54,39 +66,52 @@ public static void main(String args[]) throws PrinterException { aset.add(OrientationRequested.LANDSCAPE); pj.setPrintable(new PrinterDevice()); pj.print(aset); + if (failed) { + throw new RuntimeException("Test failed but no exception propagated."); + } } public int print(Graphics g, PageFormat pf, int pageIndex) { - if (pageIndex > 0 ) { - return Printable.NO_SUCH_PAGE; - } - - /* Make sure calls to get DeviceConfig, its transforms, - * etc all work without exceptions and as expected */ - Graphics2D g2 = (Graphics2D)g; - GraphicsConfiguration gConfig = g2.getDeviceConfiguration(); - AffineTransform dt = gConfig.getDefaultTransform(); - AffineTransform nt = gConfig.getNormalizingTransform(); - AffineTransform gt = g2.getTransform(); + if (pageIndex > 0) { + return Printable.NO_SUCH_PAGE; + } - System.out.println("Graphics2D transform = " + gt); - System.out.println("Default transform = " + dt); - System.out.println("Normalizing transform = " + nt); + Graphics2D g2 = (Graphics2D)g; + GraphicsConfiguration gConfig = g2.getDeviceConfiguration(); + AffineTransform nt = null; + try { + /* Make sure calls to get DeviceConfig, its transforms, + * etc all work without exceptions and as expected */ + System.out.println("GraphicsConfig="+gConfig); + AffineTransform dt = gConfig.getDefaultTransform(); + System.out.println("Default transform = " + dt); + nt = gConfig.getNormalizingTransform(); + System.out.println("Normalizing transform = " + nt); + AffineTransform gt = g2.getTransform(); + System.out.println("Graphics2D transform = " + gt); + } catch (Exception e) { + failed = true; + System.err.println("Unexpected exception getting transform."); + e.printStackTrace(); + throw e; + } - Rectangle bounds = gConfig.getBounds(); - System.out.println("Bounds = " + bounds); - if (!nt.isIdentity()) { - throw new RuntimeException("Expected Identity transdform"); - } + Rectangle bounds = gConfig.getBounds(); + System.out.println("Bounds = " + bounds); + if (!nt.isIdentity()) { + failed = true; + throw new RuntimeException("Expected Identity transform"); + } - /* Make sure that device really is TYPE_PRINTER */ - GraphicsDevice gd = gConfig.getDevice(); - System.out.println("Printer Device ID = " + gd.getIDstring()); - if (!(gd.getType() == GraphicsDevice.TYPE_PRINTER)) { - throw new RuntimeException("Expected printer device"); - } - System.out.println(" *** "); - System.out.println(""); - return Printable.PAGE_EXISTS; + /* Make sure that device really is TYPE_PRINTER */ + GraphicsDevice gd = gConfig.getDevice(); + System.out.println("Printer Device ID = " + gd.getIDstring()); + if (gd.getType() != GraphicsDevice.TYPE_PRINTER) { + failed = true; + throw new RuntimeException("Expected printer device"); + } + System.out.println(" *** "); + System.out.println(""); + return Printable.PAGE_EXISTS; } } diff --git a/test/jdk/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.html b/test/jdk/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.html index 3b6b87f6b03e9..9cfb86bd47976 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.html +++ b/test/jdk/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.html @@ -25,8 +25,8 @@ diff --git a/test/jdk/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.java b/test/jdk/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.java index 2178697b1709b..bb40832e36fc8 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.java +++ b/test/jdk/java/awt/print/PrinterJob/PrinterDialogsModalityTest/PrinterDialogsModalityTest.java @@ -24,8 +24,8 @@ /* test @bug 4784285 4785920 + @key printer @summary check whether Print- and Page- dialogs are modal and correct window activated after their closing - @author son@sparc.spb.su: area=PrinterJob.modality @run applet/manual=yesno PrinterDialogsModalityTest.html */ diff --git a/test/jdk/java/awt/print/PrinterJob/PrinterJobDialogBugDemo.java b/test/jdk/java/awt/print/PrinterJob/PrinterJobDialogBugDemo.java index d06d08dcbe3be..d7a18300bd7c9 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrinterJobDialogBugDemo.java +++ b/test/jdk/java/awt/print/PrinterJob/PrinterJobDialogBugDemo.java @@ -24,6 +24,7 @@ /** * @test * @bug 4775862 + * @key printer * @run main/manual PrinterJobDialogBugDemo */ import java.awt.BorderLayout; diff --git a/test/jdk/java/awt/print/PrinterJob/RadialGradientPrintingTest.java b/test/jdk/java/awt/print/PrinterJob/RadialGradientPrintingTest.java index 61c9faeda247b..8cd538f1d6264 100644 --- a/test/jdk/java/awt/print/PrinterJob/RadialGradientPrintingTest.java +++ b/test/jdk/java/awt/print/PrinterJob/RadialGradientPrintingTest.java @@ -23,6 +23,7 @@ /* * @test * @bug 8162796 + * @key printer * @summary Verifies if RadialGradientPaint is printed in osx * @run main/manual RadialGradientPrintingTest */ diff --git a/test/jdk/java/awt/print/PrinterJob/RemoveListener.java b/test/jdk/java/awt/print/PrinterJob/RemoveListener.java index 2a467a438a3cf..0818cd7e7f4c8 100644 --- a/test/jdk/java/awt/print/PrinterJob/RemoveListener.java +++ b/test/jdk/java/awt/print/PrinterJob/RemoveListener.java @@ -22,8 +22,9 @@ */ /* - * @test 1.1 01/05/17 + * @test * @bug 4459889 + * @key printer * @summary No NullPointerException should occur. * @run main RemoveListener */ diff --git a/test/jdk/java/awt/print/PrinterJob/SameService.java b/test/jdk/java/awt/print/PrinterJob/SameService.java index 4073b55fb9241..611cea9ecdb75 100644 --- a/test/jdk/java/awt/print/PrinterJob/SameService.java +++ b/test/jdk/java/awt/print/PrinterJob/SameService.java @@ -24,6 +24,7 @@ /** * @test * @bug 6446094 + * @key printer * @summary Don't re-create print services. * @run main SameService */ diff --git a/test/jdk/java/awt/print/PrinterJob/ScaledText/ScaledText.java b/test/jdk/java/awt/print/PrinterJob/ScaledText/ScaledText.java index a440db4f2f9ba..22da443111781 100644 --- a/test/jdk/java/awt/print/PrinterJob/ScaledText/ScaledText.java +++ b/test/jdk/java/awt/print/PrinterJob/ScaledText/ScaledText.java @@ -25,7 +25,7 @@ @test @bug 4291373 @summary Printing of scaled text is wrong / disappearing - @author prr: area=PrinterJob + @key printer @run main/manual ScaledText */ import java.awt.*; diff --git a/test/jdk/java/awt/print/PrinterJob/SecurityDialogTest.java b/test/jdk/java/awt/print/PrinterJob/SecurityDialogTest.java index c5d356c6118aa..d6a9efeb97c51 100644 --- a/test/jdk/java/awt/print/PrinterJob/SecurityDialogTest.java +++ b/test/jdk/java/awt/print/PrinterJob/SecurityDialogTest.java @@ -24,6 +24,7 @@ /** * @test * @bug 4937672 5100706 6252456 + * @key printer * @run main/othervm/manual -Djava.security.manager=allow SecurityDialogTest */ diff --git a/test/jdk/java/awt/print/PrinterJob/SetCopies/Test.java b/test/jdk/java/awt/print/PrinterJob/SetCopies/Test.java index 7b8d9ce7c0094..b32d716bbee3e 100644 --- a/test/jdk/java/awt/print/PrinterJob/SetCopies/Test.java +++ b/test/jdk/java/awt/print/PrinterJob/SetCopies/Test.java @@ -24,6 +24,7 @@ /** * @test * @bug 4694495 + * @key printer * @summary Check that the dialog shows copies = 3. * @run main/manual Test */ diff --git a/test/jdk/java/awt/print/PrinterJob/SwingUIText.java b/test/jdk/java/awt/print/PrinterJob/SwingUIText.java index c1e47638023c0..5fcd5e391581a 100644 --- a/test/jdk/java/awt/print/PrinterJob/SwingUIText.java +++ b/test/jdk/java/awt/print/PrinterJob/SwingUIText.java @@ -24,6 +24,7 @@ /** * @test * @bug 6488219 6560738 7158350 8017469 + * @key printer * @summary Test that text printed in Swing UI measures and looks OK. * @run main/manual=yesno PrintTextTest */ diff --git a/test/jdk/java/awt/print/PrinterJob/TestCheckSystemDefaultBannerOption.java b/test/jdk/java/awt/print/PrinterJob/TestCheckSystemDefaultBannerOption.java index b9e18d3439383..ca07c05a6ef16 100644 --- a/test/jdk/java/awt/print/PrinterJob/TestCheckSystemDefaultBannerOption.java +++ b/test/jdk/java/awt/print/PrinterJob/TestCheckSystemDefaultBannerOption.java @@ -23,6 +23,7 @@ /* * @test * @bug 8165947 8170579 + * @key printer * @summary Verifies System default banner page option is honoured by jdk * @requires os.family == "linux" * @run main/manual TestCheckSystemDefaultBannerOption diff --git a/test/jdk/java/awt/print/PrinterJob/TestMediaTraySelection.java b/test/jdk/java/awt/print/PrinterJob/TestMediaTraySelection.java index f75336c2c0deb..6a5a91ac89e7e 100644 --- a/test/jdk/java/awt/print/PrinterJob/TestMediaTraySelection.java +++ b/test/jdk/java/awt/print/PrinterJob/TestMediaTraySelection.java @@ -24,6 +24,7 @@ * @bug 6357887 8165146 8234393 * @summary Verifies if selected printertray is used * @requires (os.family == "linux" | os.family == "mac") + * @key printer * @run main/manual TestMediaTraySelection */ diff --git a/test/jdk/java/awt/print/PrinterJob/TestPageDlgFrameAssociation.java b/test/jdk/java/awt/print/PrinterJob/TestPageDlgFrameAssociation.java index 32ee61ad1c6bb..5ca2cda4b601e 100644 --- a/test/jdk/java/awt/print/PrinterJob/TestPageDlgFrameAssociation.java +++ b/test/jdk/java/awt/print/PrinterJob/TestPageDlgFrameAssociation.java @@ -23,6 +23,7 @@ /* * @test * @bug 7064425 6948907 + * @key printer * @summary Verifies if owner Frame is associated with page dialog of PrinterJob * @run main/manual TestPageDlgFrameAssociation */ diff --git a/test/jdk/java/awt/print/PrinterJob/TestPrintDlgFrameAssociation.java b/test/jdk/java/awt/print/PrinterJob/TestPrintDlgFrameAssociation.java index d1d54307ab55b..e5d58c8baea73 100644 --- a/test/jdk/java/awt/print/PrinterJob/TestPrintDlgFrameAssociation.java +++ b/test/jdk/java/awt/print/PrinterJob/TestPrintDlgFrameAssociation.java @@ -23,6 +23,7 @@ /* * @test * @bug 7064425 6948907 + * @key printer * @summary Verifies if owner Frame is associated with print dialog of PrinterJob * @run main/manual TestPrintDlgFrameAssociation */ diff --git a/test/jdk/java/awt/print/PrinterJob/TexturePaintPrintingTest.java b/test/jdk/java/awt/print/PrinterJob/TexturePaintPrintingTest.java index 8ac81c8bbad25..3d8c6815f9552 100644 --- a/test/jdk/java/awt/print/PrinterJob/TexturePaintPrintingTest.java +++ b/test/jdk/java/awt/print/PrinterJob/TexturePaintPrintingTest.java @@ -23,6 +23,7 @@ /* * @test * @bug 8040635 + * @key printer * @summary Verifies if TexturePaint is printed in osx * @run main/manual TexturePaintPrintingTest */ diff --git a/test/jdk/java/awt/print/PrinterJob/ThinLines.java b/test/jdk/java/awt/print/PrinterJob/ThinLines.java index 2d880a4400672..f8e4e60b31969 100644 --- a/test/jdk/java/awt/print/PrinterJob/ThinLines.java +++ b/test/jdk/java/awt/print/PrinterJob/ThinLines.java @@ -25,7 +25,7 @@ @test @bug 4190081 @summary Confirm that the you see "Z" shapes on the printed page. - @author prr/rbi: area=PrinterJob + @key printer @run main/manual ThinLines */ diff --git a/test/jdk/java/awt/print/PrinterJob/ValidatePage/ValidatePage.java b/test/jdk/java/awt/print/PrinterJob/ValidatePage/ValidatePage.java index 8c9f81b11df16..ccf0bed43bbbe 100644 --- a/test/jdk/java/awt/print/PrinterJob/ValidatePage/ValidatePage.java +++ b/test/jdk/java/awt/print/PrinterJob/ValidatePage/ValidatePage.java @@ -24,8 +24,8 @@ /** * @test * @bug 4252108 6229507 + * @key printer * @summary PrinterJob.validatePage() is unimplemented. - * @author prr * @run main/manual ValidatePage */ diff --git a/test/jdk/java/awt/print/PrinterJob/XparColor.java b/test/jdk/java/awt/print/PrinterJob/XparColor.java index dd39578f2cb37..9a85a78af558a 100644 --- a/test/jdk/java/awt/print/PrinterJob/XparColor.java +++ b/test/jdk/java/awt/print/PrinterJob/XparColor.java @@ -24,6 +24,7 @@ /** * @test * @bug 4179262 + @ @key printer * @summary Confirm that transparent colors are printed correctly. The * printout should show transparent rings with increasing darkness toward * the center. diff --git a/test/jdk/java/awt/print/PrinterJob/raster/RasterTest.java b/test/jdk/java/awt/print/PrinterJob/raster/RasterTest.java index 56adc8552f7cc..297094299135e 100644 --- a/test/jdk/java/awt/print/PrinterJob/raster/RasterTest.java +++ b/test/jdk/java/awt/print/PrinterJob/raster/RasterTest.java @@ -25,7 +25,7 @@ * @test * @bug 4242639 * @summary Printing quality problem on Canon and NEC - * @author prr + * @key printer * @run main/manual RasterTest */ import java.awt.*; diff --git a/test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java b/test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java index 3bfedb463a7fb..7768c54481a76 100644 --- a/test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java +++ b/test/jdk/java/awt/print/RemotePrinterStatusRefresh/RemotePrinterStatusRefresh.java @@ -23,6 +23,7 @@ /* * @test + * @key printer * @bug 8153732 8212202 8221263 8221412 8222108 8263311 * @requires (os.family == "Windows") * @summary Windows remote printer changes do not reflect in lookupPrintServices() diff --git a/test/jdk/java/awt/print/bug8023392/bug8023392.html b/test/jdk/java/awt/print/bug8023392/bug8023392.html index c51ae001e2e1f..178fba9b230e1 100644 --- a/test/jdk/java/awt/print/bug8023392/bug8023392.html +++ b/test/jdk/java/awt/print/bug8023392/bug8023392.html @@ -26,7 +26,7 @@ @test @bug 8023392 @summary Swing text components printed with spaces between chars - @author Anton Nashatyrev + @key printer @modules java.desktop/sun.swing @run applet/manual=yesno bug8023392.html --> diff --git a/test/jdk/java/awt/print/bug8023392/bug8023392.java b/test/jdk/java/awt/print/bug8023392/bug8023392.java index 071c9021ddffb..d792562ea25a8 100644 --- a/test/jdk/java/awt/print/bug8023392/bug8023392.java +++ b/test/jdk/java/awt/print/bug8023392/bug8023392.java @@ -25,7 +25,7 @@ test @bug 8023392 8259232 @summary Swing text components printed with spaces between chars - @author Anton Nashatyrev + @key printer @run applet/manual=yesno bug8023392.html */ diff --git a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java index e4fe393fd6e36..15a914934e701 100644 --- a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java +++ b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java @@ -95,10 +95,10 @@ * .awaitAndCheck(); * } * - * private static List createTestUI() { + * private static Window createTestUI() { * JFrame testUI = new JFrame("Test UI"); * testUI.setSize(250, 150); - * return List.of(testUI); + * return testUI; * } * } * } @@ -110,6 +110,10 @@ * the provided {@code createTestUI} on the Event Dispatch Thread (EDT), * and it will automatically position the test UI and make it visible. *

+ * The {@code Builder.testUI} methods accept interfaces which create one window + * or a list of windows if the test needs multiple windows, + * or directly a single window, an array of windows or a list of windows. + *

* Alternatively, use one of the {@code PassFailJFrame} constructors to * create an object, then create secondary test UI, register it * with {@code PassFailJFrame}, position it and make it visible. @@ -146,7 +150,7 @@ *

  • to enable screenshots.
  • * */ -public class PassFailJFrame { +public final class PassFailJFrame { private static final String TITLE = "Test Instruction Frame"; private static final long TEST_TIMEOUT = 5; @@ -277,12 +281,18 @@ private PassFailJFrame(Builder builder) throws InterruptedException, this(builder.title, builder.instructions, builder.testTimeOut, builder.rows, builder.columns, builder.screenCapture); - if (builder.windowCreator != null) { + if (builder.windowListCreator != null) { invokeOnEDT(() -> - builder.testWindows = builder.windowCreator.createTestUI()); + builder.testWindows = builder.windowListCreator.createTestUI()); + if (builder.testWindows == null) { + throw new IllegalStateException("Window list creator returned null list"); + } } if (builder.testWindows != null) { + if (builder.testWindows.isEmpty()) { + throw new IllegalStateException("Window list is empty"); + } addTestWindow(builder.testWindows); builder.testWindows .forEach(w -> w.addWindowListener(windowClosingHandler)); @@ -293,17 +303,15 @@ private PassFailJFrame(Builder builder) throws InterruptedException, builder.positionWindows .positionTestWindows(unmodifiableList(builder.testWindows), builder.instructionUIHandler); - - windowList.forEach(w -> w.setVisible(true)); }); } else if (builder.testWindows.size() == 1) { Window window = builder.testWindows.get(0); positionTestWindow(window, builder.position); - window.setVisible(true); } else { positionTestWindow(null, builder.position); } } + showAllWindows(); } /** @@ -369,7 +377,7 @@ private static void createUI(String title, String instructions, frame.add(buttonsPanel, BorderLayout.SOUTH); frame.pack(); frame.setLocationRelativeTo(null); - windowList.add(frame); + addTestWindow(frame); } private static JTextComponent configurePlainText(String instructions, @@ -400,14 +408,27 @@ private static JTextComponent configureHTML(String instructions, /** - * Creates one or more windows for test UI. + * Creates a test UI window. */ @FunctionalInterface public interface WindowCreator { + /** + * Creates a window for test UI. + * This method is called by the framework on the EDT. + * @return a test UI window + */ + Window createTestUI(); + } + + /** + * Creates a list of test UI windows. + */ + @FunctionalInterface + public interface WindowListCreator { /** * Creates one or more windows for test UI. * This method is called by the framework on the EDT. - * @return a list of windows. + * @return a list of test UI windows */ List createTestUI(); } @@ -423,8 +444,13 @@ public interface PositionWindows { * the instruction UI frame was positioned on the screen. *

    * The list of the test windows contains the windows - * that were passed to the framework via - * {@link Builder#testUI(WindowCreator) testUI} method. + * that were passed to the framework via the + * {@link Builder#testUI(Window...) testUI(Window...)} method or + * that were created with {@code WindowCreator} + * or {@code WindowListCreator} which were passed via + * {@link Builder#testUI(WindowCreator) testUI(WindowCreator)} or + * {@link Builder#testUI(WindowListCreator) testUI(WindowListCreator)} + * correspondingly. * * @param testWindows the list of test windows * @param instructionUI information about the instruction frame @@ -859,6 +885,29 @@ public static synchronized void addTestWindow(Collection testW windowList.addAll(testWindows); } + /** + * Displays all the windows in {@code windowList}. + * + * @throws InterruptedException if the thread is interrupted while + * waiting for the event dispatch thread to finish running + * the {@link #showUI() showUI} + * @throws InvocationTargetException if an exception is thrown while + * the event dispatch thread executes {@code showUI} + */ + private static void showAllWindows() + throws InterruptedException, InvocationTargetException { + invokeOnEDT(PassFailJFrame::showUI); + } + + /** + * Displays all the windows in {@code windowList}; it has to be called on + * the EDT — use {@link #showAllWindows() showAllWindows} to ensure it. + */ + private static synchronized void showUI() { + windowList.forEach(w -> w.setVisible(true)); + } + + /** * Forcibly pass the test. *

    The sample usage: @@ -900,7 +949,7 @@ public static final class Builder { private boolean screenCapture; private List testWindows; - private WindowCreator windowCreator; + private WindowListCreator windowListCreator; private PositionWindows positionWindows; private InstructionUI instructionUIHandler; @@ -936,39 +985,109 @@ public Builder screenCapture() { return this; } + /** + * Adds a {@code WindowCreator} which the framework will use + * to create the test UI window. + * + * @param windowCreator a {@code WindowCreator} + * to create the test UI window + * @return this builder + * @throws IllegalArgumentException if {@code windowCreator} is {@code null} + * @throws IllegalStateException if a window creator + * or a list of test windows is already set + */ + public Builder testUI(WindowCreator windowCreator) { + if (windowCreator == null) { + throw new IllegalArgumentException("The window creator can't be null"); + } + + checkWindowsLists(); + + this.windowListCreator = () -> List.of(windowCreator.createTestUI()); + return this; + } + + /** + * Adds a {@code WindowListCreator} which the framework will use + * to create a list of test UI windows. + * + * @param windowListCreator a {@code WindowListCreator} + * to create test UI windows + * @return this builder + * @throws IllegalArgumentException if {@code windowListCreator} is {@code null} + * @throws IllegalStateException if a window creator + * or a list of test windows is already set + */ + public Builder testUI(WindowListCreator windowListCreator) { + if (windowListCreator == null) { + throw new IllegalArgumentException("The window list creator can't be null"); + } + + checkWindowsLists(); + + this.windowListCreator = windowListCreator; + return this; + } + + /** + * Adds an already created test UI window. + * The window is positioned and shown automatically. + * + * @param window a test UI window + * @return this builder + */ public Builder testUI(Window window) { return testUI(List.of(window)); } + /** + * Adds an array of already created test UI windows. + * + * @param windows an array of test UI windows + * @return this builder + */ public Builder testUI(Window... windows) { return testUI(List.of(windows)); } - public Builder testUI(List windows) { + /** + * Adds a list of already created test UI windows. + * + * @param windows a list of test UI windows + * @return this builder + * @throws IllegalArgumentException if {@code windows} is {@code null} + * or the list contains {@code null} + * @throws IllegalStateException if a window creator + * or a list of test windows is already set + */ + public Builder testUI(List windows) { if (windows == null) { throw new IllegalArgumentException("The list of windows can't be null"); } if (windows.stream() .anyMatch(Objects::isNull)) { - throw new IllegalArgumentException("The windows list can't contain null"); + throw new IllegalArgumentException("The list of windows can't contain null"); } - if (windowCreator != null) { - throw new IllegalStateException("windowCreator is already set"); - } + checkWindowsLists(); + this.testWindows = windows; return this; } - public Builder testUI(WindowCreator windowCreator) { - if (windowCreator == null) { - throw new IllegalArgumentException("The window creator can't be null"); + /** + * Verifies the state of window list and window creator. + * + * @throws IllegalStateException if a windows list creator + * or a list of test windows is already set + */ + private void checkWindowsLists() { + if (windowListCreator != null) { + throw new IllegalStateException("Window list creator is already set"); } if (testWindows != null) { - throw new IllegalStateException("testWindows are already set"); + throw new IllegalStateException("The list of test windows is already set"); } - this.windowCreator = windowCreator; - return this; } public Builder positionTestUI(PositionWindows positionWindows) { @@ -1010,13 +1129,13 @@ private void validate() { } if (position == null - && (testWindows != null || windowCreator != null)) { + && (testWindows != null || windowListCreator != null)) { position = Position.HORIZONTAL; } if (positionWindows != null) { - if (testWindows == null && windowCreator == null) { + if (testWindows == null && windowListCreator == null) { throw new IllegalStateException("To position windows, " + "provide an a list of windows to the builder"); } diff --git a/test/jdk/java/foreign/LibraryLookupTest.java b/test/jdk/java/foreign/LibraryLookupTest.java index 90aa589654b9b..950e769b0f61a 100644 --- a/test/jdk/java/foreign/LibraryLookupTest.java +++ b/test/jdk/java/foreign/LibraryLookupTest.java @@ -23,10 +23,16 @@ import org.testng.annotations.Test; +import java.io.IOException; import java.lang.foreign.*; import java.lang.foreign.Arena; import java.lang.invoke.MethodHandle; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; import java.nio.file.Path; +import java.util.HashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -91,6 +97,37 @@ void testLoadLibraryBadLookupName() { } } + @Test + void testLoadLibraryNonDefaultFileSystem() throws URISyntaxException, IOException { + try (FileSystem customFs = fsFromJarOfClass(org.testng.annotations.Test.class)) { + try (Arena arena = Arena.ofConfined()) { + Path p = customFs.getPath("."); + try { + SymbolLookup.libraryLookup(p, arena); + fail("Did not throw IAE"); + } catch (IllegalArgumentException iae) { + assertTrue(iae.getMessage().contains("not in default file system")); + } + } + } + } + + private static FileSystem fsFromJarOfClass(Class clazz) throws URISyntaxException, IOException { + String name = clazz.getName(); + final int lastDot = name.lastIndexOf('.'); + if (lastDot != -1) { + name = name.substring(lastDot + 1); + } + URI uri = clazz.getResource(name + ".class").toURI(); + if (uri.getScheme().equals("jar")) { + final String[] parts = uri.toString().split("!"); + if (parts.length == 2) { + return FileSystems.newFileSystem(URI.create(parts[0]), new HashMap<>()); + } + } + throw new AssertionError("Unable to create file system from " + clazz); + } + private static MemorySegment loadLibrary(Arena session) { SymbolLookup lib = SymbolLookup.libraryLookup(LIB_PATH, session); MemorySegment addr = lib.find("inc").get(); diff --git a/test/jdk/java/foreign/NativeTestHelper.java b/test/jdk/java/foreign/NativeTestHelper.java index d12593f7b8548..1ea45437da11c 100644 --- a/test/jdk/java/foreign/NativeTestHelper.java +++ b/test/jdk/java/foreign/NativeTestHelper.java @@ -175,9 +175,13 @@ public static MethodHandle downcallHandle(String symbol, FunctionDescriptor desc } public static MemorySegment upcallStub(Class holder, String name, FunctionDescriptor descriptor) { + return upcallStub(holder, name, descriptor, Arena.ofAuto()); + } + + public static MemorySegment upcallStub(Class holder, String name, FunctionDescriptor descriptor, Arena arena) { try { MethodHandle target = MethodHandles.lookup().findStatic(holder, name, descriptor.toMethodType()); - return LINKER.upcallStub(target, descriptor, Arena.ofAuto()); + return LINKER.upcallStub(target, descriptor, arena); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } diff --git a/test/jdk/java/foreign/TestAddressDereference.java b/test/jdk/java/foreign/TestAddressDereference.java index 6dc9575e5ae8a..54477bafe1347 100644 --- a/test/jdk/java/foreign/TestAddressDereference.java +++ b/test/jdk/java/foreign/TestAddressDereference.java @@ -128,7 +128,8 @@ public void testNativeUpcallArgNeg(long alignment, ValueLayout layout) throws Th if (!badAlign) return; runInNewProcess(UpcallTestRunner.class, true, new String[] {Long.toString(alignment), layout.toString() }) - .assertStdErrContains("alignment constraint for address"); + .shouldNotHaveExitValue(0) + .stderrShouldContain("alignment constraint for address"); } public static class UpcallTestRunner { diff --git a/test/jdk/java/foreign/TestArrayCopy.java b/test/jdk/java/foreign/TestArrayCopy.java index 0a04f00e4f52f..9a1c48a394e09 100644 --- a/test/jdk/java/foreign/TestArrayCopy.java +++ b/test/jdk/java/foreign/TestArrayCopy.java @@ -26,12 +26,9 @@ * @run testng TestArrayCopy */ -import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.ValueLayout; -import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; import java.lang.invoke.VarHandle; import java.nio.ByteOrder; import java.util.ArrayList; @@ -240,7 +237,7 @@ public void testCopyReadOnlyDest(CopyMode mode, CopyHelper try { helper.copyFromArray(srcArr, 0, SEG_LENGTH_BYTES / bytesPerElement, dstSeg, 0, ByteOrder.nativeOrder()); fail(); - } catch (UnsupportedOperationException ex) { + } catch (IllegalArgumentException ex) { //ok } } diff --git a/test/jdk/java/foreign/TestHFA.java b/test/jdk/java/foreign/TestHFA.java index 33ed1f9e8462a..0ee0ef6e1de5d 100644 --- a/test/jdk/java/foreign/TestHFA.java +++ b/test/jdk/java/foreign/TestHFA.java @@ -46,43 +46,44 @@ public class TestHFA { final static Linker abi = Linker.nativeLinker(); final static SymbolLookup lookup = SymbolLookup.loaderLookup(); - static final OfFloat FLOAT = JAVA_FLOAT.withByteAlignment(4); + final static OfFloat C_FLOAT = (ValueLayout.OfFloat) abi.canonicalLayouts().get("float"); + final static OfDouble C_DOUBLE = (ValueLayout.OfDouble) abi.canonicalLayouts().get("double"); final static GroupLayout S_FFLayout = MemoryLayout.structLayout( - FLOAT.withName("p0"), - FLOAT.withName("p1") + C_FLOAT.withName("p0"), + C_FLOAT.withName("p1") ).withName("S_FF"); final static GroupLayout S_FFFFFFFLayout = MemoryLayout.structLayout( - FLOAT.withName("p0"), - FLOAT.withName("p1"), - FLOAT.withName("p2"), - FLOAT.withName("p3"), - FLOAT.withName("p4"), - FLOAT.withName("p5"), - FLOAT.withName("p6") + C_FLOAT.withName("p0"), + C_FLOAT.withName("p1"), + C_FLOAT.withName("p2"), + C_FLOAT.withName("p3"), + C_FLOAT.withName("p4"), + C_FLOAT.withName("p5"), + C_FLOAT.withName("p6") ).withName("S_FFFF"); static final FunctionDescriptor fdadd_float_structs = FunctionDescriptor.of(S_FFFFFFFLayout, S_FFFFFFFLayout, S_FFFFFFFLayout); static final FunctionDescriptor fdadd_float_to_struct_after_floats = FunctionDescriptor.of(S_FFLayout, - JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT, - JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT, JAVA_FLOAT, - JAVA_FLOAT, JAVA_FLOAT, S_FFLayout, JAVA_FLOAT); + C_FLOAT, C_FLOAT, C_FLOAT, C_FLOAT, C_FLOAT, + C_FLOAT, C_FLOAT, C_FLOAT, C_FLOAT, C_FLOAT, + C_FLOAT, C_FLOAT, S_FFLayout, C_FLOAT); static final FunctionDescriptor fdadd_float_to_struct_after_structs = FunctionDescriptor.of(S_FFLayout, S_FFLayout, S_FFLayout, S_FFLayout, S_FFLayout, S_FFLayout, S_FFLayout, - S_FFLayout, JAVA_FLOAT); + S_FFLayout, C_FLOAT); static final FunctionDescriptor fdadd_double_to_struct_after_structs = FunctionDescriptor.of(S_FFLayout, S_FFLayout, S_FFLayout, S_FFLayout, S_FFLayout, S_FFLayout, S_FFLayout, - S_FFLayout, JAVA_DOUBLE); + S_FFLayout, C_DOUBLE); static final FunctionDescriptor fdadd_float_to_large_struct_after_structs = FunctionDescriptor.of(S_FFFFFFFLayout, S_FFLayout, S_FFLayout, S_FFLayout, S_FFLayout, S_FFLayout, S_FFLayout, - S_FFFFFFFLayout, JAVA_FLOAT); + S_FFFFFFFLayout, C_FLOAT); static final FunctionDescriptor fdpass_two_large_structs = FunctionDescriptor.of(S_FFFFFFFLayout, ADDRESS, S_FFFFFFFLayout, S_FFFFFFFLayout); - static final FunctionDescriptor fdpass_struct_after_floats = FunctionDescriptor.of(S_FFLayout, ADDRESS, S_FFLayout, JAVA_FLOAT); - static final FunctionDescriptor fdpass_struct_after_structs = FunctionDescriptor.of(S_FFLayout, ADDRESS, S_FFLayout, JAVA_FLOAT); - static final FunctionDescriptor fdpass_struct_after_structs_plus_double = FunctionDescriptor.of(S_FFLayout, ADDRESS, S_FFLayout, JAVA_DOUBLE); - static final FunctionDescriptor fdpass_large_struct_after_structs = FunctionDescriptor.of(S_FFFFFFFLayout, ADDRESS, S_FFFFFFFLayout, JAVA_FLOAT); + static final FunctionDescriptor fdpass_struct_after_floats = FunctionDescriptor.of(S_FFLayout, ADDRESS, S_FFLayout, C_FLOAT); + static final FunctionDescriptor fdpass_struct_after_structs = FunctionDescriptor.of(S_FFLayout, ADDRESS, S_FFLayout, C_FLOAT); + static final FunctionDescriptor fdpass_struct_after_structs_plus_double = FunctionDescriptor.of(S_FFLayout, ADDRESS, S_FFLayout, C_DOUBLE); + static final FunctionDescriptor fdpass_large_struct_after_structs = FunctionDescriptor.of(S_FFFFFFFLayout, ADDRESS, S_FFFFFFFLayout, C_FLOAT); final static MethodHandle mhadd_float_structs = abi.downcallHandle(lookup.find("add_float_structs").orElseThrow(), fdadd_float_structs); @@ -109,24 +110,23 @@ public class TestHFA { @Test public static void testAddFloatStructs() { float p0 = 0.0f, p1 = 0.0f, p2 = 0.0f, p3 = 0.0f, p4 = 0.0f, p5 = 0.0f, p6 = 0.0f; - try { - Arena arena = Arena.ofConfined(); + try (Arena arena = Arena.ofConfined()) { MemorySegment s = arena.allocate(S_FFFFFFFLayout); - s.set(FLOAT, 0, 1.0f); - s.set(FLOAT, 4, 2.0f); - s.set(FLOAT, 8, 3.0f); - s.set(FLOAT, 12, 4.0f); - s.set(FLOAT, 16, 5.0f); - s.set(FLOAT, 20, 6.0f); - s.set(FLOAT, 24, 7.0f); + s.set(C_FLOAT, 0, 1.0f); + s.set(C_FLOAT, 4, 2.0f); + s.set(C_FLOAT, 8, 3.0f); + s.set(C_FLOAT, 12, 4.0f); + s.set(C_FLOAT, 16, 5.0f); + s.set(C_FLOAT, 20, 6.0f); + s.set(C_FLOAT, 24, 7.0f); s = (MemorySegment)mhadd_float_structs.invokeExact((SegmentAllocator)arena, s, s); - p0 = s.get(FLOAT, 0); - p1 = s.get(FLOAT, 4); - p2 = s.get(FLOAT, 8); - p3 = s.get(FLOAT, 12); - p4 = s.get(FLOAT, 16); - p5 = s.get(FLOAT, 20); - p6 = s.get(FLOAT, 24); + p0 = s.get(C_FLOAT, 0); + p1 = s.get(C_FLOAT, 4); + p2 = s.get(C_FLOAT, 8); + p3 = s.get(C_FLOAT, 12); + p4 = s.get(C_FLOAT, 16); + p5 = s.get(C_FLOAT, 20); + p6 = s.get(C_FLOAT, 24); System.out.println("S_FFFFFFF(" + p0 + ";" + p1 + ";" + p2 + ";" + p3 + ";" + p4 + ";" + p5 + ";" + p6 + ")"); } catch (Throwable t) { t.printStackTrace(); @@ -138,17 +138,16 @@ public static void testAddFloatStructs() { @Test public static void testAddFloatToStructAfterFloats() { float p0 = 0.0f, p1 = 0.0f; - try { - Arena arena = Arena.ofConfined(); + try (Arena arena = Arena.ofConfined()) { MemorySegment s = arena.allocate(S_FFLayout); - s.set(FLOAT, 0, 1.0f); - s.set(FLOAT, 4, 1.0f); + s.set(C_FLOAT, 0, 1.0f); + s.set(C_FLOAT, 4, 1.0f); s = (MemorySegment)mhadd_float_to_struct_after_floats.invokeExact((SegmentAllocator)arena, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, s, 1.0f); - p0 = s.get(FLOAT, 0); - p1 = s.get(FLOAT, 4); + p0 = s.get(C_FLOAT, 0); + p1 = s.get(C_FLOAT, 4); System.out.println("S_FF(" + p0 + ";" + p1 + ")"); } catch (Throwable t) { t.printStackTrace(); @@ -159,16 +158,15 @@ public static void testAddFloatToStructAfterFloats() { @Test public static void testAddFloatToStructAfterStructs() { float p0 = 0.0f, p1 = 0.0f; - try { - Arena arena = Arena.ofConfined(); + try (Arena arena = Arena.ofConfined()) { MemorySegment s = arena.allocate(S_FFLayout); - s.set(FLOAT, 0, 1.0f); - s.set(FLOAT, 4, 1.0f); + s.set(C_FLOAT, 0, 1.0f); + s.set(C_FLOAT, 4, 1.0f); s = (MemorySegment)mhadd_float_to_struct_after_structs.invokeExact((SegmentAllocator)arena, s, s, s, s, s, s, s, 1.0f); - p0 = s.get(FLOAT, 0); - p1 = s.get(FLOAT, 4); + p0 = s.get(C_FLOAT, 0); + p1 = s.get(C_FLOAT, 4); System.out.println("S_FF(" + p0 + ";" + p1 + ")"); } catch (Throwable t) { t.printStackTrace(); @@ -179,16 +177,15 @@ public static void testAddFloatToStructAfterStructs() { @Test public static void testAddDoubleToStructAfterStructs() { float p0 = 0.0f, p1 = 0.0f; - try { - Arena arena = Arena.ofConfined(); + try (Arena arena = Arena.ofConfined()) { MemorySegment s = arena.allocate(S_FFLayout); - s.set(FLOAT, 0, 1.0f); - s.set(FLOAT, 4, 1.0f); + s.set(C_FLOAT, 0, 1.0f); + s.set(C_FLOAT, 4, 1.0f); s = (MemorySegment)mhadd_double_to_struct_after_structs.invokeExact((SegmentAllocator)arena, s, s, s, s, s, s, s, 1.0d); - p0 = s.get(FLOAT, 0); - p1 = s.get(FLOAT, 4); + p0 = s.get(C_FLOAT, 0); + p1 = s.get(C_FLOAT, 4); System.out.println("S_FF(" + p0 + ";" + p1 + ")"); } catch (Throwable t) { t.printStackTrace(); @@ -199,26 +196,25 @@ public static void testAddDoubleToStructAfterStructs() { @Test public static void testAddFloatToLargeStructAfterStructs() { float p0 = 0.0f, p1 = 0.0f, p2 = 0.0f, p3 = 0.0f, p4 = 0.0f, p5 = 0.0f, p6 = 0.0f; - try { - Arena arena = Arena.ofConfined(); + try (Arena arena = Arena.ofConfined()) { MemorySegment s = arena.allocate(S_FFFFFFFLayout); - s.set(FLOAT, 0, 1.0f); - s.set(FLOAT, 4, 2.0f); - s.set(FLOAT, 8, 3.0f); - s.set(FLOAT, 12, 4.0f); - s.set(FLOAT, 16, 5.0f); - s.set(FLOAT, 20, 6.0f); - s.set(FLOAT, 24, 7.0f); + s.set(C_FLOAT, 0, 1.0f); + s.set(C_FLOAT, 4, 2.0f); + s.set(C_FLOAT, 8, 3.0f); + s.set(C_FLOAT, 12, 4.0f); + s.set(C_FLOAT, 16, 5.0f); + s.set(C_FLOAT, 20, 6.0f); + s.set(C_FLOAT, 24, 7.0f); s = (MemorySegment)mhadd_float_to_large_struct_after_structs.invokeExact((SegmentAllocator)arena, s, s, s, s, s, s, s, 1.0f); - p0 = s.get(FLOAT, 0); - p1 = s.get(FLOAT, 4); - p2 = s.get(FLOAT, 8); - p3 = s.get(FLOAT, 12); - p4 = s.get(FLOAT, 16); - p5 = s.get(FLOAT, 20); - p6 = s.get(FLOAT, 24); + p0 = s.get(C_FLOAT, 0); + p1 = s.get(C_FLOAT, 4); + p2 = s.get(C_FLOAT, 8); + p3 = s.get(C_FLOAT, 12); + p4 = s.get(C_FLOAT, 16); + p5 = s.get(C_FLOAT, 20); + p6 = s.get(C_FLOAT, 24); System.out.println("S_FFFFFFF(" + p0 + ";" + p1 + ";" + p2 + ";" + p3 + ";" + p4 + ";" + p5 + ";" + p6 + ")"); } catch (Throwable t) { t.printStackTrace(); @@ -229,20 +225,20 @@ public static void testAddFloatToLargeStructAfterStructs() { // Java versions for Upcall tests. public static MemorySegment addFloatStructs(MemorySegment p0, MemorySegment p1) { - float val0 = p0.get(FLOAT, 0) + p1.get(FLOAT, 0); - float val1 = p0.get(FLOAT, 4) + p1.get(FLOAT, 4); - float val2 = p0.get(FLOAT, 8) + p1.get(FLOAT, 8); - float val3 = p0.get(FLOAT, 12) + p1.get(FLOAT, 12); - float val4 = p0.get(FLOAT, 16) + p1.get(FLOAT, 16); - float val5 = p0.get(FLOAT, 20) + p1.get(FLOAT, 20); - float val6 = p0.get(FLOAT, 24) + p1.get(FLOAT, 24); - p0.set(FLOAT, 0, val0); - p0.set(FLOAT, 4, val1); - p0.set(FLOAT, 8, val2); - p0.set(FLOAT, 12, val3); - p0.set(FLOAT, 16, val4); - p0.set(FLOAT, 20, val5); - p0.set(FLOAT, 24, val6); + float val0 = p0.get(C_FLOAT, 0) + p1.get(C_FLOAT, 0); + float val1 = p0.get(C_FLOAT, 4) + p1.get(C_FLOAT, 4); + float val2 = p0.get(C_FLOAT, 8) + p1.get(C_FLOAT, 8); + float val3 = p0.get(C_FLOAT, 12) + p1.get(C_FLOAT, 12); + float val4 = p0.get(C_FLOAT, 16) + p1.get(C_FLOAT, 16); + float val5 = p0.get(C_FLOAT, 20) + p1.get(C_FLOAT, 20); + float val6 = p0.get(C_FLOAT, 24) + p1.get(C_FLOAT, 24); + p0.set(C_FLOAT, 0, val0); + p0.set(C_FLOAT, 4, val1); + p0.set(C_FLOAT, 8, val2); + p0.set(C_FLOAT, 12, val3); + p0.set(C_FLOAT, 16, val4); + p0.set(C_FLOAT, 20, val5); + p0.set(C_FLOAT, 24, val6); return p0; } @@ -250,8 +246,8 @@ public static MemorySegment addFloatToStructAfterFloats( float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, MemorySegment s, float f) { - float val = s.get(FLOAT, 0); - s.set(FLOAT, 0, val + f); + float val = s.get(C_FLOAT, 0); + s.set(C_FLOAT, 0, val + f); return s; } @@ -259,8 +255,8 @@ public static MemorySegment addFloatToStructAfterStructs( MemorySegment s1, MemorySegment s2, MemorySegment s3, MemorySegment s4, MemorySegment s5, MemorySegment s6, MemorySegment s, float f) { - float val = s.get(FLOAT, 0); - s.set(FLOAT, 0, val + f); + float val = s.get(C_FLOAT, 0); + s.set(C_FLOAT, 0, val + f); return s; } @@ -268,36 +264,35 @@ public static MemorySegment addDoubleToStructAfterStructs( MemorySegment s1, MemorySegment s2, MemorySegment s3, MemorySegment s4, MemorySegment s5, MemorySegment s6, MemorySegment s, double f) { - float val = s.get(FLOAT, 0); - s.set(FLOAT, 0, val + (float) f); + float val = s.get(C_FLOAT, 0); + s.set(C_FLOAT, 0, val + (float) f); return s; } @Test public static void testAddFloatStructsUpcall() { float p0 = 0.0f, p1 = 0.0f, p2 = 0.0f, p3 = 0.0f, p4 = 0.0f, p5 = 0.0f, p6 = 0.0f; - try { - Arena arena = Arena.ofConfined(); + try (Arena arena = Arena.ofConfined()) { MemorySegment s = arena.allocate(S_FFFFFFFLayout); - s.set(FLOAT, 0, 1.0f); - s.set(FLOAT, 4, 2.0f); - s.set(FLOAT, 8, 3.0f); - s.set(FLOAT, 12, 4.0f); - s.set(FLOAT, 16, 5.0f); - s.set(FLOAT, 20, 6.0f); - s.set(FLOAT, 24, 7.0f); + s.set(C_FLOAT, 0, 1.0f); + s.set(C_FLOAT, 4, 2.0f); + s.set(C_FLOAT, 8, 3.0f); + s.set(C_FLOAT, 12, 4.0f); + s.set(C_FLOAT, 16, 5.0f); + s.set(C_FLOAT, 20, 6.0f); + s.set(C_FLOAT, 24, 7.0f); MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class); MemorySegment stub = abi.upcallStub(MethodHandles.lookup().findStatic(TestHFA.class, "addFloatStructs", mt), fdadd_float_structs, arena); s = (MemorySegment)mhpass_two_large_structs.invokeExact((SegmentAllocator)arena, stub, s, s); - p0 = s.get(FLOAT, 0); - p1 = s.get(FLOAT, 4); - p2 = s.get(FLOAT, 8); - p3 = s.get(FLOAT, 12); - p4 = s.get(FLOAT, 16); - p5 = s.get(FLOAT, 20); - p6 = s.get(FLOAT, 24); + p0 = s.get(C_FLOAT, 0); + p1 = s.get(C_FLOAT, 4); + p2 = s.get(C_FLOAT, 8); + p3 = s.get(C_FLOAT, 12); + p4 = s.get(C_FLOAT, 16); + p5 = s.get(C_FLOAT, 20); + p6 = s.get(C_FLOAT, 24); System.out.println("S_FFFFFFF(" + p0 + ";" + p1 + ";" + p2 + ";" + p3 + ";" + p4 + ";" + p5 + ";" + p6 + ")"); } catch (Throwable t) { t.printStackTrace(); @@ -309,11 +304,10 @@ public static void testAddFloatStructsUpcall() { @Test public static void testAddFloatToStructAfterFloatsUpcall() { float p0 = 0.0f, p1 = 0.0f; - try { - Arena arena = Arena.ofConfined(); + try (Arena arena = Arena.ofConfined()) { MemorySegment s = arena.allocate(S_FFLayout); - s.set(FLOAT, 0, 1.0f); - s.set(FLOAT, 4, 1.0f); + s.set(C_FLOAT, 0, 1.0f); + s.set(C_FLOAT, 4, 1.0f); MethodType mt = MethodType.methodType(MemorySegment.class, float.class, float.class, float.class, float.class, float.class, float.class, float.class, float.class, @@ -322,8 +316,8 @@ public static void testAddFloatToStructAfterFloatsUpcall() { MemorySegment stub = abi.upcallStub(MethodHandles.lookup().findStatic(TestHFA.class, "addFloatToStructAfterFloats", mt), fdadd_float_to_struct_after_floats, arena); s = (MemorySegment)mhpass_struct_after_floats.invokeExact((SegmentAllocator)arena, stub, s, 1.0f); - p0 = s.get(FLOAT, 0); - p1 = s.get(FLOAT, 4); + p0 = s.get(C_FLOAT, 0); + p1 = s.get(C_FLOAT, 4); System.out.println("S_FF(" + p0 + ";" + p1 + ")"); } catch (Throwable t) { t.printStackTrace(); @@ -334,11 +328,10 @@ public static void testAddFloatToStructAfterFloatsUpcall() { @Test public static void testAddFloatToStructAfterStructsUpcall() { float p0 = 0.0f, p1 = 0.0f; - try { - Arena arena = Arena.ofConfined(); + try (Arena arena = Arena.ofConfined()) { MemorySegment s = arena.allocate(S_FFLayout); - s.set(FLOAT, 0, 1.0f); - s.set(FLOAT, 4, 1.0f); + s.set(C_FLOAT, 0, 1.0f); + s.set(C_FLOAT, 4, 1.0f); MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, @@ -346,8 +339,8 @@ public static void testAddFloatToStructAfterStructsUpcall() { MemorySegment stub = abi.upcallStub(MethodHandles.lookup().findStatic(TestHFA.class, "addFloatToStructAfterStructs", mt), fdadd_float_to_struct_after_structs, arena); s = (MemorySegment)mhpass_struct_after_structs.invokeExact((SegmentAllocator)arena, stub, s, 1.0f); - p0 = s.get(FLOAT, 0); - p1 = s.get(FLOAT, 4); + p0 = s.get(C_FLOAT, 0); + p1 = s.get(C_FLOAT, 4); System.out.println("S_FF(" + p0 + ";" + p1 + ")"); } catch (Throwable t) { t.printStackTrace(); @@ -358,11 +351,10 @@ public static void testAddFloatToStructAfterStructsUpcall() { @Test public static void testAddDoubleToStructAfterStructsUpcall() { float p0 = 0.0f, p1 = 0.0f; - try { - Arena arena = Arena.ofConfined(); + try (Arena arena = Arena.ofConfined()) { MemorySegment s = arena.allocate(S_FFLayout); - s.set(FLOAT, 0, 1.0f); - s.set(FLOAT, 4, 1.0f); + s.set(C_FLOAT, 0, 1.0f); + s.set(C_FLOAT, 4, 1.0f); MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, @@ -370,8 +362,8 @@ public static void testAddDoubleToStructAfterStructsUpcall() { MemorySegment stub = abi.upcallStub(MethodHandles.lookup().findStatic(TestHFA.class, "addDoubleToStructAfterStructs", mt), fdadd_double_to_struct_after_structs, arena); s = (MemorySegment)mhpass_struct_after_structs_plus_double.invokeExact((SegmentAllocator)arena, stub, s, 1.0d); - p0 = s.get(FLOAT, 0); - p1 = s.get(FLOAT, 4); + p0 = s.get(C_FLOAT, 0); + p1 = s.get(C_FLOAT, 4); System.out.println("S_FF(" + p0 + ";" + p1 + ")"); } catch (Throwable t) { t.printStackTrace(); @@ -382,16 +374,15 @@ public static void testAddDoubleToStructAfterStructsUpcall() { @Test public static void testAddFloatToLargeStructAfterStructsUpcall() { float p0 = 0.0f, p1 = 0.0f, p2 = 0.0f, p3 = 0.0f, p4 = 0.0f, p5 = 0.0f, p6 = 0.0f; - try { - Arena arena = Arena.ofConfined(); + try (Arena arena = Arena.ofConfined()) { MemorySegment s = arena.allocate(S_FFFFFFFLayout); - s.set(FLOAT, 0, 1.0f); - s.set(FLOAT, 4, 2.0f); - s.set(FLOAT, 8, 3.0f); - s.set(FLOAT, 12, 4.0f); - s.set(FLOAT, 16, 5.0f); - s.set(FLOAT, 20, 6.0f); - s.set(FLOAT, 24, 7.0f); + s.set(C_FLOAT, 0, 1.0f); + s.set(C_FLOAT, 4, 2.0f); + s.set(C_FLOAT, 8, 3.0f); + s.set(C_FLOAT, 12, 4.0f); + s.set(C_FLOAT, 16, 5.0f); + s.set(C_FLOAT, 20, 6.0f); + s.set(C_FLOAT, 24, 7.0f); MethodType mt = MethodType.methodType(MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, MemorySegment.class, @@ -399,13 +390,13 @@ public static void testAddFloatToLargeStructAfterStructsUpcall() { MemorySegment stub = abi.upcallStub(MethodHandles.lookup().findStatic(TestHFA.class, "addFloatToStructAfterStructs", mt), fdadd_float_to_large_struct_after_structs, arena); s = (MemorySegment)mhpass_large_struct_after_structs.invokeExact((SegmentAllocator)arena, stub, s, 1.0f); - p0 = s.get(FLOAT, 0); - p1 = s.get(FLOAT, 4); - p2 = s.get(FLOAT, 8); - p3 = s.get(FLOAT, 12); - p4 = s.get(FLOAT, 16); - p5 = s.get(FLOAT, 20); - p6 = s.get(FLOAT, 24); + p0 = s.get(C_FLOAT, 0); + p1 = s.get(C_FLOAT, 4); + p2 = s.get(C_FLOAT, 8); + p3 = s.get(C_FLOAT, 12); + p4 = s.get(C_FLOAT, 16); + p5 = s.get(C_FLOAT, 20); + p6 = s.get(C_FLOAT, 24); System.out.println("S_FFFFFFF(" + p0 + ";" + p1 + ";" + p2 + ";" + p3 + ";" + p4 + ";" + p5 + ";" + p6 + ")"); } catch (Throwable t) { t.printStackTrace(); diff --git a/test/jdk/java/foreign/TestHandshake.java b/test/jdk/java/foreign/TestHandshake.java index 4dc96ee9b3b25..efa175eb5c403 100644 --- a/test/jdk/java/foreign/TestHandshake.java +++ b/test/jdk/java/foreign/TestHandshake.java @@ -23,6 +23,7 @@ /* * @test + * @requires vm.flavor != "zero" * @modules java.base/jdk.internal.vm.annotation java.base/jdk.internal.misc * @key randomness * @run testng/othervm TestHandshake @@ -33,6 +34,7 @@ import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.nio.ByteBuffer; @@ -48,6 +50,7 @@ import org.testng.annotations.Test; import static java.lang.foreign.ValueLayout.JAVA_BYTE; +import static java.lang.foreign.ValueLayout.JAVA_INT; import static org.testng.Assert.*; public class TestHandshake { @@ -98,16 +101,19 @@ static abstract class AbstractSegmentAccessor implements Runnable { @Override public final void run() { start("\"Accessor #\" + id"); - outer: while (segment.scope().isAlive()) { + while (segment.scope().isAlive()) { try { doAccess(); } catch (IllegalStateException ex) { - long delay = System.currentTimeMillis() - start.get(); - System.out.println("Accessor #" + id + " suspending - elapsed (ms): " + delay); - backoff(); - delay = System.currentTimeMillis() - start.get(); - System.out.println("Accessor #" + id + " resuming - elapsed (ms): " + delay); - continue outer; + if (!failed.get()) { + // ignore - this means segment was alive, but was closed while we were accessing it + // next isAlive test should fail + assertFalse(segment.scope().isAlive()); + failed.set(true); + } else { + // rethrow! + throw ex; + } } } long delay = System.currentTimeMillis() - start.get(); @@ -174,6 +180,30 @@ public void doAccess() { } } + static class SegmentSwappyCopyAccessor extends AbstractSegmentAccessor { + + MemorySegment first, second; + ValueLayout sourceLayout, destLayout; + long count; + + + SegmentSwappyCopyAccessor(int id, MemorySegment segment, Arena _unused) { + super(id, segment); + long split = segment.byteSize() / 2; + first = segment.asSlice(0, split); + sourceLayout = JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN); + second = segment.asSlice(split); + destLayout = JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN); + count = Math.min(first.byteSize() / sourceLayout.byteSize(), + second.byteSize() / destLayout.byteSize()); + } + + @Override + public void doAccess() { + MemorySegment.copy(first, sourceLayout, 0L, second, destLayout, 0L, count); + } + } + static class SegmentFillAccessor extends AbstractSegmentAccessor { SegmentFillAccessor(int id, MemorySegment segment, Arena _unused) { @@ -246,14 +276,7 @@ static class Handshaker implements Runnable { @Override public void run() { start("Handshaker"); - while (true) { - try { - arena.close(); - break; - } catch (IllegalStateException ex) { - Thread.onSpinWait(); - } - } + arena.close(); // This should NOT throw long delay = System.currentTimeMillis() - start.get(); System.out.println("Segment closed - elapsed (ms): " + delay); } @@ -268,6 +291,7 @@ static Object[][] accessors() { return new Object[][] { { "SegmentAccessor", (AccessorFactory)SegmentAccessor::new }, { "SegmentCopyAccessor", (AccessorFactory)SegmentCopyAccessor::new }, + { "SegmentSwappyCopyAccessor", (AccessorFactory)SegmentSwappyCopyAccessor::new }, { "SegmentMismatchAccessor", (AccessorFactory)SegmentMismatchAccessor::new }, { "SegmentFillAccessor", (AccessorFactory)SegmentFillAccessor::new }, { "BufferAccessor", (AccessorFactory)BufferAccessor::new }, diff --git a/test/jdk/java/foreign/TestMemoryAccess.java b/test/jdk/java/foreign/TestMemoryAccess.java index 19f480aa4b258..ded9be1c085d2 100644 --- a/test/jdk/java/foreign/TestMemoryAccess.java +++ b/test/jdk/java/foreign/TestMemoryAccess.java @@ -87,7 +87,7 @@ private void testAccessInternal(Function viewFacto if (isRO) { throw new AssertionError(); //not ok, memory should be immutable } - } catch (UnsupportedOperationException ex) { + } catch (IllegalArgumentException ex) { if (!isRO) { throw new AssertionError(); //we should not have failed! } @@ -121,7 +121,7 @@ private void testArrayAccessInternal(Function view if (isRO) { throw new AssertionError(); //not ok, memory should be immutable } - } catch (UnsupportedOperationException ex) { + } catch (IllegalArgumentException ex) { if (!isRO) { throw new AssertionError(); //we should not have failed! } @@ -185,7 +185,7 @@ private void testMatrixAccessInternal(Function vie if (isRO) { throw new AssertionError(); //not ok, memory should be immutable } - } catch (UnsupportedOperationException ex) { + } catch (IllegalArgumentException ex) { if (!isRO) { throw new AssertionError(); //we should not have failed! } diff --git a/test/jdk/java/foreign/TestMemoryAccessInstance.java b/test/jdk/java/foreign/TestMemoryAccessInstance.java index a1c774b72dd02..d56f44388a4bb 100644 --- a/test/jdk/java/foreign/TestMemoryAccessInstance.java +++ b/test/jdk/java/foreign/TestMemoryAccessInstance.java @@ -27,7 +27,6 @@ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_SEGMENT_FORCE_EXACT=true --enable-native-access=ALL-UNNAMED TestMemoryAccessInstance */ -import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.Arena; import java.lang.foreign.ValueLayout; diff --git a/test/jdk/java/foreign/TestSegmentAllocators.java b/test/jdk/java/foreign/TestSegmentAllocators.java index 48e09f647c9a8..0e0c49320da07 100644 --- a/test/jdk/java/foreign/TestSegmentAllocators.java +++ b/test/jdk/java/foreign/TestSegmentAllocators.java @@ -100,6 +100,16 @@ public void testAllocation(Z value, AllocationFactory static final int SIZE_256M = 1024 * 1024 * 256; + @Test(expectedExceptions = IllegalArgumentException.class) + public void testReadOnlySlicingAllocator() { + SegmentAllocator.slicingAllocator(MemorySegment.ofArray(new int[0]).asReadOnly()); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testReadOnlyPrefixAllocator() { + SegmentAllocator.prefixAllocator(MemorySegment.ofArray(new int[0]).asReadOnly()); + } + @Test public void testBigAllocationInUnboundedSession() { try (Arena arena = Arena.ofConfined()) { @@ -160,6 +170,25 @@ public void testBadArenaNullReturn() { } } + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = ".*Heap segment not allowed.*") + public void testArenaAllocateFromHeapSegment() { + try (Arena arena = Arena.ofConfined()) { + var heapSegment = MemorySegment.ofArray(new int[]{1}); + arena.allocateFrom(ValueLayout.ADDRESS, heapSegment); + } + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = ".*Heap segment not allowed.*") + public void testAllocatorAllocateFromHeapSegment() { + try (Arena arena = Arena.ofConfined()) { + SegmentAllocator allocator = SegmentAllocator.prefixAllocator(arena.allocate(16)); + var heapSegment = MemorySegment.ofArray(new int[]{1}); + allocator.allocateFrom(ValueLayout.ADDRESS, heapSegment); + } + } + @Test public void testArrayAllocateDelegation() { AtomicInteger calls = new AtomicInteger(); diff --git a/test/jdk/java/foreign/TestSegmentCopy.java b/test/jdk/java/foreign/TestSegmentCopy.java index 85f843eddd792..414cd0a8451d9 100644 --- a/test/jdk/java/foreign/TestSegmentCopy.java +++ b/test/jdk/java/foreign/TestSegmentCopy.java @@ -76,7 +76,7 @@ public void testByteCopy(SegmentKind kind1, SegmentKind kind2) { } } - @Test(expectedExceptions = UnsupportedOperationException.class, dataProvider = "segmentKinds") + @Test(expectedExceptions = IllegalArgumentException.class, dataProvider = "segmentKinds") public void testReadOnlyCopy(SegmentKind kind1, SegmentKind kind2) { MemorySegment s1 = kind1.makeSegment(TEST_BYTE_SIZE); MemorySegment s2 = kind2.makeSegment(TEST_BYTE_SIZE); @@ -84,6 +84,15 @@ public void testReadOnlyCopy(SegmentKind kind1, SegmentKind kind2) { MemorySegment.copy(s1, Type.BYTE.layout, 0, s2.asReadOnly(), Type.BYTE.layout, 0, 0); } + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = ".*Attempt to write a read-only segment.*") + public void badCopy6Arg() { + try (Arena scope = Arena.ofConfined()) { + MemorySegment dest = scope.allocate(ValueLayout.JAVA_INT).asReadOnly(); + MemorySegment.copy(new int[1],0, dest, ValueLayout.JAVA_INT, 0 ,1); // should throw + } + } + @Test(expectedExceptions = IndexOutOfBoundsException.class, dataProvider = "types") public void testBadOverflow(Type type) { if (type.layout.byteSize() > 1) { diff --git a/test/jdk/java/foreign/TestSegments.java b/test/jdk/java/foreign/TestSegments.java index 940d96e844dd1..94b49eb7e594c 100644 --- a/test/jdk/java/foreign/TestSegments.java +++ b/test/jdk/java/foreign/TestSegments.java @@ -325,12 +325,18 @@ public void testScopeGlobalArena() { assertEquals(segment.scope(), arena.scope()); } - @Test(dataProvider = "segmentFactories", expectedExceptions = UnsupportedOperationException.class) + @Test(dataProvider = "segmentFactories", expectedExceptions = IllegalArgumentException.class) public void testFillIllegalAccessMode(Supplier segmentSupplier) { MemorySegment segment = segmentSupplier.get(); segment.asReadOnly().fill((byte) 0xFF); } + @Test(dataProvider = "segmentFactories", expectedExceptions = IllegalArgumentException.class) + public void testFromStringIllegalAccessMode(Supplier segmentSupplier) { + MemorySegment segment = segmentSupplier.get(); + segment.asReadOnly().setString(0, "a"); + } + @Test(dataProvider = "segmentFactories") public void testFillThread(Supplier segmentSupplier) throws Exception { MemorySegment segment = segmentSupplier.get(); diff --git a/test/jdk/java/foreign/TestStringEncoding.java b/test/jdk/java/foreign/TestStringEncoding.java index c4eeae8ea3e21..4caef6fbd09b4 100644 --- a/test/jdk/java/foreign/TestStringEncoding.java +++ b/test/jdk/java/foreign/TestStringEncoding.java @@ -22,8 +22,6 @@ * */ -import java.io.IOException; -import java.io.RandomAccessFile; import java.lang.foreign.Arena; import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.Linker; @@ -33,16 +31,12 @@ import java.lang.foreign.ValueLayout; import java.lang.invoke.MethodHandle; import java.lang.reflect.Field; -import java.nio.channels.FileChannel; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; -import java.util.function.Consumer; import java.util.function.UnaryOperator; import jdk.internal.foreign.StringSupport; @@ -333,6 +327,27 @@ public void strlen_int() { } } + @Test(dataProvider = "charsetsAndSegments") + public void testStringGetWithCharset(Charset charset, MemorySegment segment) { + for (int offset = 0 ; offset < Long.BYTES ; offset++) { + segment.getString(offset, charset); + } + } + + @Test(dataProvider = "charsetsAndSegments") + public void testStringSetWithCharset(Charset charset, MemorySegment segment) { + for (int offset = 0 ; offset < Long.BYTES ; offset++) { + segment.setString(offset, "H", charset); + } + } + + @Test(dataProvider = "charsetsAndSegments") + public void testStringAllocateFromWithCharset(Charset charset, MemorySegment segment) { + for (int offset = 0 ; offset < Long.BYTES ; offset++) { + SegmentAllocator.prefixAllocator(segment.asSlice(offset)).allocateFrom("H", charset); + } + } + @DataProvider public static Object[][] strings() { return new Object[][]{ @@ -361,7 +376,7 @@ public static boolean containsOnlyRegularCharacters(String s) { .allMatch(c -> Character.isLetterOrDigit((char) c)); } - boolean isStandard(Charset charset) { + static boolean isStandard(Charset charset) { for (Field standardCharset : StandardCharsets.class.getDeclaredFields()) { try { if (standardCharset.get(null) == charset) { @@ -374,9 +389,9 @@ boolean isStandard(Charset charset) { return false; } - List standardCharsets() { + static List standardCharsets() { return Charset.availableCharsets().values().stream() - .filter(this::isStandard) + .filter(TestStringEncoding::isStandard) .toList(); } @@ -456,4 +471,26 @@ public String toString() { } } + static MemorySegment[] heapSegments() { + return new MemorySegment[]{ + MemorySegment.ofArray(new byte[80]), + MemorySegment.ofArray(new char[40]), + MemorySegment.ofArray(new short[40]), + MemorySegment.ofArray(new int[20]), + MemorySegment.ofArray(new float[20]), + MemorySegment.ofArray(new long[10]), + MemorySegment.ofArray(new double[10]) + }; + } + + @DataProvider + public static Object[][] charsetsAndSegments() { + List values = new ArrayList<>(); + for (Charset charset : standardCharsets()) { + for (MemorySegment heapSegment : heapSegments()) { + values.add(new Object[] { charset, heapSegment }); + } + } + return values.toArray(Object[][]::new); + } } diff --git a/test/jdk/java/foreign/TestStubAllocFailure.java b/test/jdk/java/foreign/TestStubAllocFailure.java new file mode 100644 index 0000000000000..b20b3e88ea221 --- /dev/null +++ b/test/jdk/java/foreign/TestStubAllocFailure.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @library ../ /test/lib + * @requires jdk.foreign.linker != "FALLBACK" + * @run testng/othervm/native + * --enable-native-access=ALL-UNNAMED + * TestStubAllocFailure + */ + +import java.lang.foreign.*; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.io.IOException; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Stream; + +import org.testng.annotations.Test; + +import static org.testng.Assert.fail; + +public class TestStubAllocFailure extends UpcallTestHelper { + + @Test + public void testUpcallAllocFailure() throws IOException, InterruptedException { + runInNewProcess(UpcallRunner.class, true, List.of("-XX:ReservedCodeCacheSize=3M"), List.of()) + .shouldNotHaveExitValue(0) + .shouldNotHaveFatalError(); + } + + @Test + public void testUDowncallAllocFailure() throws IOException, InterruptedException { + runInNewProcess(DowncallRunner.class, true, List.of("-XX:ReservedCodeCacheSize=3M"), List.of()) + .shouldNotHaveExitValue(0) + .shouldNotHaveFatalError(); + } + + public static class UpcallRunner extends NativeTestHelper { + public static void main(String[] args) throws Throwable { + FunctionDescriptor descriptor = FunctionDescriptor.ofVoid(); + MethodHandle target = MethodHandles.lookup().findStatic(UpcallRunner.class, "target", descriptor.toMethodType()); + while (true) { + LINKER.upcallStub(target, descriptor, Arena.ofAuto()); + } + } + + public static void target() { + fail("Should not get here"); + } + } + + public static class DowncallRunner extends NativeTestHelper { + + private static final int MAX_ARITY = 5; + + private static void mapper(FunctionDescriptor fd, Consumer sink) { + for (MemoryLayout l : List.of(C_INT, C_LONG_LONG, C_DOUBLE, C_FLOAT, C_SHORT)) { + sink.accept(fd.appendArgumentLayouts(l)); + } + } + + public static void main(String[] args) throws Throwable { + Linker linker = Linker.nativeLinker(); + Stream stream = Stream.of(FunctionDescriptor.ofVoid()); + for (int i = 0; i < MAX_ARITY; i++) { + stream = stream.mapMulti(DowncallRunner::mapper); + } + + stream.forEach(linker::downcallHandle); + } + } +} diff --git a/test/jdk/java/foreign/TestUpcallException.java b/test/jdk/java/foreign/TestUpcallException.java index fa922b9fb3911..beaa33f5e61f3 100644 --- a/test/jdk/java/foreign/TestUpcallException.java +++ b/test/jdk/java/foreign/TestUpcallException.java @@ -48,7 +48,8 @@ public class TestUpcallException extends UpcallTestHelper { @Test(dataProvider = "exceptionCases") public void testException(Class target, boolean useSpec) throws InterruptedException, IOException { runInNewProcess(target, useSpec) - .assertStdErrContains("Testing upcall exceptions"); + .shouldNotHaveExitValue(0) + .stderrShouldContain("Testing upcall exceptions"); } @DataProvider diff --git a/test/jdk/java/foreign/UpcallTestHelper.java b/test/jdk/java/foreign/UpcallTestHelper.java index 2939c4bfd3747..bbc01959ccdaf 100644 --- a/test/jdk/java/foreign/UpcallTestHelper.java +++ b/test/jdk/java/foreign/UpcallTestHelper.java @@ -21,64 +21,45 @@ * questions. */ +import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.Utils; -import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import java.util.concurrent.TimeUnit; -import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertTrue; public class UpcallTestHelper extends NativeTestHelper { - public record Output(List stdout, List stderr) { - private static void assertContains(List lines, String shouldInclude, String name) { - assertTrue(lines.stream().anyMatch(line -> line.contains(shouldInclude)), - "Did not find '" + shouldInclude + "' in " + name); - } - public Output assertStdErrContains(String shouldInclude) { - assertContains(stderr, shouldInclude, "stderr"); - return this; - } - - public Output assertStdOutContains(String shouldInclude) { - assertContains(stdout, shouldInclude, "stdout"); - return this; - } + public OutputAnalyzer runInNewProcess(Class target, boolean useSpec, String... programArgs) throws IOException, InterruptedException { + return runInNewProcess(target, useSpec, List.of(), List.of(programArgs)); } - public Output runInNewProcess(Class target, boolean useSpec, String... programArgs) throws IOException, InterruptedException { + public OutputAnalyzer runInNewProcess(Class target, boolean useSpec, List vmArgs, List programArgs) throws IOException, InterruptedException { assert !target.isArray(); List command = new ArrayList<>(List.of( "--enable-native-access=ALL-UNNAMED", "-Djava.library.path=" + System.getProperty("java.library.path"), - "-Djdk.internal.foreign.UpcallLinker.USE_SPEC=" + useSpec, - target.getName() + "-Djdk.internal.foreign.UpcallLinker.USE_SPEC=" + useSpec )); - command.addAll(Arrays.asList(programArgs)); + command.addAll(vmArgs); + command.add(target.getName()); + command.addAll(programArgs); Process process = ProcessTools.createTestJavaProcessBuilder(command).start(); - int result = process.waitFor(); - assertNotEquals(result, 0); - - List outLines = linesFromStream(process.getInputStream()); - outLines.forEach(System.out::println); - List errLines = linesFromStream(process.getErrorStream()); - errLines.forEach(System.err::println); + long timeOut = (long) (Utils.TIMEOUT_FACTOR * 1L); + boolean completed = process.waitFor(timeOut, TimeUnit.MINUTES); + assertTrue(completed, "Time out while waiting for process"); - return new Output(outLines, errLines); - } + OutputAnalyzer output = new OutputAnalyzer(process); + output.outputTo(System.out); + output.errorTo(System.err); - private static List linesFromStream(InputStream stream) throws IOException { - try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { - return reader.lines().toList(); - } + return output; } } diff --git a/test/jdk/java/foreign/critical/TestCriticalUpcall.java b/test/jdk/java/foreign/critical/TestCriticalUpcall.java index fe19720bf9335..862c008b0808a 100644 --- a/test/jdk/java/foreign/critical/TestCriticalUpcall.java +++ b/test/jdk/java/foreign/critical/TestCriticalUpcall.java @@ -43,7 +43,9 @@ public class TestCriticalUpcall extends UpcallTestHelper { @Test public void testUpcallFailure() throws IOException, InterruptedException { // test to see if we catch a trivial downcall doing an upcall - runInNewProcess(Runner.class, true).assertStdOutContains("wrong thread state for upcall"); + runInNewProcess(Runner.class, true) + .shouldNotHaveExitValue(0) + .stdoutShouldContain("wrong thread state for upcall"); } public static class Runner extends NativeTestHelper { diff --git a/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java b/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java index d78e1a293d7c5..fadcdf1ba2446 100644 --- a/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java +++ b/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java @@ -53,7 +53,9 @@ public void testNoHeapArgs() throws Throwable { @Test(dataProvider = "specs") public void testNoHeapReturns(boolean spec) throws IOException, InterruptedException { - runInNewProcess(Runner.class, spec).assertStdErrContains("Heap segment not allowed"); + runInNewProcess(Runner.class, spec) + .shouldNotHaveExitValue(0) + .stderrShouldContain("Heap segment not allowed"); } public static class Runner { diff --git a/test/jdk/java/io/ByteArrayInputStream/TransferToTrusted.java b/test/jdk/java/io/ByteArrayInputStream/TransferToTrusted.java new file mode 100644 index 0000000000000..24b2209e814f0 --- /dev/null +++ b/test/jdk/java/io/ByteArrayInputStream/TransferToTrusted.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8321053 + * @summary Verify ByteArrayInputStream.buf is used directly by + * ByteArrayInputStream.transferTo only when its OutputStream + * parameter is trusted + * @key randomness + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Objects; +import java.util.Random; + +public class TransferToTrusted { + private static final Random RND = new Random(System.nanoTime()); + + private static class UntrustedOutputStream extends OutputStream { + UntrustedOutputStream() { + super(); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + Objects.checkFromIndexSize(off, len, b.length); + byte[] tmp = new byte[len]; + RND.nextBytes(tmp); + System.arraycopy(tmp, 0, b, off, len); + } + + @Override + public void write(int b) throws IOException { + write(new byte[] {(byte)b}); + } + } + + public static void main(String[] args) throws IOException { + byte[] buf = new byte[RND.nextInt(1025)]; + System.out.println("buf.length: " + buf.length); + RND.nextBytes(buf); + byte[] dup = Arrays.copyOf(buf, buf.length); + + ByteArrayInputStream bais = new ByteArrayInputStream(dup); + bais.mark(dup.length); + + OutputStream[] outputStreams = new OutputStream[] { + new ByteArrayOutputStream(), + new UntrustedOutputStream() + }; + + for (OutputStream out : outputStreams) { + System.err.println("out: " + out.getClass().getName()); + + bais.transferTo(out); + bais.reset(); + try { + if (!Arrays.equals(buf, bais.readAllBytes())) + throw new RuntimeException("Internal buffer was modified"); + } finally { + out.close(); + } + bais.reset(); + } + } +} diff --git a/test/jdk/java/lang/Class/UnnamedClass/TestUnnamedClass.java b/test/jdk/java/lang/Class/UnnamedClass/TestUnnamedClass.java deleted file mode 100644 index 9e4635ab932c1..0000000000000 --- a/test/jdk/java/lang/Class/UnnamedClass/TestUnnamedClass.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8306112 - * @enablePreview - * @build Unnamed TestUnnamedClass - * @run main TestUnnamedClass - * @summary Basic checks of java.lang.Class support for unnamed classes - */ - -import java.lang.reflect.Modifier; - -public class TestUnnamedClass { - public static void main(String... args) throws Exception { - Class unnamedClass = Class.forName("Unnamed"); - - /* - * From JEP 445 JLS changes: - * - * "An unnamed class compilation unit implicitly declares a class that satisfies the following - * properties: - * It is always a top level class. - * It is always an unnamed class (it has no canonical or fully qualified name (6.7)). - * It is never abstract (8.1.1.1). - * It is always final (8.1.1.2). - * It is always a member of an unnamed package (7.4.2) and has package access. - * Its direct superclass type is always Object (8.1.4). - * It never has any direct superinterface types (8.1.5). - */ - - check(unnamedClass.isUnnamedClass(), "Unnamed class was isUnnamedClass() false"); - - check(!(unnamedClass.isInterface() || - unnamedClass.isEnum() || - unnamedClass.isRecord() || - unnamedClass.isHidden()), - "Unnamed class was not a normal class"); - - check(!(unnamedClass.isLocalClass() || - unnamedClass.isMemberClass() || - unnamedClass.isPrimitive() || - unnamedClass.isArray()), - "Unnamed class was not top-level"); - - check("Unnamed".equals(unnamedClass.getName()), "Unexpected Class.getName result"); - check("Unnamed".equals(unnamedClass.getTypeName()), "Unexpected Class.getTypeName result"); - check("".equals(unnamedClass.getSimpleName()), "Unexpected Class.getSimpleName result"); - check(unnamedClass.getCanonicalName() == null, "Unexpected non-null Class.getCanonicalName"); - - int modifiers = unnamedClass.getModifiers(); - check((modifiers & Modifier.ABSTRACT) == 0, "Unnamed class was abstract"); - check((modifiers & Modifier.FINAL) != 0, "Unnamed class was not final"); - check((modifiers & (Modifier.PUBLIC | - Modifier.PRIVATE | - Modifier.PROTECTED)) == 0, "Unnamed class was not package access"); - - check(unnamedClass.isSynthetic(), "Unnamed class was not synthetic"); - - check("".equals(unnamedClass.getPackage().getName()), "Unnamed class not in an unnamed package"); - - check(unnamedClass.getSuperclass() == Object.class, "Superclass was not java.lang.Object"); - - check(unnamedClass.getInterfaces().length == 0, "Unnamed class had super interfaces"); - } - - private static void check(boolean predicate, String message) { - if (!predicate) { - throw new RuntimeException(message); - } - } -} diff --git a/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java b/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java index 7f335d15eddaf..08342caeb75d1 100644 --- a/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java +++ b/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java @@ -26,10 +26,8 @@ * @bug 8168423 * @summary Different types of ClassLoader running with(out) SecurityManager and * (in)valid security policy file. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.module + * @enablePreview + * @modules java.base/jdk.internal.module * @library /test/lib * @build jdk.test.lib.util.JarUtils * jdk.test.lib.util.ModuleInfoWriter diff --git a/test/jdk/java/lang/ModuleTests/AnnotationsTest.java b/test/jdk/java/lang/ModuleTests/AnnotationsTest.java index 724b757cf7b16..479230ad75aaa 100644 --- a/test/jdk/java/lang/ModuleTests/AnnotationsTest.java +++ b/test/jdk/java/lang/ModuleTests/AnnotationsTest.java @@ -50,11 +50,9 @@ /** * @test + * @enablePreview * @modules java.base/jdk.internal.org.objectweb.asm * java.base/jdk.internal.org.objectweb.asm.commons - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool * java.base/jdk.internal.module * @library /test/lib * @build jdk.test.lib.util.ModuleInfoWriter diff --git a/test/jdk/java/lang/String/Chars.java b/test/jdk/java/lang/String/Chars.java index ab6771b8e0b04..035a7a9de27f4 100644 --- a/test/jdk/java/lang/String/Chars.java +++ b/test/jdk/java/lang/String/Chars.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,10 +22,12 @@ */ /* - @test - @bug 8054307 - @summary test chars() and codePoints() -*/ + * @test + * @bug 8054307 8311906 8321514 + * @summary test String chars() and codePoints() + * @run main/othervm -XX:+CompactStrings Chars + * @run main/othervm -XX:-CompactStrings Chars + */ import java.util.Arrays; import java.util.Random; @@ -44,6 +46,8 @@ public static void main(String[] args) { cc[j] = (char)(ccExp[j] = cpExp[j] = r.nextInt(0x80)); } testChars(cc, ccExp); + testCharsSubrange(cc, ccExp); + testIntsSubrange(ccExp); testCPs(cc, cpExp); // bmp without surrogates @@ -51,6 +55,7 @@ public static void main(String[] args) { cc[j] = (char)(ccExp[j] = cpExp[j] = r.nextInt(0x8000)); } testChars(cc, ccExp); + testCharsSubrange(cc, ccExp); testCPs(cc, cpExp); // bmp with surrogates @@ -69,6 +74,8 @@ public static void main(String[] args) { } cpExp = Arrays.copyOf(cpExp, k); testChars(cc, ccExp); + testCharsSubrange(cc, ccExp); + testIntsSubrange(ccExp); testCPs(cc, cpExp); } } @@ -76,14 +83,56 @@ public static void main(String[] args) { static void testChars(char[] cc, int[] expected) { String str = new String(cc); if (!Arrays.equals(expected, str.chars().toArray())) { - throw new RuntimeException("chars/codePoints() failed!"); + throw new RuntimeException("testChars failed!"); + } + } + + static void testCharsSubrange(char[] cc, int[] expected) { + int[] offsets = { 7, 31 }; // offsets to test + int LENGTH = 13; + for (int i = 0; i < offsets.length; i++) { + int offset = Math.max(0, offsets[i]); // confine to the input array + int count = Math.min(LENGTH, cc.length - offset); + String str = new String(cc, offset, count); + int[] actual = str.chars().toArray(); + int errOffset = Arrays.mismatch(actual, 0, actual.length, + expected, offset, offset + count); + if (errOffset >= 0) { + System.err.printf("expected[%d] (%d) != actual[%d] (%d)%n", + offset + errOffset, expected[offset + errOffset], + errOffset, actual[errOffset]); + System.err.println("expected: " + Arrays.toString(expected)); + System.err.println("actual: " + Arrays.toString(actual)); + throw new RuntimeException("testCharsSubrange failed!"); + } + } + } + + static void testIntsSubrange(int[] expected) { + int[] offsets = { 7, 31 }; // offsets to test + int LENGTH = 13; + for (int i = 0; i < offsets.length; i++) { + int offset = Math.max(0, offsets[i]); // confine to the input array + int count = Math.min(LENGTH, expected.length - offset); + String str = new String(expected, offset, count); + int[] actual = str.chars().toArray(); + int errOffset = Arrays.mismatch(actual, 0, actual.length, + expected, offset, offset + count); + if (errOffset >= 0) { + System.err.printf("expected[%d] (%d) != actual[%d] (%d)%n", + offset + errOffset, expected[offset + errOffset], + errOffset, actual[errOffset]); + System.err.println("expected: " + Arrays.toString(expected)); + System.err.println("actual: " + Arrays.toString(actual)); + throw new RuntimeException("testIntsSubrange failed!"); + } } } static void testCPs(char[] cc, int[] expected) { String str = new String(cc); if (!Arrays.equals(expected, str.codePoints().toArray())) { - throw new RuntimeException("chars/codePoints() failed!"); + throw new RuntimeException("testCPs failed!"); } } } diff --git a/test/jdk/java/lang/String/CompactString/MaxSizeUTF16String.java b/test/jdk/java/lang/String/CompactString/MaxSizeUTF16String.java new file mode 100644 index 0000000000000..15fe3f8f7253f --- /dev/null +++ b/test/jdk/java/lang/String/CompactString/MaxSizeUTF16String.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +import java.nio.charset.StandardCharsets; + +/* + * @test + * @bug 8077559 8321180 + * @summary Tests Compact String for maximum size strings + * @requires os.maxMemory >= 7g & vm.bits == 64 + * @run junit/othervm -XX:+CompactStrings -Xmx7g MaxSizeUTF16String + * @run junit/othervm -XX:-CompactStrings -Xmx7g MaxSizeUTF16String + */ + +public class MaxSizeUTF16String { + + private final static int MAX_UTF16_STRING_LENGTH = Integer.MAX_VALUE / 2; + + private final static String EXPECTED_OOME_MESSAGE = "UTF16 String size is"; + + // Create a large UTF-8 byte array with a single non-latin1 character + private static byte[] generateUTF8Data(int byteSize) { + byte[] nonAscii = "\u0100".getBytes(StandardCharsets.UTF_8); + byte[] arr = new byte[byteSize]; + System.arraycopy(nonAscii, 0, arr, 0, nonAscii.length); // non-latin1 at start + return arr; + } + + // Create a large char array with a single non-latin1 character + private static char[] generateCharData(int size) { + char[] nonAscii = "\u0100".toCharArray(); + char[] arr = new char[size]; + System.arraycopy(nonAscii, 0, arr, 0, nonAscii.length); // non-latin1 at start + return arr; + } + + @Test + public void testMaxUTF8() { + // Overly large UTF-8 data with 1 non-latin1 char + final byte[] large_utf8_bytes = generateUTF8Data(MAX_UTF16_STRING_LENGTH + 1); + int[] sizes = new int[] { + MAX_UTF16_STRING_LENGTH + 1, + MAX_UTF16_STRING_LENGTH, + MAX_UTF16_STRING_LENGTH - 1}; + for (int size : sizes) { + System.err.println("Checking max UTF16 string len: " + size); + try { + // Use only part of the UTF-8 byte array + new String(large_utf8_bytes, 0, size, StandardCharsets.UTF_8); + if (size >= MAX_UTF16_STRING_LENGTH) { + fail("Expected OutOfMemoryError with message prefix: " + EXPECTED_OOME_MESSAGE); + } + } catch (OutOfMemoryError ex) { + if (!ex.getMessage().startsWith(EXPECTED_OOME_MESSAGE)) { + fail("Failed: Not the OutOfMemoryError expected", ex); + } + } + } + } + + @Test + public void testMaxCharArray() { + // Overly large UTF-8 data with 1 non-latin1 char + final char[] large_char_array = generateCharData(MAX_UTF16_STRING_LENGTH + 1); + int[] sizes = new int[]{ + MAX_UTF16_STRING_LENGTH + 1, + MAX_UTF16_STRING_LENGTH, + MAX_UTF16_STRING_LENGTH - 1}; + for (int size : sizes) { + System.err.println("Checking max UTF16 string len: " + size); + try { + // Large char array with 1 non-latin1 char + new String(large_char_array, 0, size); + if (size >= MAX_UTF16_STRING_LENGTH) { + fail("Expected OutOfMemoryError with message prefix: " + EXPECTED_OOME_MESSAGE); + } + } catch (OutOfMemoryError ex) { + if (!ex.getMessage().startsWith(EXPECTED_OOME_MESSAGE)) { + throw new RuntimeException("Wrong exception message: " + ex.getMessage(), ex); + } + } + } + } +} diff --git a/test/jdk/java/lang/String/CompactString/NegativeSize.java b/test/jdk/java/lang/String/CompactString/NegativeSize.java new file mode 100644 index 0000000000000..a218c5f18f8d7 --- /dev/null +++ b/test/jdk/java/lang/String/CompactString/NegativeSize.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +/* + * @test + * @bug 8077559 + * @summary Tests Compact String for negative size. + * @requires vm.bits == 64 & os.maxMemory >= 4G + * @run main/othervm -XX:+CompactStrings -Xmx4g NegativeSize + * @run main/othervm -XX:-CompactStrings -Xmx4g NegativeSize + */ + +// In Java8: java.lang.OutOfMemoryError: Java heap space +// In Java9+: was java.lang.NegativeArraySizeException: -1894967266 +public class NegativeSize { + + static byte[] generateData() { + int asciisize = 1_200_000_000; + byte[] nonAscii = "非アスキー".getBytes(); + int nonAsciiSize = nonAscii.length; + // 1 GB + byte[] arr = new byte[asciisize + nonAsciiSize]; + for (int i=0; i strings() { + return List.of("01234", " "); + } + + @ParameterizedTest + @MethodSource("strings") + @EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings") + public void racyString(String orig) { + String racyString = racyStringConstruction(orig); + // The contents are indeterminate due to the race + assertTrue(validCoder(racyString), orig + " string invalid" + + ", racyString: " + inspectString(racyString)); + } + + @ParameterizedTest + @MethodSource("strings") + @EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings") + public void racyCodePoint(String orig) { + String iffyString = racyStringConstructionCodepoints(orig); + // The contents are indeterminate due to the race + assertTrue(validCoder(iffyString), "invalid coder in non-deterministic string" + + ", orig:" + inspectString(orig) + + ", iffyString: " + inspectString(iffyString)); + } + + @ParameterizedTest + @MethodSource("strings") + @EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings") + public void racyCodePointSurrogates(String orig) { + String iffyString = racyStringConstructionCodepointsSurrogates(orig); + // The contents are indeterminate due to the race + if (!orig.equals(iffyString)) + System.err.println("orig: " + orig + ", iffy: " + iffyString + Arrays.toString(iffyString.codePoints().toArray())); + assertTrue(validCoder(iffyString), "invalid coder in non-deterministic string" + + ", orig:" + inspectString(orig) + + ", iffyString: " + inspectString(iffyString)); + } + + // Test the private methods of StringUTF16 that compress and copy COMPRESSED_STRING + // encoded byte arrays. + @Test + public void verifyUTF16CopyBytes() + throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class stringUTF16 = Class.forName("java.lang.StringUTF16"); + Method mCompressChars = stringUTF16.getDeclaredMethod("compress", + char[].class, int.class, byte[].class, int.class, int.class); + mCompressChars.setAccessible(true); + + // First warmup the intrinsic and check 1 case + char[] chars = {'a', 'b', 'c', 0xff21, 0xff22, 0xff23}; + byte[] bytes = new byte[chars.length]; + int printWarningCount = 0; + + for (int i = 0; i < 1_000_000; i++) { // repeat to get C2 to kick in + // Copy only latin1 chars from UTF-16 converted prefix (3 chars -> 3 bytes) + int intResult = (int) mCompressChars.invoke(null, chars, 0, bytes, 0, chars.length); + if (intResult == 0) { + if (printWarningCount == 0) { + printWarningCount = 1; + System.err.println("Intrinsic for StringUTF16.compress returned 0, may not have been updated."); + } + } else { + assertEquals(3, intResult, "return length not-equal, iteration: " + i); + } + } + + // Exhaustively check compress returning the correct index of the non-latin1 char. + final int SIZE = 48; + final byte FILL_BYTE = 'R'; + chars = new char[SIZE]; + bytes = new byte[chars.length]; + for (int i = 0; i < SIZE; i++) { // Every starting index + for (int j = i; j < SIZE; j++) { // Every location of non-latin1 + Arrays.fill(chars, 'A'); + Arrays.fill(bytes, FILL_BYTE); + chars[j] = 0xFF21; + int intResult = (int) mCompressChars.invoke(null, chars, i, bytes, 0, chars.length - i); + assertEquals(j - i, intResult, "compress found wrong index"); + assertEquals(FILL_BYTE, bytes[j], "extra character stored"); + } + } + + } + + // Check that a concatenated "hello" has a valid coder + @Test + @EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings") + public void checkConcatAndIntern() { + var helloWorld = "hello world"; + String helloToo = racyStringConstruction("hell".concat("o")); + String o = helloToo.intern(); + var hello = "hello"; + assertTrue(validCoder(helloToo), "startsWith: " + + ", hell: " + inspectString(helloToo) + + ", o: " + inspectString(o) + + ", hello: " + inspectString(hello) + + ", hello world: " + inspectString(helloWorld)); + } + + // Check that an empty string with racy construction has a valid coder + @Test + @EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings") + public void racyEmptyString() { + var space = racyStringConstruction(" "); + var trimmed = space.trim(); + assertTrue(validCoder(trimmed), "empty string invalid coder" + + ", trimmed: " + inspectString(trimmed)); + } + + // Check that an exception in a user implemented CharSequence doesn't result in + // an invalid coder when appended to a StringBuilder + @Test + @EnabledIf("test.java.lang.String.StringRacyConstructor#isCompactStrings") + void charSequenceException() { + ThrowingCharSequence bs = new ThrowingCharSequence("A\u2030\uFFFD"); + var sb = new StringBuilder(); + try { + sb.append(bs); + fail("An IllegalArgumentException should have been thrown"); + } catch (IllegalArgumentException ex) { + // ignore expected + } + assertTrue(validCoder(sb), "invalid coder in StringBuilder"); + } + + /** + * Given a latin-1 String, attempt to create a copy that is + * incorrectly encoded as UTF-16. + */ + public static String racyStringConstruction(String original) throws ConcurrentModificationException { + if (original.chars().max().getAsInt() >= 256) { + throw new IllegalArgumentException( + "Only work with latin-1 Strings"); + } + + char[] chars = original.toCharArray(); + + // In another thread, flip the first character back + // and forth between being latin-1 or not + Thread thread = new Thread(() -> { + while (!Thread.interrupted()) { + chars[0] ^= 256; + } + }); + thread.start(); + + // at the same time call the String constructor, + // until we hit the race condition + int i = 0; + while (true) { + i++; + String s = new String(chars); + if ((s.charAt(0) < 256 && !original.equals(s)) || i > 1_000_000) { + thread.interrupt(); + try { + thread.join(); + } catch (InterruptedException ie) { + // ignore interrupt + } + return s; + } + } + } + + /** + * Given a latin-1 String, creates a copy that is + * incorrectly encoded as UTF-16 using the APIs for Codepoints. + */ + public static String racyStringConstructionCodepoints(String original) throws ConcurrentModificationException { + if (original.chars().max().getAsInt() >= 256) { + throw new IllegalArgumentException( + "Can only work with latin-1 Strings"); + } + + int len = original.length(); + int[] codePoints = new int[len]; + for (int i = 0; i < len; i++) { + codePoints[i] = original.charAt(i); + } + + // In another thread, flip the first character back + // and forth between being latin-1 or not + Thread thread = new Thread(() -> { + while (!Thread.interrupted()) { + codePoints[0] ^= 256; + } + }); + thread.start(); + + // at the same time call the String constructor, + // until we hit the race condition + int i = 0; + while (true) { + i++; + String s = new String(codePoints, 0, len); + if ((s.charAt(0) < 256 && !original.equals(s)) || i > 1_000_000) { + thread.interrupt(); + try { + thread.join(); + } catch (InterruptedException ie) { + // ignore interrupt + } + return s; + } + } + } + + /** + * Returns a string created from a codepoint array that has been racily + * modified to contain high and low surrogates. The string is a different length + * than the original due to the surrogate encoding. + */ + public static String racyStringConstructionCodepointsSurrogates(String original) throws ConcurrentModificationException { + if (original.chars().max().getAsInt() >= 256) { + throw new IllegalArgumentException( + "Can only work with latin-1 Strings"); + } + + int len = original.length(); + int[] codePoints = new int[len]; + for (int i = 0; i < len; i++) { + codePoints[i] = original.charAt(i); + } + + // In another thread, flip the first character back + // and forth between being latin-1 or as a surrogate pair. + Thread thread = new Thread(() -> { + while (!Thread.interrupted()) { + codePoints[0] ^= 0x10000; + } + }); + thread.start(); + + // at the same time call the String constructor, + // until we hit the race condition + int i = 0; + while (true) { + i++; + String s = new String(codePoints, 0, len); + if ((s.length() != original.length()) || i > 1_000_000) { + thread.interrupt(); + try { + thread.join(); + } catch (InterruptedException ie) { + // ignore interrupt + } + return s; + } + } + } + + // A CharSequence that returns characters from a string and throws IllegalArgumentException + // when the character requested is 0xFFFD (the replacement character) + // The string contents determine when the exception is thrown. + static class ThrowingCharSequence implements CharSequence { + private final String aString; + + ThrowingCharSequence(String aString) { + this.aString = aString; + } + + @Override + public int length() { + return aString.length(); + } + + @Override + public char charAt(int index) { + char ch = aString.charAt(index); + if (ch == 0xFFFD) { + throw new IllegalArgumentException("Replacement character at index " + index); + } + return ch; + } + + @Override + // Not used; returns the entire string + public CharSequence subSequence(int start, int end) { + return this; + } + } +} diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForImageTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForImageTest.java index b155ba994a64b..120bba40e0e37 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForImageTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForImageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm JDKLoggerForImageTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForJDKTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForJDKTest.java index 68bc6fd839bdb..8c25b062002f6 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForJDKTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/JDKLoggerForJDKTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ * 2. clients are in named/unnamed module, * patched system module, or Xbootclasspath * This test DOES require existence of java.logging module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm JDKLoggerForJDKTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/LoggerInImageTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/LoggerInImageTest.java index d3c3ace5a6507..2cc510e7f9950 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/LoggerInImageTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/LoggerInImageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm LoggerInImageTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForImageTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForImageTest.java index 2e621597935c9..df14801c1647b 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForImageTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForImageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm NamedLoggerForImageTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForJDKTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForJDKTest.java index 6abf98c52279a..e48cf4786c705 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForJDKTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/NamedLoggerForJDKTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm NamedLoggerForJDKTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForImageTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForImageTest.java index 038c96697cb71..26f6246bb85fe 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForImageTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForImageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm UnnamedLoggerForImageTest diff --git a/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForJDKTest.java b/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForJDKTest.java index b239483b0b78f..74a76756162bf 100644 --- a/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForJDKTest.java +++ b/test/jdk/java/lang/System/LoggerFinder/modules/UnnamedLoggerForJDKTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ * patched system module, or Xbootclasspath * This test does not require existence of java.logging module, * but require jdk.compiler module + * @requires vm.flagless * @library /test/lib * @build Base jdk.test.lib.compiler.CompilerUtils * @run main/othervm UnnamedLoggerForJDKTest diff --git a/test/jdk/java/lang/Thread/DegradedMethodsThrowUOE.java b/test/jdk/java/lang/Thread/ThreadStopTest.java similarity index 57% rename from test/jdk/java/lang/Thread/DegradedMethodsThrowUOE.java rename to test/jdk/java/lang/Thread/ThreadStopTest.java index b16b70eaff079..f3886a3312cc4 100644 --- a/test/jdk/java/lang/Thread/DegradedMethodsThrowUOE.java +++ b/test/jdk/java/lang/Thread/ThreadStopTest.java @@ -22,60 +22,43 @@ */ /* @test - * @bug 8289610 8249627 8205132 - * @summary Test that Thread stop/suspend/resume throw UOE - * @run junit DegradedMethodsThrowUOE + * @bug 8289610 8249627 8205132 8320532 + * @summary Test that Thread stops throws UOE + * @run junit ThreadStopTest */ import java.time.Duration; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.LockSupport; -import java.util.function.Consumer; -import java.util.stream.Stream; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; -class DegradedMethodsThrowUOE { +class ThreadStopTest { /** - * Returns a stream of operations on a Thread that should throw UOE. + * Test current thread calling Thread.stop on itself. */ - static Stream> ops() { - return Stream.>of( - Thread::stop, - Thread::suspend, - Thread::resume - ); - } - - /** - * Test degraded method on current thread. - */ - @ParameterizedTest - @MethodSource("ops") - void testCurrentThread(Consumer op) { + @Test + void testCurrentThread() { var thread = Thread.currentThread(); - assertThrows(UnsupportedOperationException.class, () -> op.accept(thread)); + assertThrows(UnsupportedOperationException.class, thread::stop); } /** - * Test degraded method on an unstarted thread. + * Test Thread.stop on an unstarted thread. */ - @ParameterizedTest - @MethodSource("ops") - void testUnstartedThread(Consumer op) { + @Test + void testUnstartedThread() { Thread thread = new Thread(() -> { }); - assertThrows(UnsupportedOperationException.class, () -> op.accept(thread)); + assertThrows(UnsupportedOperationException.class, thread::stop); assertTrue(thread.getState() == Thread.State.NEW); } /** - * Test degraded method on a thread spinning in a loop. + * Test Thread.stop on a thread spinning in a loop. */ - @ParameterizedTest - @MethodSource("ops") - void testRunnableThread(Consumer op) throws Exception { + @Test + void testRunnableThread() throws Exception { AtomicBoolean done = new AtomicBoolean(); Thread thread = new Thread(() -> { while (!done.get()) { @@ -84,7 +67,7 @@ void testRunnableThread(Consumer op) throws Exception { }); thread.start(); try { - assertThrows(UnsupportedOperationException.class, () -> op.accept(thread)); + assertThrows(UnsupportedOperationException.class, thread::stop); // thread should not terminate boolean terminated = thread.join(Duration.ofMillis(500)); @@ -96,11 +79,10 @@ void testRunnableThread(Consumer op) throws Exception { } /** - * Test degraded method on a thread that is parked. + * Test Thread.stop on a thread that is parked. */ - @ParameterizedTest - @MethodSource("ops") - void testWaitingThread(Consumer op) throws Exception { + @Test + void testWaitingThread() throws Exception { Thread thread = new Thread(LockSupport::park); thread.start(); try { @@ -108,7 +90,7 @@ void testWaitingThread(Consumer op) throws Exception { while ((thread.getState() != Thread.State.WAITING)) { Thread.sleep(10); } - assertThrows(UnsupportedOperationException.class, () -> op.accept(thread)); + assertThrows(UnsupportedOperationException.class, thread::stop); assertTrue(thread.getState() == Thread.State.WAITING); } finally { LockSupport.unpark(thread); @@ -117,15 +99,14 @@ void testWaitingThread(Consumer op) throws Exception { } /** - * Test degraded method on a terminated thread. + * Test Thread.stop on a terminated thread. */ - @ParameterizedTest - @MethodSource("ops") - void testTerminatedThread(Consumer op) throws Exception { + @Test + void testTerminatedThread() throws Exception { Thread thread = new Thread(() -> { }); thread.start(); thread.join(); - assertThrows(UnsupportedOperationException.class, () -> op.accept(thread)); + assertThrows(UnsupportedOperationException.class, thread::stop); assertTrue(thread.getState() == Thread.State.TERMINATED); } } diff --git a/test/jdk/java/lang/Thread/virtual/ThreadAPI.java b/test/jdk/java/lang/Thread/virtual/ThreadAPI.java index 27d21a793460b..3371b5bc9e755 100644 --- a/test/jdk/java/lang/Thread/virtual/ThreadAPI.java +++ b/test/jdk/java/lang/Thread/virtual/ThreadAPI.java @@ -23,7 +23,7 @@ /* * @test id=default - * @bug 8284161 8286788 + * @bug 8284161 8286788 8321270 * @summary Test Thread API with virtual threads * @modules java.base/java.lang:+open * @library /test/lib @@ -273,64 +273,6 @@ void testStop2() throws Exception { } } - /** - * Test Thread::suspend from current thread. - */ - @Test - void testSuspend1() throws Exception { - VThreadRunner.run(() -> { - Thread t = Thread.currentThread(); - assertThrows(UnsupportedOperationException.class, t::suspend); - }); - } - - /** - * Test Thread::suspend from another thread. - */ - @Test - void testSuspend2() throws Exception { - var thread = Thread.ofVirtual().start(() -> { - try { - Thread.sleep(20*1000); - } catch (InterruptedException e) { } - }); - try { - assertThrows(UnsupportedOperationException.class, () -> thread.suspend()); - } finally { - thread.interrupt(); - thread.join(); - } - } - - /** - * Test Thread::resume from current thread. - */ - @Test - void testResume1() throws Exception { - VThreadRunner.run(() -> { - Thread t = Thread.currentThread(); - assertThrows(UnsupportedOperationException.class, t::resume); - }); - } - - /** - * Test Thread::resume from another thread. - */ - @Test - void testResume2() throws Exception { - var thread = Thread.ofVirtual().start(() -> { - try { - Thread.sleep(20*1000); - } catch (InterruptedException e) { } - }); - try { - assertThrows(UnsupportedOperationException.class, () -> thread.resume()); - } finally { - thread.interrupt(); - thread.join(); - } - } - /** * Test Thread.join before thread starts, platform thread invokes join. */ @@ -1191,6 +1133,36 @@ void testYield2() throws Exception { assertEquals(List.of("A", "A", "B"), list); } + /** + * Test that Thread.yield does not consume the thread's parking permit. + */ + @Test + void testYield3() throws Exception { + var thread = Thread.ofVirtual().start(() -> { + LockSupport.unpark(Thread.currentThread()); + Thread.yield(); + LockSupport.park(); // should not park + }); + thread.join(); + } + + /** + * Test that Thread.yield does not make available the thread's parking permit. + */ + @Test + void testYield4() throws Exception { + var thread = Thread.ofVirtual().start(() -> { + Thread.yield(); + LockSupport.park(); // should park + }); + try { + await(thread, Thread.State.WAITING); + } finally { + LockSupport.unpark(thread); + thread.join(); + } + } + /** * Test Thread.onSpinWait. */ diff --git a/test/jdk/java/lang/ThreadGroup/BasicTests.java b/test/jdk/java/lang/ThreadGroup/BasicTests.java index 2c6cf6dbca75a..ccd8a0153c399 100644 --- a/test/jdk/java/lang/ThreadGroup/BasicTests.java +++ b/test/jdk/java/lang/ThreadGroup/BasicTests.java @@ -732,24 +732,6 @@ void testList() { group.list(); } - @Test - void testSuspend() { - ThreadGroup group = new ThreadGroup("foo"); - assertThrows(UnsupportedOperationException.class, () -> group.suspend()); - } - - @Test - void testResume() { - ThreadGroup group = new ThreadGroup("foo"); - assertThrows(UnsupportedOperationException.class, () -> group.resume()); - } - - @Test - void testStop() { - ThreadGroup group = new ThreadGroup("foo"); - assertThrows(UnsupportedOperationException.class, () -> group.stop()); - } - @Test void testNull1() { assertThrows(NullPointerException.class, diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/BasicTest.java b/test/jdk/java/lang/invoke/MethodHandleProxies/BasicTest.java index 656083e3a6e3d..cd013f9f543a9 100644 --- a/test/jdk/java/lang/invoke/MethodHandleProxies/BasicTest.java +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/BasicTest.java @@ -21,8 +21,8 @@ * questions. */ -import jdk.internal.classfile.ClassHierarchyResolver; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassHierarchyResolver; +import java.lang.classfile.ClassFile; import org.junit.jupiter.api.Test; import java.io.Closeable; @@ -50,15 +50,13 @@ import static java.lang.invoke.MethodHandleProxies.*; import static java.lang.invoke.MethodType.genericMethodType; import static java.lang.invoke.MethodType.methodType; -import static jdk.internal.classfile.Classfile.*; +import static java.lang.classfile.ClassFile.*; import static org.junit.jupiter.api.Assertions.*; /* * @test * @bug 6983726 8206955 8269351 - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool + * @enablePreview * @summary Basic sanity tests for MethodHandleProxies * @build BasicTest Client * @run junit BasicTest @@ -287,7 +285,7 @@ private List> loadBaseAndChild() throws IllegalAccessException { var objMtd = MethodTypeDesc.of(CD_Object); var integerMtd = MethodTypeDesc.of(CD_Integer); var intMtd = MethodTypeDesc.of(CD_int); - var classfile = Classfile.of(Classfile.ClassHierarchyResolverOption.of(ClassHierarchyResolver.defaultResolver().orElse( + var classfile = ClassFile.of(ClassFile.ClassHierarchyResolverOption.of(ClassHierarchyResolver.defaultResolver().orElse( ClassHierarchyResolver.of(List.of(baseCd, childCd), Map.ofEntries(Map.entry(baseCd, CD_Object), Map.entry(childCd, CD_Object)))))); diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/WrapperHiddenClassTest.java b/test/jdk/java/lang/invoke/MethodHandleProxies/WrapperHiddenClassTest.java index d3d488385ae9c..435f59fe755c4 100644 --- a/test/jdk/java/lang/invoke/MethodHandleProxies/WrapperHiddenClassTest.java +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/WrapperHiddenClassTest.java @@ -21,7 +21,7 @@ * questions. */ -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import jdk.test.lib.util.ForceGC; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -39,16 +39,14 @@ import static java.lang.constant.ConstantDescs.*; import static java.lang.invoke.MethodHandleProxies.*; import static java.lang.invoke.MethodType.methodType; -import static jdk.internal.classfile.Classfile.*; +import static java.lang.classfile.ClassFile.*; import static org.junit.jupiter.api.Assertions.*; /* * @test * @bug 6983726 * @library /test/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool + * @enablePreview * @summary Tests on implementation hidden classes spinned by MethodHandleProxies * @build WrapperHiddenClassTest Client jdk.test.lib.util.ForceGC * @run junit WrapperHiddenClassTest @@ -85,7 +83,7 @@ public void testWrapperInstance() throws Throwable { // Update this template when the MHP template is updated @SuppressWarnings("unchecked") private Comparator createHostileInstance() throws Throwable { - var cf = Classfile.of(); + var cf = ClassFile.of(); var bytes = cf.build(CD_HostileWrapper, clb -> { clb.withSuperclass(CD_Object); clb.withFlags(ACC_FINAL | ACC_SYNTHETIC); diff --git a/test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/InstructionHelper.java b/test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/InstructionHelper.java index cec786e67df26..722f0ee4d8f10 100644 --- a/test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/InstructionHelper.java +++ b/test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/InstructionHelper.java @@ -23,9 +23,9 @@ package test.java.lang.invoke.lib; -import jdk.internal.classfile.ClassBuilder; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.TypeKind; +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.ClassFile; +import java.lang.classfile.TypeKind; import java.lang.constant.*; import java.lang.invoke.MethodHandle; @@ -43,7 +43,7 @@ private static void commonBuild(ClassBuilder classBuilder) { classBuilder .withVersion(55, 0) .withSuperclass(ConstantDescs.CD_Object) - .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, Classfile.ACC_PUBLIC, + .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, ClassFile.ACC_PUBLIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .aload(0) @@ -55,11 +55,11 @@ private static void commonBuild(ClassBuilder classBuilder) { public static MethodHandle invokedynamic(MethodHandles.Lookup l, String name, MethodType type, String bsmMethodName, MethodType bsmType, ConstantDesc... boostrapArgs) throws Exception { ClassDesc genClassDesc = classDesc(l.lookupClass(), "$Code_" + COUNT.getAndIncrement()); - byte[] byteArray = Classfile.of().build(genClassDesc, classBuilder -> { + byte[] byteArray = ClassFile.of().build(genClassDesc, classBuilder -> { commonBuild(classBuilder); classBuilder .withMethod("m", MethodTypeDesc.ofDescriptor(type.toMethodDescriptorString()), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> { for (int i = 0; i < type.parameterCount(); i++) { codeBuilder.loadInstruction(TypeKind.from(type.parameterType(i)), i); @@ -102,10 +102,10 @@ public static MethodHandle ldcDynamicConstant(MethodHandles.Lookup l, String nam throws IllegalAccessException, NoSuchMethodException { String methodType = "()" + type; ClassDesc genClassDesc = classDesc(l.lookupClass(), "$Code_" + COUNT.getAndIncrement()); - byte[] bytes = Classfile.of().build(genClassDesc, classBuilder -> { + byte[] bytes = ClassFile.of().build(genClassDesc, classBuilder -> { commonBuild(classBuilder); classBuilder.withMethod("m", MethodTypeDesc.of(ClassDesc.ofDescriptor(type)), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( MethodHandleDesc.ofMethod( diff --git a/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java b/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java index 75b887753387e..1dc30a8de59f1 100644 --- a/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java +++ b/test/jdk/java/lang/invoke/condy/BootstrapMethodJumboArgsTest.java @@ -27,11 +27,7 @@ * @summary Test bootstrap methods throwing an exception * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng BootstrapMethodJumboArgsTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 BootstrapMethodJumboArgsTest */ diff --git a/test/jdk/java/lang/invoke/condy/CondyBSMException.java b/test/jdk/java/lang/invoke/condy/CondyBSMException.java index 4a8b5106c1224..3b0d59c3a01a0 100644 --- a/test/jdk/java/lang/invoke/condy/CondyBSMException.java +++ b/test/jdk/java/lang/invoke/condy/CondyBSMException.java @@ -27,11 +27,7 @@ * @summary Test bootstrap methods throwing an exception * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng CondyBSMException * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMException */ diff --git a/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java b/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java index 0cf51f4819b93..14eb7560a7ddd 100644 --- a/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java +++ b/test/jdk/java/lang/invoke/condy/CondyBSMInvocation.java @@ -27,11 +27,7 @@ * @summary Test basic invocation of bootstrap methods * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng CondyBSMInvocation * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMInvocation */ diff --git a/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java b/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java index d833ddd279f8d..5cfe85d064213 100644 --- a/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyBSMValidationTest.java @@ -27,11 +27,7 @@ * @summary Test invalid name in name and type * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng CondyBSMValidationTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyBSMValidationTest */ diff --git a/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java b/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java index 9ba6e3c28f764..2b2fb159e3e7b 100644 --- a/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java +++ b/test/jdk/java/lang/invoke/condy/CondyInterfaceWithOverpassMethods.java @@ -27,16 +27,12 @@ * @summary Test for an interface using condy with default overpass methods * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng CondyInterfaceWithOverpassMethods * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyInterfaceWithOverpassMethods */ -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import test.java.lang.invoke.lib.InstructionHelper; @@ -80,11 +76,11 @@ public void generateClass() throws Exception { String bsmDescriptor = MethodType.methodType(Object.class, MethodHandles.Lookup.class, String.class, Class.class).toMethodDescriptorString(); - byte[] byteArray = Classfile.of().build(ClassDesc.of(genClassName), classBuilder -> classBuilder - .withFlags(Classfile.ACC_INTERFACE + Classfile.ACC_ABSTRACT) + byte[] byteArray = ClassFile.of().build(ClassDesc.of(genClassName), classBuilder -> classBuilder + .withFlags(ClassFile.ACC_INTERFACE + ClassFile.ACC_ABSTRACT) .withSuperclass(ConstantDescs.CD_Object) .withInterfaceSymbols(InstructionHelper.classDesc(A.class)) - .withMethod("y", MethodTypeDesc.of(ConstantDescs.CD_String), Classfile.ACC_PUBLIC, methodBuilder -> methodBuilder + .withMethod("y", MethodTypeDesc.of(ConstantDescs.CD_String), ClassFile.ACC_PUBLIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( MethodHandleDesc.of( diff --git a/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java b/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java index 24a71a80edbd9..5f6e0dc04a27f 100644 --- a/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyNameValidationTest.java @@ -27,11 +27,7 @@ * @summary Test invalid name in name and type * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng CondyNameValidationTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyNameValidationTest */ diff --git a/test/jdk/java/lang/invoke/condy/CondyNestedTest.java b/test/jdk/java/lang/invoke/condy/CondyNestedTest.java index dc11c7f560ad6..53275905abb96 100644 --- a/test/jdk/java/lang/invoke/condy/CondyNestedTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyNestedTest.java @@ -26,11 +26,7 @@ * @bug 8186046 * @summary Test nested dynamic constant declarations that are recursive * @compile CondyNestedTest_Code.jcod - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng CondyNestedTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyNestedTest */ @@ -83,10 +79,10 @@ public class CondyNestedTest { // "bsmIndy", // bsmIndyDescriptor // ); -// byte[] byteArray = Classfile.of().build(ClassDesc.of(genClassName), classBuilder -> classBuilder +// byte[] byteArray = ClassFile.of().build(ClassDesc.of(genClassName), classBuilder -> classBuilder // .withVersion(55, 0) // .withSuperclass(ConstantDescs.CD_Object) -// .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, Classfile.ACC_PUBLIC, methodBuilder -> methodBuilder +// .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, ClassFile.ACC_PUBLIC, methodBuilder -> methodBuilder // .withCode(codeBuilder -> codeBuilder // .aload(0) // .invokespecial(ConstantDescs.CD_Object, ConstantDescs.INIT_NAME, ConstantDescs.MTD_void) @@ -94,7 +90,7 @@ public class CondyNestedTest { // ) // ) // .withMethod("main", MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_String.arrayType()), -// Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder +// ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder // .withCode(codeBuilder -> { // codeBuilder // .aload(0) @@ -138,7 +134,7 @@ public class CondyNestedTest { // // bsm that when used with indy returns a call site whose target is MethodHandles.constant(String.class, name), and // // when used with condy returns the name // .withMethod("bsm", MethodTypeDesc.ofDescriptor(bsmDescriptor), -// Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder +// ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder // .withCode(codeBuilder -> { // codeBuilder // .aload(2) @@ -168,7 +164,7 @@ public class CondyNestedTest { // ) // // an indy bsm, that returns a call site whose target is MethodHandles.constant(String.class, methodName) // .withMethod("bsmIndy", MethodTypeDesc.ofDescriptor(bsmIndyDescriptor), -// Classfile.ACC_PUBLIC + Classfile.ACC_PUBLIC, methodBuilder -> methodBuilder +// ClassFile.ACC_PUBLIC + ClassFile.ACC_PUBLIC, methodBuilder -> methodBuilder // .withCode(codeBuilder -> codeBuilder // .new_(ClassDesc.ofDescriptor(ConstantCallSite.class.descriptorString())) // .dup() @@ -184,7 +180,7 @@ public class CondyNestedTest { // ) // ) // .withMethod("condy_bsm_condy_bsm", MethodTypeDesc.of(ConstantDescs.CD_Object), -// Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder +// ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder // .withCode(codeBuilder -> codeBuilder // .ldc(DynamicConstantDesc.ofNamed( // bsmMhDesc, @@ -202,7 +198,7 @@ public class CondyNestedTest { // ) // ) // .withMethod("indy_bsmIndy_condy_bsm", MethodTypeDesc.of(ConstantDescs.CD_Object), -// Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder +// ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder // .withCode(codeBuilder -> codeBuilder // .invokedynamic(DynamicCallSiteDesc.of( // bsmIndyMhDesc, @@ -220,7 +216,7 @@ public class CondyNestedTest { // ) // ) // .withMethod("indy_bsm_condy_bsm", MethodTypeDesc.of(ConstantDescs.CD_Object), -// Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder +// ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder // .withCode(codeBuilder -> codeBuilder // .invokedynamic(DynamicCallSiteDesc.of( // bsmMhDesc, diff --git a/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java b/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java index 2f0208171ae34..f635bbfd59b3e 100644 --- a/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java +++ b/test/jdk/java/lang/invoke/condy/CondyRepeatFailedResolution.java @@ -26,16 +26,12 @@ * @bug 8186211 * @summary Test basic invocation of multiple ldc's of the same dynamic constant that fail resolution * @library /java/lang/invoke/common - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng CondyRepeatFailedResolution * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyRepeatFailedResolution */ -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -108,10 +104,10 @@ public void generateClass() throws Exception { bsmMethodName, bsmDescriptor ); - byte[] byteArray = Classfile.of().build(ClassDesc.of(genClassName), classBuilder -> classBuilder + byte[] byteArray = ClassFile.of().build(ClassDesc.of(genClassName), classBuilder -> classBuilder .withVersion(55, 0) .withSuperclass(ConstantDescs.CD_Object) - .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, Classfile.ACC_PUBLIC, + .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, ClassFile.ACC_PUBLIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .aload(0) @@ -121,7 +117,7 @@ public void generateClass() throws Exception { ) ) .withMethod("B", MethodTypeDesc.of(ConstantDescs.CD_byte), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -132,7 +128,7 @@ public void generateClass() throws Exception { ) ) .withMethod("C", MethodTypeDesc.of(ConstantDescs.CD_char), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -143,7 +139,7 @@ public void generateClass() throws Exception { ) ) .withMethod("D", MethodTypeDesc.of(ConstantDescs.CD_double), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -154,7 +150,7 @@ public void generateClass() throws Exception { ) ) .withMethod("D_AsType", MethodTypeDesc.of(ConstantDescs.CD_double), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -165,7 +161,7 @@ public void generateClass() throws Exception { ) ) .withMethod("F", MethodTypeDesc.of(ConstantDescs.CD_float), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -176,7 +172,7 @@ public void generateClass() throws Exception { ) ) .withMethod("F_AsType", MethodTypeDesc.of(ConstantDescs.CD_float), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -187,7 +183,7 @@ public void generateClass() throws Exception { ) ) .withMethod("I", MethodTypeDesc.of(ConstantDescs.CD_int), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -198,7 +194,7 @@ public void generateClass() throws Exception { ) ) .withMethod("J", MethodTypeDesc.of(ConstantDescs.CD_long), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -209,7 +205,7 @@ public void generateClass() throws Exception { ) ) .withMethod("J_AsType", MethodTypeDesc.of(ConstantDescs.CD_long), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -220,7 +216,7 @@ public void generateClass() throws Exception { ) ) .withMethod("S", MethodTypeDesc.of(ConstantDescs.CD_short), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -231,7 +227,7 @@ public void generateClass() throws Exception { ) ) .withMethod("Z_F", MethodTypeDesc.of(ConstantDescs.CD_boolean), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -242,7 +238,7 @@ public void generateClass() throws Exception { ) ) .withMethod("Z_T", MethodTypeDesc.of(ConstantDescs.CD_boolean), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -253,7 +249,7 @@ public void generateClass() throws Exception { ) ) .withMethod("null", MethodTypeDesc.of(ConstantDescs.CD_Object), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -264,7 +260,7 @@ public void generateClass() throws Exception { ) ) .withMethod("string", MethodTypeDesc.of(ConstantDescs.CD_String), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -275,7 +271,7 @@ public void generateClass() throws Exception { ) ) .withMethod("stringArray", MethodTypeDesc.of(ConstantDescs.CD_String.arrayType()), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, diff --git a/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java b/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java index 805cbd42fd1f2..057d540551602 100644 --- a/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyReturnPrimitiveTest.java @@ -25,16 +25,12 @@ * @test * @bug 8186046 * @summary Test for condy BSMs returning primitive values or null - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng CondyReturnPrimitiveTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyReturnPrimitiveTest */ -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -108,10 +104,10 @@ public void generateClass() throws Exception { bsmMethodName, bsmDescriptor ); - byte[] byteArray = Classfile.of().build(ClassDesc.of(genClassName), classBuilder -> classBuilder + byte[] byteArray = ClassFile.of().build(ClassDesc.of(genClassName), classBuilder -> classBuilder .withVersion(55, 0) .withSuperclass(ConstantDescs.CD_Object) - .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, Classfile.ACC_PUBLIC, + .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, ClassFile.ACC_PUBLIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .aload(0) @@ -121,7 +117,7 @@ public void generateClass() throws Exception { ) ) .withMethod("B", MethodTypeDesc.of(ConstantDescs.CD_byte), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -132,7 +128,7 @@ public void generateClass() throws Exception { ) ) .withMethod("C", MethodTypeDesc.of(ConstantDescs.CD_char), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -143,7 +139,7 @@ public void generateClass() throws Exception { ) ) .withMethod("D", MethodTypeDesc.of(ConstantDescs.CD_double), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -154,7 +150,7 @@ public void generateClass() throws Exception { ) ) .withMethod("D_AsType", MethodTypeDesc.of(ConstantDescs.CD_double), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -165,7 +161,7 @@ public void generateClass() throws Exception { ) ) .withMethod("F", MethodTypeDesc.of(ConstantDescs.CD_float), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -176,7 +172,7 @@ public void generateClass() throws Exception { ) ) .withMethod("F_AsType", MethodTypeDesc.of(ConstantDescs.CD_float), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -187,7 +183,7 @@ public void generateClass() throws Exception { ) ) .withMethod("I", MethodTypeDesc.of(ConstantDescs.CD_int), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -198,7 +194,7 @@ public void generateClass() throws Exception { ) ) .withMethod("J", MethodTypeDesc.of(ConstantDescs.CD_long), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -209,7 +205,7 @@ public void generateClass() throws Exception { ) ) .withMethod("J_AsType", MethodTypeDesc.of(ConstantDescs.CD_long), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -220,7 +216,7 @@ public void generateClass() throws Exception { ) ) .withMethod("S", MethodTypeDesc.of(ConstantDescs.CD_short), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -231,7 +227,7 @@ public void generateClass() throws Exception { ) ) .withMethod("Z_F", MethodTypeDesc.of(ConstantDescs.CD_boolean), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -242,7 +238,7 @@ public void generateClass() throws Exception { ) ) .withMethod("Z_T", MethodTypeDesc.of(ConstantDescs.CD_boolean), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -253,7 +249,7 @@ public void generateClass() throws Exception { ) ) .withMethod("null", MethodTypeDesc.of(ConstantDescs.CD_Object), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -264,7 +260,7 @@ public void generateClass() throws Exception { ) ) .withMethod("string", MethodTypeDesc.of(ConstantDescs.CD_String), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, @@ -275,7 +271,7 @@ public void generateClass() throws Exception { ) ) .withMethod("stringArray", MethodTypeDesc.of(ConstantDescs.CD_String.arrayType()), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .ldc(DynamicConstantDesc.ofNamed( bsmMhDesc, diff --git a/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java b/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java index 96afb2cb3774a..e488c35e77872 100644 --- a/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyStaticArgumentsTest.java @@ -27,11 +27,7 @@ * @summary Test bootstrap arguments for condy * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng CondyStaticArgumentsTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyStaticArgumentsTest */ diff --git a/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java b/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java index e3a1edb725f3f..89db90efa144a 100644 --- a/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyTypeValidationTest.java @@ -27,11 +27,7 @@ * @summary Test invalid name in name and type * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyTypeValidationTest */ diff --git a/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java b/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java index daf1755e15f38..766678f4686a3 100644 --- a/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java +++ b/test/jdk/java/lang/invoke/condy/CondyWithGarbageTest.java @@ -27,18 +27,14 @@ * @summary Stress test ldc to ensure HotSpot correctly manages oop maps * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng CondyWithGarbageTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyWithGarbageTest */ -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeBuilder; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeBuilder; import org.testng.Assert; import org.testng.annotations.Test; @@ -70,10 +66,10 @@ public static Object bsmString(MethodHandles.Lookup l, static MethodHandle lcdStringBasher() throws Exception { ClassDesc cd = classDesc(L.lookupClass(), "$Code$String"); - byte[] bytes = Classfile.of().build(cd, classBuilder -> classBuilder + byte[] bytes = ClassFile.of().build(cd, classBuilder -> classBuilder .withVersion(55, 0) .withSuperclass(ConstantDescs.CD_Object) - .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, Classfile.ACC_PUBLIC, + .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, ClassFile.ACC_PUBLIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .aload(0) @@ -81,7 +77,7 @@ static MethodHandle lcdStringBasher() throws Exception { ConstantDescs.MTD_void, false) .return_())) .withMethod("m", MethodTypeDesc.of(ConstantDescs.CD_String), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> { codeBuilder .new_(classDesc(StringBuilder.class)) @@ -149,10 +145,10 @@ public static Object bsmStringArray(MethodHandles.Lookup l, static MethodHandle lcdStringArrayBasher() throws Exception { ClassDesc cd = classDesc(L.lookupClass(), "$Code$StringArray"); - byte[] bytes = Classfile.of().build(cd, classBuilder -> classBuilder + byte[] bytes = ClassFile.of().build(cd, classBuilder -> classBuilder .withVersion(55, 0) .withSuperclass(ConstantDescs.CD_Object) - .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, Classfile.ACC_PUBLIC, + .withMethod(ConstantDescs.INIT_NAME, ConstantDescs.MTD_void, ClassFile.ACC_PUBLIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> codeBuilder .aload(0) @@ -160,7 +156,7 @@ static MethodHandle lcdStringArrayBasher() throws Exception { ConstantDescs.MTD_void, false) .return_())) .withMethod("m", MethodTypeDesc.of(classDesc(String.class)), - Classfile.ACC_PUBLIC + Classfile.ACC_STATIC, methodBuilder -> methodBuilder + ClassFile.ACC_PUBLIC + ClassFile.ACC_STATIC, methodBuilder -> methodBuilder .withCode(codeBuilder -> { codeBuilder .new_(classDesc(StringBuilder.class)) diff --git a/test/jdk/java/lang/invoke/condy/CondyWrongType.java b/test/jdk/java/lang/invoke/condy/CondyWrongType.java index db4024c63a2ec..09ec64a3656f7 100644 --- a/test/jdk/java/lang/invoke/condy/CondyWrongType.java +++ b/test/jdk/java/lang/invoke/condy/CondyWrongType.java @@ -27,11 +27,7 @@ * @summary Test bootstrap methods returning the wrong type * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng CondyWrongType * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyWrongType */ diff --git a/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java b/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java index bda6251900a70..9babd3b57d686 100644 --- a/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java +++ b/test/jdk/java/lang/invoke/condy/ConstantBootstrapsTest.java @@ -27,11 +27,7 @@ * @summary Test dynamic constant bootstraps * @library /java/lang/invoke/common * @build test.java.lang.invoke.lib.InstructionHelper - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run testng ConstantBootstrapsTest * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 ConstantBootstrapsTest */ diff --git a/test/jdk/java/lang/module/AutomaticModulesTest.java b/test/jdk/java/lang/module/AutomaticModulesTest.java index a1977ae8774dc..84240be22fea0 100644 --- a/test/jdk/java/lang/module/AutomaticModulesTest.java +++ b/test/jdk/java/lang/module/AutomaticModulesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,12 +23,12 @@ /** * @test - * @bug 8142968 8253751 8262944 + * @bug 8142968 8253751 8262944 8314986 * @library /test/lib * @build AutomaticModulesTest * jdk.test.lib.util.JarUtils * jdk.test.lib.util.ModuleUtils - * @run testng AutomaticModulesTest + * @run junit AutomaticModulesTest * @summary Basic tests for automatic modules */ @@ -54,75 +54,69 @@ import jdk.test.lib.util.JarUtils; import jdk.test.lib.util.ModuleUtils; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.params.provider.Arguments.arguments; -@Test public class AutomaticModulesTest { - private static final Path USER_DIR = Path.of(System.getProperty("user.dir")); - @DataProvider(name = "jarnames") - public Object[][] createJarNames() { - return new Object[][] { - - // JAR file name module-name[/version] - - { "foo.jar", "foo" }, - { "foo4j.jar", "foo4j", }, - - { "foo1.jar", "foo1" }, - { "foo10.jar", "foo10" }, - - { "foo-1.jar", "foo/1" }, - { "foo-1.2.jar", "foo/1.2" }, - { "foo-1.2.3.jar", "foo/1.2.3" }, - { "foo-1.2.3.4.jar", "foo/1.2.3.4" }, - - { "foo-10.jar", "foo/10" }, - { "foo-10.20.jar", "foo/10.20" }, - { "foo-10.20.30.jar", "foo/10.20.30" }, - { "foo-10.20.30.40.jar", "foo/10.20.30.40" }, - - { "foo-bar.jar", "foo.bar" }, - { "foo-bar-1.jar", "foo.bar/1" }, - { "foo-bar-1.2.jar", "foo.bar/1.2"}, - { "foo-bar-10.jar", "foo.bar/10" }, - { "foo-bar-10.20.jar", "foo.bar/10.20" }, - - { "foo.bar1.jar", "foo.bar1" }, - { "foo.bar10.jar", "foo.bar10" }, - - { "foo-1.2-SNAPSHOT.jar", "foo/1.2-SNAPSHOT" }, - { "foo-bar-1.2-SNAPSHOT.jar", "foo.bar/1.2-SNAPSHOT" }, - - { "foo--bar-1.0.jar", "foo.bar/1.0" }, - { "-foo-bar-1.0.jar", "foo.bar/1.0" }, - { "foo-bar--1.0.jar", "foo.bar/1.0" }, - - }; + // JAR file name to expected module name / version + static Stream jarNames() { + return Stream.of( + arguments( "foo.jar", "foo" ), + arguments( "foo4j.jar", "foo4j" ), + + arguments( "foo1.jar", "foo1" ), + arguments( "foo10.jar", "foo10" ), + + arguments( "foo-1.jar", "foo/1" ), + arguments( "foo-1.2.jar", "foo/1.2" ), + arguments( "foo-1.2.3.jar", "foo/1.2.3" ), + arguments( "foo-1.2.3.4.jar", "foo/1.2.3.4" ), + + arguments( "foo-10.jar", "foo/10" ), + arguments( "foo-10.20.jar", "foo/10.20" ), + arguments( "foo-10.20.30.jar", "foo/10.20.30" ), + arguments( "foo-10.20.30.40.jar", "foo/10.20.30.40" ), + + arguments( "foo-bar.jar", "foo.bar" ), + arguments( "foo-bar-1.jar", "foo.bar/1" ), + arguments( "foo-bar-1.2.jar", "foo.bar/1.2" ), + arguments( "foo-bar-10.jar", "foo.bar/10" ), + arguments( "foo-bar-10.20.jar", "foo.bar/10.20" ), + + arguments("foo.bar1.jar", "foo.bar1" ), + arguments( "foo.bar10.jar", "foo.bar10" ), + + arguments( "foo-1.2-SNAPSHOT.jar", "foo/1.2-SNAPSHOT" ), + arguments( "foo-bar-1.2-SNAPSHOT.jar", "foo.bar/1.2-SNAPSHOT" ), + + arguments( "foo--bar-1.0.jar", "foo.bar/1.0" ), + arguments( "-foo-bar-1.0.jar", "foo.bar/1.0" ), + arguments( "foo-bar--1.0.jar", "foo.bar/1.0" ) + ); } // JAR file names that do not map to a legal module name - @DataProvider(name = "badjarnames") - public Object[][] createBadNames() { - return new Object[][]{ - - { ".jar", null }, - { "_.jar", null }, - - { "foo.1.jar", null }, - { "1foo.jar", null }, - { "foo.1bar.jar", null }, - - }; + static Stream barJarNames() { + return Stream.of( + ".jar", + "_.jar", + "foo.1.jar", + "1foo.jar", + "foo.1bar.jar" + ); } /** * Test mapping of JAR file names to module names */ - @Test(dataProvider = "jarnames") + @ParameterizedTest + @MethodSource("jarNames") public void testNames(String fn, String mid) throws IOException { String[] s = mid.split("/"); String mn = s[0]; @@ -143,19 +137,20 @@ public void testNames(String fn, String mid) throws IOException { ModuleDescriptor descriptor = mref.get().descriptor(); assertTrue(descriptor.isAutomatic()); - assertEquals(descriptor.name(), mn); + assertEquals(mn, descriptor.name()); if (vs == null) { assertFalse(descriptor.version().isPresent()); } else { - assertEquals(descriptor.version().get().toString(), vs); + assertEquals(vs, descriptor.version().get().toString()); } } /** * Test impossible mapping of JAR files to modules names */ - @Test(dataProvider = "badjarnames", expectedExceptions = FindException.class) - public void testBadNames(String fn, String ignore) throws IOException { + @ParameterizedTest + @MethodSource("barJarNames") + public void testBadNames(String fn) throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); Path jf = dir.resolve(fn); @@ -163,37 +158,36 @@ public void testBadNames(String fn, String ignore) throws IOException { createDummyJarFile(jf); // should throw FindException - ModuleFinder.of(dir).findAll(); + var finder = ModuleFinder.of(dir); + assertThrows(FindException.class, finder::findAll); } - @DataProvider(name = "modulenames") - public Object[][] createModuleNames() { - return new Object[][] { - { "foo", null }, - { "foo", "1.0" }, - { "foo.bar", null }, - { "foo.bar", "1.0" }, - { "class_", null }, - { "class_", "1.0" }, - }; + // Automatic-Module-Name attribute values and version in JAR file name + static Stream automaticModuleNames() { + return Stream.of( + arguments( "foo", null ), + arguments( "foo", "1.0" ), + arguments( "foo.bar", null ), + arguments( "foo.bar", "1.0" ), + arguments( "class_", null ), + arguments( "class_", "1.0" ) + ); } - @DataProvider(name = "badmodulenames") - public Object[][] createBadModuleNames() { - return new Object[][] { - { "", null }, - { "", "1.0" }, - { "666", null }, - { "666", "1.0" }, - { "foo.class", null }, - { "foo.class", "1.0" }, - }; + // Bad Automatic-Module-Name attribute values + static Stream badAutomaticModuleNames() { + return Stream.of( + "", + "666", + "foo.class" + ); } /** * Test JAR files with the Automatic-Module-Name attribute */ - @Test(dataProvider = "modulenames") + @ParameterizedTest + @MethodSource("automaticModuleNames") public void testAutomaticModuleNameAttribute(String name, String vs) throws IOException { @@ -218,27 +212,26 @@ public void testAutomaticModuleNameAttribute(String name, String vs) ModuleReference mref = finder.find(name).get(); ModuleDescriptor descriptor = mref.descriptor(); - assertEquals(descriptor.name(), name); - assertEquals(descriptor.version() + assertEquals(name, descriptor.name()); + assertEquals(vs, descriptor.version() .map(ModuleDescriptor.Version::toString) - .orElse(null), vs); + .orElse(null)); } /** * Test JAR files with the Automatic-Module-Name attribute with a value * that is not a legal module name. */ - @Test(dataProvider = "badmodulenames", expectedExceptions = FindException.class) - public void testBadAutomaticModuleNameAttribute(String name, String ignore) - throws IOException - { - // should throw FindException - testAutomaticModuleNameAttribute(name, null); + @ParameterizedTest + @MethodSource("badAutomaticModuleNames") + public void testBadAutomaticModuleNameAttribute(String name) throws IOException { + assertThrows(FindException.class, () -> testAutomaticModuleNameAttribute(name, null)); } /** * Test all packages are exported */ + @Test public void testPackages() throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); createDummyJarFile(dir.resolve("m.jar"), @@ -263,6 +256,7 @@ public void testPackages() throws IOException { * Test class files in JAR file where the entry does not correspond to a * legal package name. */ + @Test public void testBadPackage() throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); createDummyJarFile(dir.resolve("m.jar"), "p/C1.class", "p-/C2.class"); @@ -284,6 +278,7 @@ public void testBadPackage() throws IOException { /** * Test non-class resources in a JAR file. */ + @Test public void testNonClassResources() throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); createDummyJarFile(dir.resolve("m.jar"), @@ -307,17 +302,18 @@ public void testNonClassResources() throws IOException { /** * Test .class file in unnamed package (top-level directory) */ - @Test(expectedExceptions = FindException.class) + @Test public void testClassInUnnamedPackage() throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); createDummyJarFile(dir.resolve("m.jar"), "Mojo.class"); - ModuleFinder finder = ModuleFinder.of(dir); - finder.findAll(); + var finder = ModuleFinder.of(dir); + assertThrows(FindException.class, finder::findAll); } /** * Test JAR file with META-INF/services configuration file */ + @Test public void testServicesConfiguration() throws IOException { String service = "p.S"; String provider = "p.S1"; @@ -345,27 +341,25 @@ public void testServicesConfiguration() throws IOException { ModuleDescriptor descriptor = mref.get().descriptor(); assertTrue(descriptor.provides().size() == 1); ModuleDescriptor.Provides provides = descriptor.provides().iterator().next(); - assertEquals(provides.service(), service); + assertEquals(service, provides.service()); assertTrue(provides.providers().size() == 1); assertTrue(provides.providers().contains((provider))); } // META-INF/services files that don't map to legal service names - @DataProvider(name = "badservices") - public Object[][] createBadServices() { - return new Object[][] { - - // service type provider type - { "-", "p.S1" }, - { ".S", "p.S1" }, - }; + static Stream badServices() { + return Stream.of( + arguments( "-", "p.S1" ), + arguments( ".S", "p.S1" ) + ); } /** * Test JAR file with META-INF/services configuration file with bad * values or names. */ - @Test(dataProvider = "badservices") + @ParameterizedTest + @MethodSource("badServices") public void testBadServicesNames(String service, String provider) throws IOException { @@ -383,22 +377,20 @@ public void testBadServicesNames(String service, String provider) } // META-INF/services configuration file entries that are not legal - @DataProvider(name = "badproviders") - public Object[][] createBadProviders() { - return new Object[][] { - - // service type provider type - { "p.S", "-" }, - { "p.S", "p..S1" }, - { "p.S", "S1." }, - }; + static Stream badProviders() { + return Stream.of( + arguments("p.S", "-"), + arguments("p.S", "p..S1"), + arguments("p.S", "S1.") + ); } /** * Test JAR file with META-INF/services configuration file with bad * values or names. */ - @Test(dataProvider = "badproviders", expectedExceptions = FindException.class) + @ParameterizedTest + @MethodSource("badProviders") public void testBadProviderNames(String service, String provider) throws IOException { @@ -418,14 +410,15 @@ public void testBadProviderNames(String service, String provider) JarUtils.createJarFile(dir.resolve("m.jar"), tmpdir); // should throw FindException - ModuleFinder.of(dir).findAll(); + var finder = ModuleFinder.of(dir); + assertThrows(FindException.class, finder::findAll); } /** * Test JAR file with META-INF/services configuration file listing a * provider that is not in the module. */ - @Test(expectedExceptions = FindException.class) + @Test public void testMissingProviderPackage() throws IOException { Path tmpdir = Files.createTempDirectory(USER_DIR, "tmp"); @@ -438,31 +431,20 @@ public void testMissingProviderPackage() throws IOException { Path jarfile = dir.resolve("m.jar"); JarUtils.createJarFile(jarfile, tmpdir); - // catch FindException, inspect its cause's type and details, and rethrow - var expectedMessage = "Provider class q.P not in JAR file " + jarfile.getFileName(); - try { - ModuleFinder.of(dir).findAll(); - } catch (FindException exception) { - if (exception.getCause() instanceof InvalidModuleDescriptorException imde) { - var actualMessage = imde.getMessage(); - if (actualMessage.equals(expectedMessage)) { - throw exception; // rethrow as expected - } - throw new AssertionError( - """ - Unexpected detail message in InvalidModuleDescriptorException: - Expected message -> '%s' - Actual message -> '%s' - """.formatted(expectedMessage, actualMessage)); - } - throw new AssertionError("Unexpected exception cause: " + exception.getCause()); - } + // FindException should be thrown with InvalidModuleDescriptorException as cause + var finder = ModuleFinder.of(dir); + FindException ex = assertThrows(FindException.class, () -> finder.findAll()); + Throwable cause = ex.getCause(); + assertTrue(cause instanceof InvalidModuleDescriptorException); + var imde = (InvalidModuleDescriptorException) cause; + assertEquals("Provider class q.P not in JAR file " + jarfile.getFileName(), imde.getMessage()); } /** * Test that a JAR file with a Main-Class attribute results * in a module with a main class. */ + @Test public void testMainClass() throws IOException { String mainClass = "p.Main"; @@ -481,27 +463,24 @@ public void testMainClass() throws IOException { Configuration cf = resolve(parent, finder, "m"); ModuleDescriptor descriptor = findDescriptor(cf, "m"); - - assertTrue(descriptor.mainClass().isPresent()); - assertEquals(descriptor.mainClass().get(), mainClass); + assertEquals(mainClass, descriptor.mainClass().get()); } - // Main-Class files that do not map to a legal qualified type name - @DataProvider(name = "badmainclass") - public Object[][] createBadMainClass() { - return new Object[][] { - { "p..Main", null }, - { "p-.Main", null }, - - }; + // Main-Class attribute values that do not map to a legal qualified type name + static Stream badMainClasses() { + return Stream.of( + "p..Main", + "p-.Main" + ); } /** * Test that a JAR file with a Main-Class attribute that is not a qualified * type name. */ - @Test(dataProvider = "badmainclass") - public void testBadMainClass(String mainClass, String ignore) throws IOException { + @ParameterizedTest + @MethodSource("badMainClasses") + public void testBadMainClass(String mainClass) throws IOException { Manifest man = new Manifest(); Attributes attrs = man.getMainAttributes(); attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0.0"); @@ -521,6 +500,7 @@ public void testBadMainClass(String mainClass, String ignore) throws IOException /** * Test that a JAR file with a Main-Class attribute that is not in the module */ + @Test public void testMissingMainClassPackage() throws IOException { Manifest man = new Manifest(); Attributes attrs = man.getMainAttributes(); @@ -544,6 +524,7 @@ public void testMissingMainClassPackage() throws IOException { * b* * c* */ + @Test public void testConfiguration1() throws Exception { ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("a") @@ -588,13 +569,14 @@ public void testConfiguration1() throws Exception { assertTrue(a.reads().contains(c)); assertTrue(b.reads().contains(a)); + assertFalse(b.reads().contains(b)); assertTrue(b.reads().contains(c)); testReadAllBootModules(cf, "b"); // b reads all modules in boot layer assertTrue(c.reads().contains(a)); assertTrue(c.reads().contains(b)); + assertFalse(c.reads().contains(c)); testReadAllBootModules(cf, "c"); // c reads all modules in boot layer - } /** @@ -604,6 +586,7 @@ public void testConfiguration1() throws Exception { * c* * d* */ + @Test public void testInConfiguration2() throws IOException { ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("a") @@ -660,12 +643,14 @@ public void testInConfiguration2() throws IOException { assertTrue(c.reads().contains(a)); assertTrue(c.reads().contains(b)); + assertFalse(c.reads().contains(c)); assertTrue(c.reads().contains(d)); testReadAllBootModules(cf, "c"); // c reads all modules in boot layer assertTrue(d.reads().contains(a)); assertTrue(d.reads().contains(b)); assertTrue(d.reads().contains(c)); + assertFalse(d.reads().contains(d)); testReadAllBootModules(cf, "d"); // d reads all modules in boot layer } @@ -676,6 +661,7 @@ public void testInConfiguration2() throws IOException { * c* * d* */ + @Test public void testInConfiguration3() throws IOException { ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("a") @@ -732,18 +718,16 @@ public void testInConfiguration3() throws IOException { assertTrue(b.reads().contains(d)); assertTrue(b.reads().contains(base)); - assertTrue(reads(cf, "b", "c")); - assertTrue(reads(cf, "b", "d")); - assertTrue(reads(cf, "b", "java.base")); - assertTrue(c.reads().contains(a)); assertTrue(c.reads().contains(b)); + assertFalse(c.reads().contains(c)); assertTrue(c.reads().contains(d)); testReadAllBootModules(cf, "c"); // c reads all modules in boot layer assertTrue(d.reads().contains(a)); assertTrue(d.reads().contains(b)); assertTrue(d.reads().contains(c)); + assertFalse(d.reads().contains(d)); testReadAllBootModules(cf, "d"); // d reads all modules in boot layer } @@ -751,6 +735,7 @@ public void testInConfiguration3() throws IOException { * Basic test to ensure that no automatic modules are resolved when * an automatic module is not a root or required by other modules. */ + @Test public void testInConfiguration4() throws IOException { ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1") @@ -780,6 +765,7 @@ public void testInConfiguration4() throws IOException { * Basic test to ensure that if an automatic module is resolved then * all observable automatic modules are resolved. */ + @Test public void testInConfiguration5() throws IOException { // m1 requires m2 ModuleDescriptor descriptor1 @@ -836,6 +822,7 @@ public void testInConfiguration5() throws IOException { assertTrue(auto1.reads().contains(m1)); assertTrue(auto1.reads().contains(m2)); + assertFalse(auto1.reads().contains(auto1)); assertTrue(auto1.reads().contains(auto2)); assertTrue(auto1.reads().contains(auto3)); assertTrue(auto1.reads().contains(base)); @@ -843,6 +830,7 @@ public void testInConfiguration5() throws IOException { assertTrue(auto2.reads().contains(m1)); assertTrue(auto2.reads().contains(m2)); assertTrue(auto2.reads().contains(auto1)); + assertFalse(auto2.reads().contains(auto2)); assertTrue(auto2.reads().contains(auto3)); assertTrue(auto2.reads().contains(base)); @@ -850,6 +838,7 @@ public void testInConfiguration5() throws IOException { assertTrue(auto3.reads().contains(m2)); assertTrue(auto3.reads().contains(auto1)); assertTrue(auto3.reads().contains(auto2)); + assertFalse(auto3.reads().contains(auto3)); assertTrue(auto3.reads().contains(base)); } @@ -859,6 +848,7 @@ public void testInConfiguration5() throws IOException { * automatic modules that are found by the after finder and not shadowed * by the before finder, or parent configurations, should also be resolved. */ + @Test public void testInConfiguration6() throws IOException { // m1 requires auto1 ModuleDescriptor descriptor1 @@ -918,12 +908,14 @@ public void testInConfiguration6() throws IOException { assertTrue(auto2.reads().contains(m1)); assertTrue(auto2.reads().contains(auto1)); + assertFalse(auto2.reads().contains(auto2)); assertTrue(auto2.reads().contains(auto3)); assertTrue(auto2.reads().contains(base)); assertTrue(auto3.reads().contains(m1)); assertTrue(auto3.reads().contains(auto1)); assertTrue(auto3.reads().contains(auto2)); + assertFalse(auto3.reads().contains(auto3)); assertTrue(auto3.reads().contains(base)); } @@ -933,6 +925,7 @@ public void testInConfiguration6() throws IOException { * automatic module in a parent configuration then it should read all * automatic modules in the parent configuration. */ + @Test public void testInConfiguration7() throws Exception { // m1 requires auto1 ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("m1") @@ -964,11 +957,13 @@ public void testInConfiguration7() throws Exception { assertTrue(auto1.reads().contains(base)); assertTrue(auto1.reads().contains(m1)); + assertFalse(auto1.reads().contains(auto1)); assertTrue(auto1.reads().contains(auto2)); assertTrue(auto2.reads().contains(base)); assertTrue(auto2.reads().contains(m1)); assertTrue(auto2.reads().contains(auto1)); + assertFalse(auto2.reads().contains(auto2)); // m2 requires auto1 ModuleDescriptor descriptor2 = ModuleDescriptor.newModule("m2") @@ -999,7 +994,7 @@ public void testInConfiguration7() throws Exception { * b* contains p * c* contains p */ - @Test(expectedExceptions = { ResolutionException.class }) + @Test public void testDuplicateSuppliers1() throws IOException { ModuleDescriptor descriptor = ModuleDescriptor.newModule("a") @@ -1018,7 +1013,7 @@ public void testDuplicateSuppliers1() throws IOException { ModuleFinder.of(dir)); Configuration parent = ModuleLayer.boot().configuration(); - resolve(parent, finder, "a"); + assertThrows(ResolutionException.class, () -> resolve(parent, finder, "a")); } /** @@ -1026,7 +1021,7 @@ public void testDuplicateSuppliers1() throws IOException { * a contains p, requires b* * b* contains p */ - @Test(expectedExceptions = { ResolutionException.class }) + @Test public void testDuplicateSuppliers2() throws IOException { ModuleDescriptor descriptor = ModuleDescriptor.newModule("a") @@ -1044,12 +1039,13 @@ public void testDuplicateSuppliers2() throws IOException { ModuleFinder.of(dir)); Configuration parent = ModuleLayer.boot().configuration(); - resolve(parent, finder, "a"); + assertThrows(ResolutionException.class, () -> resolve(parent, finder, "a")); } /** * Basic test of layer containing automatic modules */ + @Test public void testInLayer() throws IOException { ModuleDescriptor descriptor = ModuleDescriptor.newModule("a") @@ -1091,6 +1087,7 @@ public void testInLayer() throws IOException { /** * Test miscellaneous methods. */ + @Test public void testMisc() throws IOException { Path dir = Files.createTempDirectory(USER_DIR, "mods"); Path m_jar = createDummyJarFile(dir.resolve("m.jar"), "p/T.class"); @@ -1132,13 +1129,10 @@ static ModuleDescriptor findDescriptor(Configuration cf, String name) { * configuration. */ static void testReadAllBootModules(Configuration cf, String mn) { - Set bootModules = ModuleLayer.boot().modules().stream() .map(Module::getName) .collect(Collectors.toSet()); - bootModules.forEach(other -> assertTrue(reads(cf, mn, other))); - } /** @@ -1202,5 +1196,4 @@ static Path createDummyJarFile(Path jarfile, String... entries) { return createDummyJarFile(jarfile, null, entries); } - } diff --git a/test/jdk/java/lang/module/ClassFileVersionsTest.java b/test/jdk/java/lang/module/ClassFileVersionsTest.java index b0830f02903dc..849a56301a103 100644 --- a/test/jdk/java/lang/module/ClassFileVersionsTest.java +++ b/test/jdk/java/lang/module/ClassFileVersionsTest.java @@ -23,10 +23,8 @@ /** * @test - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.module + * @enablePreview + * @modules java.base/jdk.internal.module * @library /test/lib * @build jdk.test.lib.util.ModuleInfoWriter * @run testng ClassFileVersionsTest diff --git a/test/jdk/java/lang/module/ConfigurationTest.java b/test/jdk/java/lang/module/ConfigurationTest.java index 7bcd527c9cc59..2f2131b3fc228 100644 --- a/test/jdk/java/lang/module/ConfigurationTest.java +++ b/test/jdk/java/lang/module/ConfigurationTest.java @@ -23,10 +23,8 @@ /** * @test + * @enablePreview * @modules java.base/jdk.internal.access - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool * java.base/jdk.internal.module * @library /test/lib * @build ConfigurationTest diff --git a/test/jdk/java/lang/module/ModuleDescriptorTest.java b/test/jdk/java/lang/module/ModuleDescriptorTest.java index f0155488242ab..c9267f3db3d64 100644 --- a/test/jdk/java/lang/module/ModuleDescriptorTest.java +++ b/test/jdk/java/lang/module/ModuleDescriptorTest.java @@ -24,10 +24,8 @@ /** * @test * @bug 8142968 8158456 8298875 + * @enablePreview * @modules java.base/jdk.internal.access - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool * java.base/jdk.internal.module * @library /test/lib * @build jdk.test.lib.util.ModuleInfoWriter @@ -62,8 +60,8 @@ import jdk.internal.access.JavaLangModuleAccess; import jdk.internal.access.SharedSecrets; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.attribute.ModuleAttribute; +import java.lang.classfile.ClassFile; +import java.lang.classfile.attribute.ModuleAttribute; import java.lang.constant.PackageDesc; import java.lang.constant.ModuleDesc; import jdk.test.lib.util.ModuleInfoWriter; @@ -1371,7 +1369,7 @@ public void testReadsWithPackageFinder() throws Exception { * complete set of packages. */ public void testReadsWithBadPackageFinder() throws Exception { - ByteBuffer bb = ByteBuffer.wrap(Classfile.of().buildModule( + ByteBuffer bb = ByteBuffer.wrap(ClassFile.of().buildModule( ModuleAttribute.of( ModuleDesc.of("foo"), mb -> mb.requires(ModuleDesc.of("java.base"), 0, null) diff --git a/test/jdk/java/lang/module/ModuleFinderTest.java b/test/jdk/java/lang/module/ModuleFinderTest.java index 42223227c9b63..df7a17954b67b 100644 --- a/test/jdk/java/lang/module/ModuleFinderTest.java +++ b/test/jdk/java/lang/module/ModuleFinderTest.java @@ -23,10 +23,8 @@ /** * @test - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.module + * @enablePreview + * @modules java.base/jdk.internal.module * @library /test/lib * @build ModuleFinderTest jdk.test.lib.util.ModuleInfoWriter * @run testng ModuleFinderTest diff --git a/test/jdk/java/lang/module/ModuleNamesTest.java b/test/jdk/java/lang/module/ModuleNamesTest.java index cacaa5c0f83f5..3b8b9ddcafc45 100644 --- a/test/jdk/java/lang/module/ModuleNamesTest.java +++ b/test/jdk/java/lang/module/ModuleNamesTest.java @@ -23,10 +23,8 @@ /** * @test + * @enablePreview * @modules java.base/jdk.internal.access - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool * java.base/jdk.internal.module * @library /test/lib * @build jdk.test.lib.util.ModuleInfoWriter diff --git a/test/jdk/java/lang/module/MultiReleaseJarTest.java b/test/jdk/java/lang/module/MultiReleaseJarTest.java index 2bc1172993803..53180174b8592 100644 --- a/test/jdk/java/lang/module/MultiReleaseJarTest.java +++ b/test/jdk/java/lang/module/MultiReleaseJarTest.java @@ -23,10 +23,8 @@ /** * @test - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.module + * @enablePreview + * @modules java.base/jdk.internal.module * @library /test/lib * @build MultiReleaseJarTest * jdk.test.lib.util.JarUtils diff --git a/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java b/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java index 8e31f35bef55e..4e3b905b2cbd3 100644 --- a/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java +++ b/test/jdk/java/lang/runtime/SwitchBootstrapsTest.java @@ -33,7 +33,7 @@ import java.lang.reflect.AccessFlag; import java.lang.runtime.SwitchBootstraps; import java.util.concurrent.atomic.AtomicBoolean; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import org.testng.annotations.Test; @@ -46,7 +46,6 @@ * @test * @bug 8318144 * @enablePreview - * @modules java.base/jdk.internal.classfile * @compile SwitchBootstrapsTest.java * @run testng/othervm SwitchBootstrapsTest */ @@ -368,11 +367,11 @@ public void testHiddenClassAsCaseLabel() throws Throwable { } private static byte[] createClass() { - return Classfile.of().build(ClassDesc.of("C"), clb -> { + return ClassFile.of().build(ClassDesc.of("C"), clb -> { clb.withFlags(AccessFlag.SYNTHETIC) .withMethodBody("", MethodTypeDesc.of(ConstantDescs.CD_void), - Classfile.ACC_PUBLIC, + ClassFile.ACC_PUBLIC, cb -> { cb.aload(0); cb.invokespecial(ConstantDescs.CD_Object, diff --git a/test/jdk/java/net/Inet6Address/serialize/Inet6AddressSerializationTest.java b/test/jdk/java/net/Inet6Address/serialize/Inet6AddressSerializationTest.java index 4b1ffafc9df3e..c52884f104017 100644 --- a/test/jdk/java/net/Inet6Address/serialize/Inet6AddressSerializationTest.java +++ b/test/jdk/java/net/Inet6Address/serialize/Inet6AddressSerializationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,10 +38,16 @@ import java.util.Enumeration; import java.util.List; +import jdk.test.lib.Platform; +import jdk.test.lib.NetworkConfiguration; + /** * @test * @bug 8007373 * @summary jdk7 backward compatibility serialization problem + * @library /test/lib + * @build jdk.test.lib.NetworkConfiguration + * @run main/othervm Inet6AddressSerializationTest */ public class Inet6AddressSerializationTest { @@ -177,12 +183,19 @@ static void testAllNetworkInterfaces() throws Exception { .getNetworkInterfaces(); e.hasMoreElements();) { NetworkInterface netIF = e.nextElement(); // Skip (Windows)Teredo Tunneling Pseudo-Interface + String dName = netIF.getDisplayName(); if (isWindows) { - String dName = netIF.getDisplayName(); if (dName != null && dName.contains("Teredo")) { continue; } } + // skip awdl and llw interfaces on macosx + if (Platform.isOSX()) { + if((dName != null) && + ((dName.contains("awdl")) || (dName.contains("llw")))) { + continue; + } + } for (Enumeration iadrs = netIF.getInetAddresses(); iadrs .hasMoreElements();) { InetAddress iadr = iadrs.nextElement(); @@ -622,8 +635,8 @@ static void assertNetworkInterfaceEqual( + deserializedNetworkInterface); failed = true; } - } else if (!expectedNetworkInterface - .equals(deserializedNetworkInterface)) { + } else if (!NetworkConfiguration.isSameInterface(expectedNetworkInterface, + deserializedNetworkInterface)) { System.err.println("Error checking " + // versionStr + " NetworkInterface, expected:" + expectedNetworkInterface diff --git a/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java b/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java index f97cfcec2432d..051a31dcb1b3a 100644 --- a/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java +++ b/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java @@ -64,6 +64,7 @@ * -Djdk.httpclient.HttpClient.log=frames,ssl,requests,responses,errors * -Djdk.internal.httpclient.debug=true * -Dsun.net.httpserver.idleInterval=50000 + * -Djdk.tracePinnedThreads=full * HttpClientLocalAddrTest * * @run testng/othervm/java.security.policy=httpclient-localaddr-security.policy diff --git a/test/jdk/java/nio/channels/SocketChannel/SendUrgentData.java b/test/jdk/java/nio/channels/SocketChannel/SendUrgentData.java index b861e62a26774..4fb88c265a1a0 100644 --- a/test/jdk/java/nio/channels/SocketChannel/SendUrgentData.java +++ b/test/jdk/java/nio/channels/SocketChannel/SendUrgentData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,9 @@ public static void main(String[] args) throws Exception { boolean inline = false; if (args.length > 0 && args[0].equals("-server")) { System.out.println(serverThread.getAddress()); - Thread.currentThread().suspend(); + while (true) { + Thread.sleep(60_000); + } } else { if (args.length > 0 && args[0].equals("-client")) { host = args[1]; diff --git a/test/jdk/java/nio/file/Files/probeContentType/Basic.java b/test/jdk/java/nio/file/Files/probeContentType/Basic.java index 8bf86320b3f96..8add9e76104b0 100644 --- a/test/jdk/java/nio/file/Files/probeContentType/Basic.java +++ b/test/jdk/java/nio/file/Files/probeContentType/Basic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* @test * @bug 4313887 8129632 8129633 8162624 8146215 8162745 8273655 8274171 8287237 8297609 + * @modules java.base/jdk.internal.util * @summary Unit test for probeContentType method * @library ../.. * @build Basic SimpleFileTypeDetector @@ -33,17 +34,18 @@ import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; +import jdk.internal.util.OperatingSystem; +import jdk.internal.util.OSVersion; + /** * Uses Files.probeContentType to probe html file, custom file type, and minimal * set of file extension to content type mappings. */ public class Basic { - private static final boolean IS_UNIX = - ! System.getProperty("os.name").startsWith("Windows"); - static Path createHtmlFile() throws IOException { Path file = Files.createTempFile("foo", ".html"); try (OutputStream out = Files.newOutputStream(file)) { @@ -79,7 +81,7 @@ private static int checkContentTypes(String expected, String actual) { assert actual != null; if (!expected.equals(actual)) { - if (IS_UNIX) { + if (!OperatingSystem.isWindows()) { Path userMimeTypes = Path.of(System.getProperty("user.home"), ".mime.types"); checkMimeTypesFile(userMimeTypes); @@ -98,12 +100,12 @@ private static int checkContentTypes(String expected, String actual) { return 0; } - static int checkContentTypes(ExType[] exTypes) + static int checkContentTypes(List exTypes) throws IOException { int failures = 0; - for (int i = 0; i < exTypes.length; i++) { - String extension = exTypes[i].extension(); - List expectedTypes = exTypes[i].expectedTypes(); + for (ExType exType : exTypes) { + String extension = exType.extension(); + List expectedTypes = exType.expectedTypes(); Path file = Files.createTempFile("foo", "." + extension); try { String type = Files.probeContentType(file); @@ -155,40 +157,55 @@ public static void main(String[] args) throws IOException { } // Verify that certain extensions are mapped to the correct type. - var exTypes = new ExType[] { - new ExType("adoc", List.of("text/plain")), - new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip")), - new ExType("css", List.of("text/css")), - new ExType("csv", List.of("text/csv")), - new ExType("doc", List.of("application/msword")), - new ExType("docx", List.of("application/vnd.openxmlformats-officedocument.wordprocessingml.document")), - new ExType("gz", List.of("application/gzip", "application/x-gzip")), - new ExType("jar", List.of("application/java-archive", "application/x-java-archive", "application/jar")), - new ExType("jpg", List.of("image/jpeg")), - new ExType("js", List.of("text/plain", "text/javascript", "application/javascript")), - new ExType("json", List.of("application/json")), - new ExType("markdown", List.of("text/markdown")), - new ExType("md", List.of("text/markdown", "application/x-genesis-rom")), - new ExType("mp3", List.of("audio/mpeg")), - new ExType("mp4", List.of("video/mp4")), - new ExType("odp", List.of("application/vnd.oasis.opendocument.presentation")), - new ExType("ods", List.of("application/vnd.oasis.opendocument.spreadsheet")), - new ExType("odt", List.of("application/vnd.oasis.opendocument.text")), - new ExType("pdf", List.of("application/pdf")), - new ExType("php", List.of("text/plain", "text/php", "application/x-php")), - new ExType("png", List.of("image/png")), - new ExType("ppt", List.of("application/vnd.ms-powerpoint")), - new ExType("pptx",List.of("application/vnd.openxmlformats-officedocument.presentationml.presentation")), - new ExType("py", List.of("text/plain", "text/x-python", "text/x-python-script")), - new ExType("rar", List.of("application/rar", "application/vnd.rar", "application/x-rar", "application/x-rar-compressed")), - new ExType("rtf", List.of("application/rtf", "text/rtf")), - new ExType("webm", List.of("video/webm")), - new ExType("webp", List.of("image/webp")), - new ExType("xls", List.of("application/vnd.ms-excel")), - new ExType("xlsx", List.of("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")), - new ExType("7z", List.of("application/x-7z-compressed")), - new ExType("wasm", List.of("application/wasm")), - }; + List exTypes = new ArrayList(); + + // extensions with consistent content type + exTypes.add(new ExType("adoc", List.of("text/plain"))); + exTypes.add(new ExType("css", List.of("text/css"))); + exTypes.add(new ExType("doc", List.of("application/msword"))); + exTypes.add(new ExType("docx", List.of("application/vnd.openxmlformats-officedocument.wordprocessingml.document"))); + exTypes.add(new ExType("gz", List.of("application/gzip", "application/x-gzip"))); + exTypes.add(new ExType("jar", List.of("application/java-archive", "application/x-java-archive", "application/jar"))); + exTypes.add(new ExType("jpg", List.of("image/jpeg"))); + exTypes.add(new ExType("js", List.of("text/plain", "text/javascript", "application/javascript"))); + exTypes.add(new ExType("json", List.of("application/json"))); + exTypes.add(new ExType("markdown", List.of("text/markdown"))); + exTypes.add(new ExType("md", List.of("text/markdown", "application/x-genesis-rom"))); + exTypes.add(new ExType("mp3", List.of("audio/mpeg"))); + exTypes.add(new ExType("mp4", List.of("video/mp4"))); + exTypes.add(new ExType("odp", List.of("application/vnd.oasis.opendocument.presentation"))); + exTypes.add(new ExType("ods", List.of("application/vnd.oasis.opendocument.spreadsheet"))); + exTypes.add(new ExType("odt", List.of("application/vnd.oasis.opendocument.text"))); + exTypes.add(new ExType("pdf", List.of("application/pdf"))); + exTypes.add(new ExType("php", List.of("text/plain", "text/php", "application/x-php"))); + exTypes.add(new ExType("png", List.of("image/png"))); + exTypes.add(new ExType("ppt", List.of("application/vnd.ms-powerpoint"))); + exTypes.add(new ExType("pptx", List.of("application/vnd.openxmlformats-officedocument.presentationml.presentation"))); + exTypes.add(new ExType("py", List.of("text/plain", "text/x-python", "text/x-python-script"))); + exTypes.add(new ExType("webm", List.of("video/webm"))); + exTypes.add(new ExType("webp", List.of("image/webp"))); + exTypes.add(new ExType("xls", List.of("application/vnd.ms-excel"))); + exTypes.add(new ExType("xlsx", List.of("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))); + exTypes.add(new ExType("wasm", List.of("application/wasm"))); + + // extensions with content type that differs on Windows 11+ + if (OperatingSystem.isWindows() && + (System.getProperty("os.name").endsWith("11") || + new OSVersion(10, 0).compareTo(OSVersion.current()) > 0)) { + System.out.println("Windows 11+ detected: using different types"); + exTypes.add(new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip", "application/x-compressed"))); + exTypes.add(new ExType("csv", List.of("text/csv", "application/vnd.ms-excel"))); + exTypes.add(new ExType("rar", List.of("application/rar", "application/vnd.rar", "application/x-rar", "application/x-rar-compressed", "application/x-compressed"))); + exTypes.add(new ExType("rtf", List.of("application/rtf", "text/rtf", "application/msword"))); + exTypes.add(new ExType("7z", List.of("application/x-7z-compressed", "application/x-compressed"))); + } else { + exTypes.add(new ExType("bz2", List.of("application/bz2", "application/x-bzip2", "application/x-bzip"))); + exTypes.add(new ExType("csv", List.of("text/csv"))); + exTypes.add(new ExType("rar", List.of("application/rar", "application/vnd.rar", "application/x-rar", "application/x-rar-compressed"))); + exTypes.add(new ExType("rtf", List.of("application/rtf", "text/rtf"))); + exTypes.add(new ExType("7z", List.of("application/x-7z-compressed"))); + } + failures += checkContentTypes(exTypes); // Verify type is found when the extension is in a fragment component diff --git a/test/jdk/java/security/Provider/SecurityProviderModularTest.java b/test/jdk/java/security/Provider/SecurityProviderModularTest.java index a919f104817fb..c475d59337057 100644 --- a/test/jdk/java/security/Provider/SecurityProviderModularTest.java +++ b/test/jdk/java/security/Provider/SecurityProviderModularTest.java @@ -47,10 +47,8 @@ * @bug 8130360 8183310 * @summary Test security provider in different combination of modular option * defined with(out) service description. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.module + * @enablePreview + * @modules java.base/jdk.internal.module * @library /test/lib * @build jdk.test.lib.util.JarUtils * jdk.test.lib.util.ModuleInfoWriter diff --git a/test/jdk/java/time/nontestng/java/time/chrono/HijrahConfigTest.java b/test/jdk/java/time/nontestng/java/time/chrono/HijrahConfigTest.java index 0506872cf44aa..1caaf68153b35 100644 --- a/test/jdk/java/time/nontestng/java/time/chrono/HijrahConfigTest.java +++ b/test/jdk/java/time/nontestng/java/time/chrono/HijrahConfigTest.java @@ -33,12 +33,8 @@ * @bug 8187987 * @requires (vm.compMode != "Xcomp" & os.maxMemory >= 2g) * @library /tools/lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jimage * jdk.compiler * @build HijrahConfigCheck tests.* diff --git a/test/jdk/java/util/Currency/PropertiesTest.sh b/test/jdk/java/util/Currency/PropertiesTest.sh deleted file mode 100644 index f7825640480af..0000000000000 --- a/test/jdk/java/util/Currency/PropertiesTest.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# @test -# @bug 6332666 6863624 7180362 8003846 8074350 8074351 8130246 8149735 7102969 -# 8157138 8190904 -# @summary tests the capability of replacing the currency data with user -# specified currency properties file -# @build PropertiesTest -# @run shell/timeout=600 PropertiesTest.sh - -if [ "${TESTSRC}" = "" ] -then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTCLASSES=${TESTCLASSES}" -echo "CLASSPATH=${CLASSPATH}" - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Linux | Darwin | AIX ) - PS=":" - FS="/" - ;; - Windows* ) - PS=";" - FS="/" - ;; - CYGWIN*|MSYS*|MINGW* ) - PS=";" - FS="/" - TESTJAVA=`cygpath -u ${TESTJAVA}` - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -failures=0 - -run() { - echo '' - ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} ${TESTJAVAOPTS} -cp ${TESTCLASSES} $* 2>&1 - if [ $? != 0 ]; then failures=`expr $failures + 1`; fi -} - -PROPS=${TESTSRC}${FS}currency.properties - - -# Dump built-in currency data - -run PropertiesTest -d dump1 -if [ ! -f dump1 ]; then echo "file dump1 not created. Test cannot execute. Failed."; exit 1; fi - -# Dump built-in currency data + overrides in properties file specified -# by system property. - -run -Djava.util.currency.data=${PROPS} PropertiesTest -d dump2 -if [ ! -f dump2 ]; then echo "file dump2 not created. Test cannot execute. Failed."; exit 1; fi -run PropertiesTest -c dump1 dump2 ${PROPS} - - -# Dump built-in currency data + overrides in properties file copied into -# JRE image. - -# Make a private copy of the jdk so we can write to the properties file location -# without disturbing other users, including concurrently executing tests. -WRITABLEJDK=.${FS}testjava -cp -H -R $TESTJAVA $WRITABLEJDK || exit 1 -PROPLOCATION=${WRITABLEJDK}${FS}lib -chmod -R u+w $WRITABLEJDK || exit 1 -cp ${PROPS} $PROPLOCATION || exit 1 -echo "Properties location: ${PROPLOCATION}" - -# run -echo '' -${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} ${TESTJAVAOPTS} -cp ${TESTCLASSES} PropertiesTest -d dump3 -if [ $? != 0 ]; then failures=`expr $failures + 1`; fi -if [ ! -f dump3 ]; then echo "file dump3 not created. Test cannot execute. Failed."; exit 1; fi - -# run bug7102969 test -echo '' -${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} ${TESTJAVAOPTS} -cp ${TESTCLASSES} PropertiesTest bug7102969 -if [ $? != 0 ]; then failures=`expr $failures + 1`; fi - -# run bug8157138 test -echo '' -${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} ${TESTJAVAOPTS} -cp ${TESTCLASSES} PropertiesTest bug8157138 -if [ $? != 0 ]; then failures=`expr $failures + 1`; fi - -# run bug8190904 test -echo '' -${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} ${TESTJAVAOPTS} -cp ${TESTCLASSES} PropertiesTest bug8190904 -if [ $? != 0 ]; then failures=`expr $failures + 1`; fi - -# Cleanup -rm -rf $WRITABLEJDK - -# compare the two dump files -run PropertiesTest -c dump1 dump3 ${PROPS} - - -# Results -echo '' -if [ $failures -gt 0 ]; - then echo "$failures tests failed"; - else echo "All tests passed"; fi -exit $failures diff --git a/test/jdk/java/util/Currency/PropertiesTestRun.java b/test/jdk/java/util/Currency/PropertiesTestRun.java new file mode 100644 index 0000000000000..6f2ea28a90d3a --- /dev/null +++ b/test/jdk/java/util/Currency/PropertiesTestRun.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6332666 6863624 7180362 8003846 8074350 8074351 8130246 8149735 7102969 + * 8157138 8190904 8210410 + * @summary Tests the capability of replacing the currency data with a user + * specified currency properties file in lib directory (old way) or + * via the system property in the cmdline (new way). + * @library /test/lib + * @build PropertiesTest + * @run junit PropertiesTestRun + */ + +import jdk.test.lib.Utils; +import jdk.test.lib.process.ProcessTools; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Arrays; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.fail; + +public class PropertiesTestRun { + + // String paths used for the cmdline processes + private static final String TEST_JDK = Utils.TEST_JDK; + private static final String TEST_PROPS = + Utils.TEST_SRC+Utils.FILE_SEPARATOR+"currency.properties"; + private static final String WRITABLE_JDK = + "."+Utils.FILE_SEPARATOR+"WRITABLE_JDK"; + private static final String WRITABLE_JDK_LIB = + WRITABLE_JDK+Utils.FILE_SEPARATOR+"lib"; + private static final String WRITABLE_JDK_BIN = + WRITABLE_JDK+Utils.FILE_SEPARATOR+"bin"; + private static final String WRITABLE_JDK_JAVA_PATH = + WRITABLE_JDK_BIN + Utils.FILE_SEPARATOR + "java"; + + // Create a writable JDK and set up dumps 1-3 + @BeforeAll + static void setUp() throws Throwable { + // Create separate JDK to supersede currencies via lib directory + createWritableJDK(); + // Create dump without user defined prop file + executeTestJDKMethod("PropertiesTest", "-d", "dump1"); + // Create dump with user defined prop file (via system property) + executeTestJDKMethod("-Djava.util.currency.data="+TEST_PROPS, + "PropertiesTest", "-d", "dump2"); + // Create dump with user defined prop file (via lib) + executeWritableJDKMethod("PropertiesTest", "-d", "dump3"); + } + + // Need to create a separate JDK to insert the user defined properties file + // into the lib folder. Create separate JDK to not disturb current TEST JDK. + private static void createWritableJDK() throws Throwable { + // Copy Test JDK into a separate JDK folder + executeProcess(new String[]{"cp", "-H", "-R", TEST_JDK, WRITABLE_JDK}); + // Make the separate JDK writable + executeProcess(new String[]{"chmod", "-R", "u+w", WRITABLE_JDK_LIB}); + // Copy the properties file into the writable JDK lib folder + executeProcess(new String[]{"cp", TEST_PROPS, WRITABLE_JDK_LIB}); + } + + // Compares the dumped output is expected between the default currencies + // and the user-defined custom currencies + @Test + void compareDumps() throws Throwable { + // Compare dump (from sys prop) + executeTestJDKMethod("PropertiesTest", "-c", "dump1", "dump2", + TEST_PROPS); + // Compare dump (from lib) + executeTestJDKMethod("PropertiesTest", "-c", "dump1", "dump3", + TEST_PROPS); + } + + // Launch a test from PropertiesTest. See PropertiesTest.java for more + // detail regarding a specific test that was launched. + @ParameterizedTest + @MethodSource("PropertiesTestMethods") + void launchPropertiesTests(String methodName) throws Throwable { + // Test via both the lib and system property + executeWritableJDKMethod("PropertiesTest", methodName); + executeTestJDKMethod("-Djava.util.currency.data="+TEST_PROPS, + "PropertiesTest", methodName); + } + + private static Stream PropertiesTestMethods() { + return Stream.of("bug7102969", "bug8157138", "bug8190904"); + } + + // Launch a PropertiesTest method using the TEST JDK + private static void executeTestJDKMethod(String... params) throws Throwable { + int exitStatus = ProcessTools.executeTestJvm(params).getExitValue(); + if (exitStatus != 0) { + fail("Process started with: " + Arrays.toString(params) + " failed"); + } + } + + // Launch a PropertiesTest method using the WRITABLE JDK + private static void executeWritableJDKMethod(String... params) throws Throwable { + // Need to include WritableJDK javapath, TEST JDK classpath + String[] allParams = new String[3+params.length+Utils.getTestJavaOpts().length]; + // We don't use executeTestJvm() because we want to point to separate JDK java path + allParams[0] = WRITABLE_JDK_JAVA_PATH; + allParams[1] = "-cp"; + allParams[2] = System.getProperty("java.class.path"); + // Add test.vm.opts and test.java.opts + System.arraycopy(Utils.getTestJavaOpts(), 0, allParams, 3, + Utils.getTestJavaOpts().length); + // Add the rest of the actual arguments + System.arraycopy(params, 0, allParams, Utils.getTestJavaOpts().length+3, + params.length); + // Launch the actual test method with all parameters set + executeProcess(allParams); + } + + // Execute a process and fail if the command is not successful + private static void executeProcess(String[] params) throws Throwable { + System.out.println("Command line: " + Arrays.toString(params)); + int exitStatus = ProcessTools.executeProcess(params).getExitValue(); + if (exitStatus != 0) { + fail("Process started with: " + Arrays.toString(params) + " failed"); + } + } + + @AfterAll + static void tearDown() throws Throwable { + // Remove the copied writable JDK image from scratch folder + executeProcess(new String[]{"rm", "-rf", WRITABLE_JDK}); + } +} diff --git a/test/jdk/java/util/Locale/LocaleProvidersRun.java b/test/jdk/java/util/Locale/LocaleProvidersRun.java index aae8ff03c11a0..947633a8e21ab 100644 --- a/test/jdk/java/util/Locale/LocaleProvidersRun.java +++ b/test/jdk/java/util/Locale/LocaleProvidersRun.java @@ -28,6 +28,7 @@ * 8150432 8215913 8220227 8228465 8232871 8232860 8236495 8245241 * 8246721 8248695 8257964 8261919 * @summary tests for "java.locale.providers" system property + * @requires vm.flagless * @library /test/lib * @build LocaleProviders * providersrc.spi.src.tznp @@ -179,8 +180,8 @@ public static void main(String[] args) throws Throwable { private static void testRun(String prefList, String methodName, String param1, String param2, String param3) throws Throwable { - // Build process (with VM flags) - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + // Build process (without VM flags) + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( "-ea", "-esa", "-cp", Utils.TEST_CLASS_PATH, "-Djava.util.logging.config.class=LocaleProviders$LogConfig", diff --git a/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java b/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java index b81c69a426938..e0fdb9a93abb9 100644 --- a/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java +++ b/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java @@ -26,6 +26,7 @@ * @bug 8137317 8139238 8210408 * @summary Visibility tests for ResourceBundle.getBundle with and without * an unnamed module argument. + * @requires vm.flagless * @library /test/lib * .. * @build jdk.test.lib.JDKToolLauncher @@ -330,8 +331,8 @@ public void RunWithPkgRes(List argsList) throws Throwable { } private int runCmd(List argsList) throws Throwable { - // Build process (with VM flags) - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + // Build process (without VM flags) + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( Stream.concat(Stream.of("-ea", "-esa"), argsList.stream()).toList()); // Evaluate process status return ProcessTools.executeCommand(pb).getExitValue(); diff --git a/test/jdk/java/util/concurrent/ConcurrentLinkedQueue/WhiteBox.java b/test/jdk/java/util/concurrent/ConcurrentLinkedQueue/WhiteBox.java index 63fd29a8a9a4d..2ea188aed46f5 100644 --- a/test/jdk/java/util/concurrent/ConcurrentLinkedQueue/WhiteBox.java +++ b/test/jdk/java/util/concurrent/ConcurrentLinkedQueue/WhiteBox.java @@ -281,36 +281,6 @@ public void pollActionsOneNodeSlack( assertInvariants(q); } - /** - * Actions that append an element, and are expected to - * leave at most one slack node at tail. - */ - @DataProvider - public Object[][] addActions() { - return List.>of( - q -> q.add(1), - q -> q.offer(1)) - .stream().map(x -> new Object[]{ x }).toArray(Object[][]::new); - } - - @Test(dataProvider = "addActions") - public void addActionsOneNodeSlack( - Consumer addAction) { - ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(); - int n = 1 + rnd.nextInt(5); - for (int i = 0; i < n; i++) { - boolean slack = next(tail(q)) != null; - addAction.accept(q); - if (slack) - assertNull(next(tail(q))); - else { - assertNotNull(next(tail(q))); - assertNull(next(next(tail(q)))); - } - assertInvariants(q); - } - } - byte[] serialBytes(Object o) { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); diff --git a/test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java b/test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java index 781b7bffe6d0c..7db3e20a2fb75 100644 --- a/test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java +++ b/test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java @@ -626,6 +626,22 @@ public void testSubmitEE() throws Throwable { } } + /** + * invoke throws a RuntimeException if task throws unchecked exception + */ + public void testInvokeUncheckedException() throws Throwable { + ForkJoinPool p = new ForkJoinPool(1); + try (PoolCleaner cleaner = cleaner(p)) { + try { + p.invoke(ForkJoinTask.adapt(new Callable() { + public Object call() { throw new ArithmeticException(); }})); + shouldThrow(); + } catch (RuntimeException success) { + assertTrue(success.getCause() instanceof ArithmeticException); + } + } + } + /** * invokeAny(null) throws NullPointerException */ diff --git a/test/jdk/java/util/stream/GathererAPITest.java b/test/jdk/java/util/stream/GathererAPITest.java new file mode 100644 index 0000000000000..4bcda85ccbc05 --- /dev/null +++ b/test/jdk/java/util/stream/GathererAPITest.java @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.util.List; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Supplier; +import java.util.stream.*; +import java.util.stream.Gatherer; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; + +/** + * @test + * @summary Testing public API of Gatherer + * @enablePreview + * @run junit GathererAPITest + */ + +public class GathererAPITest { + final static Supplier initializer = () -> (Void)null; + final static Gatherer.Integrator integrator = (v,e,d) -> d.push(e); + final static BinaryOperator combiner = (l,r) -> l; + final static BiConsumer> finisher = (v,d) -> {}; + + final static Supplier nullInitializer = null; + final static Gatherer.Integrator nullIntegrator = null; + final static BinaryOperator nullCombiner = null; + final static BiConsumer> nullFinisher = null; + + private final static Gatherer passthrough() { + return Gatherer.of( + () -> (Void)null, + Gatherer.Integrator.ofGreedy((v,e,d) -> d.push(e)), + (l,r) -> l, + (v,d) -> {} + ); + } + + private final static Gatherer verifyGathererContract(Gatherer gatherer) { + // basics + assertNotNull(gatherer); + + // components + assertNotNull(gatherer.initializer()); + assertNotNull(gatherer.integrator()); + assertNotNull(gatherer.combiner()); + assertNotNull(gatherer.finisher()); + assertNotNull(gatherer.andThen(passthrough())); + + return gatherer; + } + + private final static Gatherer verifyGathererStructure( + Gatherer gatherer, + Supplier expectedSupplier, + Gatherer.Integrator expectedIntegrator, + BinaryOperator expectedCombiner, + BiConsumer> expectedFinisher + ) { + // basics + assertNotNull(gatherer); + + // components + assertSame(expectedSupplier, gatherer.initializer()); + assertSame(expectedIntegrator, gatherer.integrator()); + assertSame(expectedCombiner, gatherer.combiner()); + assertSame(expectedFinisher, gatherer.finisher()); + + return gatherer; + } + + @Test + public void testGathererDefaults() { + final Gatherer.Integrator expectedIntegrator = + (a,b,c) -> false; + + class Test implements Gatherer { + @Override + public Integrator integrator() { + return expectedIntegrator; + } + } + + var t = new Test(); + assertSame(Gatherer.defaultInitializer(), t.initializer()); + assertSame(expectedIntegrator, t.integrator()); + assertSame(Gatherer.defaultCombiner(), t.combiner()); + assertSame(Gatherer.>defaultFinisher(), t.finisher()); + } + + @Test + public void testDownstreamDefaults() { + class Test implements Gatherer.Downstream { + @Override public boolean push(Void v) { return false; } + } + + var t = new Test(); + assertEquals(false, t.isRejecting()); + } + + @Test + public void testGathererFactoriesNPE() { + assertThrows(NullPointerException.class, + () -> Gatherer.of(nullInitializer, integrator, combiner, finisher)); + assertThrows(NullPointerException.class, + () -> Gatherer.of(initializer, nullIntegrator, combiner, finisher)); + assertThrows(NullPointerException.class, + () -> Gatherer.of(initializer, integrator, nullCombiner, finisher)); + assertThrows(NullPointerException.class, + () -> Gatherer.of(initializer, integrator, combiner, nullFinisher)); + + assertThrows(NullPointerException.class, + () -> Gatherer.of(nullIntegrator)); + + assertThrows(NullPointerException.class, + () -> Gatherer.of(nullIntegrator, finisher)); + assertThrows(NullPointerException.class, + () -> Gatherer.of(integrator, nullFinisher)); + + assertThrows(NullPointerException.class, + () -> Gatherer.ofSequential(nullInitializer, integrator)); + assertThrows(NullPointerException.class, + () -> Gatherer.ofSequential(initializer, nullIntegrator)); + + assertThrows(NullPointerException.class, + () -> Gatherer.ofSequential(nullIntegrator)); + + assertThrows(NullPointerException.class, + () -> Gatherer.ofSequential(nullIntegrator, finisher)); + assertThrows(NullPointerException.class, + () -> Gatherer.ofSequential(integrator, nullFinisher)); + + assertThrows(NullPointerException.class, + () -> Gatherer.ofSequential(nullInitializer, integrator, finisher)); + assertThrows(NullPointerException.class, + () -> Gatherer.ofSequential(initializer, nullIntegrator, finisher)); + assertThrows(NullPointerException.class, + () -> Gatherer.ofSequential(initializer, integrator, nullFinisher)); + } + + @Test + public void testGathererFactoriesAPI() { + final var defaultInitializer = Gatherer.defaultInitializer(); + final var defaultCombiner = Gatherer.defaultCombiner(); + final var defaultFinisher = Gatherer.defaultFinisher(); + + var g1 = verifyGathererContract(passthrough()); // Quis custodiet ipsos custodes? + verifyGathererContract(g1.andThen(g1)); + + var g2 = verifyGathererContract(Gatherer.of(integrator)); + verifyGathererContract(g2.andThen(g2)); + assertSame(defaultInitializer, g2.initializer()); + assertSame(integrator, g2.integrator()); + assertNotSame(defaultCombiner, g2.combiner()); + assertSame(defaultFinisher, g2.finisher()); + + var g3 = verifyGathererContract(Gatherer.of(integrator, finisher)); + verifyGathererContract(g3.andThen(g3)); + assertSame(integrator, g3.integrator()); + assertNotSame(defaultCombiner, g3.combiner()); + assertSame(finisher, g3.finisher()); + + var g4 = verifyGathererContract(Gatherer.ofSequential(integrator)); + verifyGathererContract(g4.andThen(g4)); + verifyGathererStructure(g4, defaultInitializer, integrator, defaultCombiner, defaultFinisher); + + var g5 = verifyGathererContract(Gatherer.ofSequential(initializer, integrator)); + verifyGathererContract(g5.andThen(g5)); + verifyGathererStructure(g5, initializer, integrator, defaultCombiner, defaultFinisher); + + var g6 = verifyGathererContract(Gatherer.ofSequential(integrator, finisher)); + verifyGathererContract(g6.andThen(g6)); + verifyGathererStructure(g6, defaultInitializer, integrator, defaultCombiner, finisher); + + var g7 = verifyGathererContract(Gatherer.ofSequential(initializer, integrator, finisher)); + verifyGathererContract(g7.andThen(g7)); + verifyGathererStructure(g7, initializer, integrator, defaultCombiner, finisher); + + var g8 = verifyGathererContract(Gatherer.of(initializer, integrator, combiner, finisher)); + verifyGathererContract(g8.andThen(g8)); + verifyGathererStructure(g8, initializer, integrator, combiner, finisher); + } + + @Test + public void testGathererVariance() { + + // Make sure that Gatherers can pass-through type + Gatherer nums = Gatherer.of((unused, element, downstream) -> downstream.push(element)); + + // Make sure that Gatherers can upcast the output type from the input type + Gatherer upcast = Gatherer.of((unused, element, downstream) -> downstream.push(element)); + + // Make sure that Gatherers can consume a supertype of the Stream output + assertEquals(List.of(1,2,3,4,5), Stream.of(1,2,3,4,5).gather(nums).toList()); + + Gatherer ints = Gatherer.of((unused, element, downstream) -> downstream.push(element)); + + // Make sure that Gatherers can be composed where the output is a subtype of the input type of the next + Gatherer composition = ints.andThen(nums); + + // Make sure that composition works transitively, typing-wise + Gatherer upcastComposition = ints.andThen(nums.andThen(upcast)); + + assertEquals(List.of(1,2,3,4,5), Stream.of(1,2,3,4,5).gather(composition).toList()); + assertEquals(List.of(1,2,3,4,5), Stream.of(1,2,3,4,5).gather(upcastComposition).toList()); + } +} diff --git a/test/jdk/java/util/stream/GathererTest.java b/test/jdk/java/util/stream/GathererTest.java new file mode 100644 index 0000000000000..3d8e608cc6c2d --- /dev/null +++ b/test/jdk/java/util/stream/GathererTest.java @@ -0,0 +1,479 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.*; +import java.util.stream.Gatherer; +import static java.util.stream.DefaultMethodStreams.delegateTo; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; + +/** + * @test + * @summary Testing the Gatherer contract + * @enablePreview + * @library /lib/testlibrary/bootlib + * @build java.base/java.util.stream.DefaultMethodStreams + * @run junit GathererTest + */ + +public class GathererTest { + + record Config(int streamSize, boolean parallel, boolean defaultImpl) { + + Stream countTo(int n) { + return Stream.iterate(1, i -> i + 1).limit(n); + } + + Stream stream() { + return wrapStream(countTo(streamSize)); + } + + Stream wrapStream(Stream stream) { + stream = parallel ? stream.parallel() : stream.sequential(); + stream = defaultImpl ? delegateTo(stream) : stream; + return stream; + } + + List list() { + return stream().toList(); + } + } + + final static Stream configurations() { + return Stream.of(0,1,10,33,99,9999) + .flatMap(size -> + Stream.of(false, true) + .flatMap(parallel -> + Stream.of(false, true).map( defaultImpl -> + new Config(size, parallel, + defaultImpl)) ) + ); + } + + final class TestException extends RuntimeException { + TestException(String message) { + super(message); + } + } + + final static class InvocationTracker { + int initialize; + int integrate; + int combine; + int finish; + + void copyFrom(InvocationTracker other) { + initialize = other.initialize; + integrate = other.integrate; + combine = other.combine; + finish = other.finish; + } + + void combine(InvocationTracker other) { + if (other != this) { + initialize += other.initialize; + integrate += other.integrate; + combine += other.combine + 1; // track this merge + finish += other.finish; + } + } + } + + final Gatherer addOne = Gatherer.of( + Gatherer.Integrator.ofGreedy((vöid, element, downstream) -> downstream.push(element + 1)) + ); + + final Gatherer timesTwo = Gatherer.of( + Gatherer.Integrator.ofGreedy((vöid, element, downstream) -> downstream.push(element * 2)) + ); + + @ParameterizedTest + @MethodSource("configurations") + public void testInvocationSemanticsGreedy(Config config) { + var result = new InvocationTracker(); + var g = Gatherer.of( + () -> { + var t = new InvocationTracker(); + t.initialize++; + return t; + }, + Gatherer.Integrator.ofGreedy((t, e, d) -> { + t.integrate++; + return d.push(e); + }), + (t1, t2) -> { + t1.combine(t2); + return t1; + }, + (t, d) -> { + t.finish++; + result.copyFrom(t); + }); + var res = config.stream().gather(g).toList(); + assertEquals(config.countTo(config.streamSize).toList(), res); + if (config.parallel) { + assertTrue(result.initialize > 0); + assertEquals(config.streamSize, result.integrate); + assertTrue(config.streamSize < 2 || result.combine > 0); + assertEquals(1, result.finish); + } else { + assertEquals(1, result.initialize); + assertEquals(config.streamSize, result.integrate); + assertEquals(0, result.combine); + assertEquals(1, result.finish); + } + } + + @ParameterizedTest + @MethodSource("configurations") + public void testInvocationSemanticsShortCircuit(Config config) { + final int CONSUME_UNTIL = Math.min(config.streamSize, 5); + var result = new InvocationTracker(); + var g = Gatherer.of( + () -> { + var t = new InvocationTracker(); + t.initialize++; + return t; + }, + (t, e, d) -> { + ++t.integrate; + return e <= CONSUME_UNTIL && d.push(e) && e != CONSUME_UNTIL; + }, + (t1, t2) -> { + t1.combine(t2); + return t1; + }, + (t, d) -> { + t.finish++; + result.copyFrom(t); + }); + var res = config.stream().gather(g).toList(); + assertEquals(config.countTo(CONSUME_UNTIL).toList(), res); + if (config.parallel) { + assertTrue(result.initialize > 0); + assertEquals(CONSUME_UNTIL, result.integrate); + assertTrue(result.combine >= 0); // We can't guarantee split sizes + assertEquals(1, result.finish); + } else { + assertEquals(1, result.initialize); + assertEquals(CONSUME_UNTIL, result.integrate); + assertEquals(0, result.combine); + assertEquals(1, result.finish); + } + } + + @ParameterizedTest + @MethodSource("configurations") + public void testEmissionDuringFinisher(Config config) { + var g = Gatherer.of( + () -> { + var t = new InvocationTracker(); + t.initialize++; + return t; + }, + (t, e, d) -> { + t.integrate++; + return true; + }, + (t1, t2) -> { + t1.combine(t2); + return t1; + }, + (t, d) -> { + t.finish++; + d.push(t); + }); + var resultList = config.stream().gather(g).collect(Collectors.toList()); + assertEquals(resultList.size(), 1); + + var t = resultList.get(0); + + if (config.parallel) { + assertTrue(t.initialize > 0); + assertEquals(config.streamSize, t.integrate); + assertTrue(config.streamSize < 2 || t.combine > 0); + assertEquals(1, t.finish); + } else { + assertEquals(1, t.initialize); + assertEquals(config.streamSize, t.integrate); + assertEquals(0, t.combine); + assertEquals(1, t.finish); + } + } + + @ParameterizedTest + @MethodSource("configurations") + public void testInvocationSemanticsShortCircuitDuringCollect(Config config) { + final int CONSUME_UNTIL = Math.min(config.streamSize, 5); + var result = new InvocationTracker(); + var g = Gatherer.of( + () -> { + var t = new InvocationTracker(); + t.initialize++; + return t; + }, + (t, e, d) -> { + t.integrate++; + return e <= CONSUME_UNTIL && d.push(e) && e != CONSUME_UNTIL; + }, + (t1, t2) -> { + t1.combine(t2); + return t1; + }, + (t, d) -> { + t.finish++; + result.copyFrom(t); + }); + var res = config.stream().gather(g).collect(Collectors.toList()); + assertEquals(config.countTo(CONSUME_UNTIL).toList(), res); + if (config.parallel) { + assertTrue(result.initialize > 0); + assertEquals(CONSUME_UNTIL, result.integrate); + assertTrue(result.combine >= 0); // We can't guarantee split sizes + assertEquals(result.finish, 1); + } else { + assertEquals(result.initialize, 1); + assertEquals(CONSUME_UNTIL, result.integrate); + assertEquals(result.combine, 0); + assertEquals(result.finish, 1); + } + } + + @ParameterizedTest + @MethodSource("configurations") + public void testCompositionOfStatelessGatherers(Config config) { + var range = config.stream().toList(); + var gRes = range.stream().gather(addOne.andThen(timesTwo)).toList(); + var rRes = range.stream().map(j -> j + 1).map(j -> j * 2).toList(); + assertEquals(config.streamSize, gRes.size()); + assertEquals(config.streamSize, rRes.size()); + assertEquals(gRes, rRes); + } + + @ParameterizedTest + @MethodSource("configurations") + public void testCompositionOfStatefulGatherers(Config config) { + var t1 = new InvocationTracker(); + var g1 = Gatherer.of( + () -> { + var t = new InvocationTracker(); + t.initialize++; + return t; + }, + (t, e, d) -> { + t.integrate++; + return d.push(e); + }, + (l, r) -> { + l.combine(r); + return l; + }, + (t, d) -> { + t.finish++; + t1.copyFrom(t); + }); + + var t2 = new InvocationTracker(); + var g2 = Gatherer.of( + () -> { + var t = new InvocationTracker(); + t.initialize++; + return t; + }, + (t, e, d) -> { + t.integrate++; + return d.push(e); + }, + (l, r) -> { + l.combine(r); + return l; + }, + (t, d) -> { + t.finish++; + t2.copyFrom(t); + }); + + var res = config.stream().gather(g1.andThen(g2)).toList(); + assertEquals(config.stream().toList(), res); + + if (config.parallel) { + assertTrue(t1.initialize > 0); + assertEquals(config.streamSize, t1.integrate); + assertTrue(config.streamSize < 2 || t1.combine > 0); + assertEquals(1, t1.finish); + + assertTrue(t2.initialize > 0); + assertEquals(config.streamSize, t2.integrate); + assertTrue(config.streamSize < 2 || t2.combine > 0); + assertEquals(1, t2.finish); + } else { + assertEquals(1, t1.initialize); + assertEquals(config.streamSize, t1.integrate); + assertEquals(0, t1.combine); + assertEquals(1, t1.finish); + + assertEquals(1, t2.initialize); + assertEquals(config.streamSize, t2.integrate); + assertEquals(0, t2.combine); + assertEquals(1, t2.finish); + } + } + + @ParameterizedTest + @MethodSource("configurations") + public void testMassivelyComposedGatherers(Config config) { + final int ITERATIONS = 256; // Total number of compositions is 1 + (iterations*2) + Gatherer g = addOne; + for(int i = 0;i < ITERATIONS;++i) { + g = g.andThen(timesTwo).andThen(addOne); + } + + g = g.andThen(timesTwo); + + var ref = config.stream().map(n -> n + 1); + for(int c = 0; c < ITERATIONS; ++c) { + ref = ref.map(n -> n * 2).map(n -> n + 1); + } + ref = ref.map(n -> n * 2); + + var gatherered = config.stream().gather(g).toList(); + var reference = ref.toList(); + assertEquals(gatherered, reference); + } + + @Test + public void testUnboundedEmissions() { + Gatherer g = Gatherer.of( + () -> (Void)null, + (v,e,d) -> { do {} while(d.push(e)); return false; }, + (l,r) -> l, + (v,d) -> {} + ); + assertEquals(Stream.of(1).gather(g).limit(1).toList(), List.of(1)); + assertEquals(Stream.of(1).gather(g.andThen(g)).limit(1).toList(), List.of(1)); + } + + @ParameterizedTest + @MethodSource("configurations") + public void testCompositionSymmetry(Config config) { + var consecutiveResult = config.stream().gather(addOne).gather(timesTwo).toList(); + var interspersedResult = config.stream().gather(addOne).map(id -> id).gather(timesTwo).toList(); + var composedResult = config.stream().gather(addOne.andThen(timesTwo)).toList(); + + var reference = config.stream().map(j -> j + 1).map(j -> j * 2).toList(); + + assertEquals(config.streamSize, consecutiveResult.size()); + assertEquals(config.streamSize, interspersedResult.size()); + assertEquals(config.streamSize, composedResult.size()); + assertEquals(config.streamSize, reference.size()); + + assertEquals(consecutiveResult, reference); + assertEquals(interspersedResult, reference); + assertEquals(composedResult, reference); + } + + @ParameterizedTest + @MethodSource("configurations") + public void testExceptionInInitializer(Config config) { + final var expectedMessage = "testExceptionInInitializer()"; + assertThrowsTestException(() -> + config.stream().gather( + Gatherer.of( + () -> { throw new TestException(expectedMessage); }, + (i, e, d) -> true, + (l,r) -> l, + (i,d) -> {} + ) + ).toList(), expectedMessage); + } + + @ParameterizedTest + @MethodSource("configurations") + public void testExceptionInIntegrator(Config config) { + if (config.streamSize < 1) return; // No exceptions expected + + final var expectedMessage = "testExceptionInIntegrator()"; + assertThrowsTestException(() -> + config.stream().gather( + Gatherer.of( + () -> 1, + (i, e, d) -> { throw new TestException(expectedMessage); }, + (l,r) -> l, + (i,d) -> {} + ) + ).toList() + , expectedMessage); + } + + @ParameterizedTest + @MethodSource("configurations") + public void testExceptionInCombiner(Config config) { + if (config.streamSize < 2 || !config.parallel) return; // No exceptions expected + + final var expectedMessage = "testExceptionInCombiner()"; + assertThrowsTestException(() -> + config.stream().gather( + Gatherer.of( + () -> 1, + (i, e, d) -> true, + (l,r) -> { throw new TestException(expectedMessage); }, + (i,d) -> {} + ) + ).toList() + , expectedMessage); + } + + @ParameterizedTest + @MethodSource("configurations") + public void testExceptionInFinisher(Config config) { + final var expectedMessage = "testExceptionInFinisher()"; + assertThrowsTestException(() -> + config.stream().gather( + Gatherer.of( + () -> 1, + (i, e, d) -> true, + (l,r) -> l, + (v, d) -> { throw new TestException(expectedMessage); } + ) + ).toList() + , expectedMessage); + } + + private final static void assertThrowsTestException(Supplier supplier, String expectedMessage) { + try { + var discard = supplier.get(); + } catch (TestException e) { + assertSame(TestException.class, e.getClass()); + assertEquals(expectedMessage, e.getMessage()); + return; + } + fail("Expected TestException but wasn't thrown!"); + } +} diff --git a/test/jdk/java/util/stream/GatherersFoldTest.java b/test/jdk/java/util/stream/GatherersFoldTest.java new file mode 100644 index 0000000000000..caecff19e3ac5 --- /dev/null +++ b/test/jdk/java/util/stream/GatherersFoldTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.List; +import java.util.stream.Gatherers; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; + +/** + * @test + * @summary Tests the API and contract of Gatherers.fold + * @enablePreview + * @run junit GatherersFoldTest + */ + +public class GatherersFoldTest { + + record Config(int streamSize, boolean parallel) { + Stream stream() { + var stream = Stream.iterate(1, i -> i + 1).limit(streamSize); + stream = parallel ? stream.parallel() : stream.sequential(); + return stream; + } + } + + static final Stream sizes(){ + return Stream.of(0,1,10,33,99,9999); + } + + static final Stream sequentialAndParallel(int size) { + return Stream.of(false, true) + .map(parallel -> + new Config(size, parallel)); + } + + static final Stream configurations() { + return sizes().flatMap(i -> sequentialAndParallel(i)); + } + + @Test + public void throwsNPEWhenStateSupplierIsNull() { + assertThrows(NullPointerException.class, () -> Gatherers.fold(null, (state, next) -> state)); + } + + @Test + public void throwsNPEWhenFolderFunctionIsNull() { + assertThrows(NullPointerException.class, () -> Gatherers.fold(() -> "", null)); + } + + @ParameterizedTest + @MethodSource("configurations") + public void behavesAsExpected(Config config) { + final var expectedResult = List.of( + config.stream() + .sequential() + .reduce(0L, (acc, next) -> acc + next,(l, r) -> { + throw new IllegalStateException(); + }) + ); + + final var result = config.stream() + .gather(Gatherers.fold(() -> 0L, (acc, next) -> acc + next)) + .toList(); + + assertEquals(expectedResult, result); + } +} diff --git a/test/jdk/java/util/stream/GatherersMapConcurrentTest.java b/test/jdk/java/util/stream/GatherersMapConcurrentTest.java new file mode 100644 index 0000000000000..5ff845f55b9a4 --- /dev/null +++ b/test/jdk/java/util/stream/GatherersMapConcurrentTest.java @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Semaphore; +import java.util.stream.Gatherer; +import java.util.stream.Gatherers; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; + +/** + * @test + * @summary Tests the API and contract of Gatherers.mapConcurrent + * @enablePreview + * @run junit GatherersMapConcurrentTest + */ + +public class GatherersMapConcurrentTest { + + record Config(int streamSize, boolean parallel) { + Stream stream() { + var stream = Stream.iterate(1, i -> i + 1).limit(streamSize); + stream = parallel ? stream.parallel() : stream.sequential(); + return stream; + } + } + + record ConcurrencyConfig(Config config, int concurrencyLevel) {} + + static final Stream sizes(){ + return Stream.of(0,1,10,33,99,9999); + } + + static final Stream concurrencyLevels() { return Stream.of(1, 2, 3, 10, + 1000); } + + static final Stream sequentialAndParallel(int size) { + return Stream.of(false, true) + .map(parallel -> + new Config(size, parallel)); + } + + static final Stream configurations() { + return sizes().flatMap(i -> sequentialAndParallel(i)); + } + + static final Stream concurrencyConfigurations() { + return configurations().flatMap( c -> concurrencyLevels().map( l -> new ConcurrencyConfig(c, l)) ); + } + + static final Stream small_atleast3_configurations() { + return sizes().filter(i -> i > 2 && i < 100).flatMap(i -> sequentialAndParallel(i)); + } + + static final class TestException extends RuntimeException { + TestException(String message) { + super(message); + } + } + + @ParameterizedTest + @ValueSource(ints = { Integer.MIN_VALUE, -999, -1, 0}) + public void throwsIAEWhenConcurrencyLevelIsLowerThanOne(int level) { + assertThrows(IllegalArgumentException.class, + () -> Gatherers.mapConcurrent(level, s -> s)); + } + + @Test + public void throwsNPEWhenMapperFunctionIsNull() { + assertThrows(NullPointerException.class, () -> Gatherers.mapConcurrent(2, null)); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false } ) + public void rethrowsRuntimeExceptionsUnwrapped(boolean parallel) { + final var stream = parallel ? Stream.of(1).parallel() : Stream.of(1); + + var exception = + assertThrows( + RuntimeException.class, + () -> stream.gather( + Gatherers.mapConcurrent(2, x -> { + throw new RuntimeException("expected"); + }) + ).toList() + ); + assertEquals("expected", exception.getMessage()); + assertNull(exception.getCause()); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false } ) + public void rethrowsSubtypesOfRuntimeExceptionsUnwrapped(boolean parallel) { + final var stream = parallel ? Stream.of(1).parallel() : Stream.of(1); + + var exception = + assertThrows( + IllegalStateException.class, + () -> stream.gather( + Gatherers.mapConcurrent(2, x -> { + throw new IllegalStateException("expected"); + }) + ).toList() + ); + assertEquals("expected", exception.getMessage()); + assertNull(exception.getCause()); + } + + @ParameterizedTest + @ValueSource(booleans = { true, false } ) + public void rethrowsErrorsWrappedAsRuntimeExceptions(boolean parallel) { + final var stream = parallel ? Stream.of(1).parallel() : Stream.of(1); + + var exception = + assertThrows( + RuntimeException.class, + () -> stream.gather( + Gatherers.mapConcurrent(2, x -> { + throw new Error("expected"); + }) + ).toList() + ); + assertEquals("expected", exception.getCause().getMessage()); + assertEquals(Error.class, exception.getCause().getClass()); + } + + @ParameterizedTest + @MethodSource("small_atleast3_configurations") + public void cancelsStartedTasksIfExceptionDuringProcessingIsThrown(Config config) { + final var streamSize = config.streamSize(); + + assertTrue(streamSize > 2, "This test case won't work with tiny streams!"); + + final var tasksToCancel = streamSize - 2; + final var throwerReady = new CountDownLatch(1); + final var initiateThrow = new CountDownLatch(1); + final var tasksCancelled = new CountDownLatch(tasksToCancel); + + final var tasksWaiting = new Semaphore(0); + + try { + config.stream() + .gather( + Gatherers.mapConcurrent(streamSize, i -> { + switch (i) { + case 1 -> { + throwerReady.countDown(); + try { initiateThrow.await(); } + catch (InterruptedException ie) { + fail("Unexpected"); + } + throw new TestException("expected"); + } + + case Integer n when n == streamSize -> { + try { throwerReady.await(); } + catch (InterruptedException ie) { + fail("Unexpected"); + } + while(tasksWaiting.getQueueLength() < tasksToCancel) { + try { + Thread.sleep(10); + } catch (InterruptedException ie) { + // Ignore + } + } + initiateThrow.countDown(); + } + + default -> { + try { + tasksWaiting.acquire(); + } catch (InterruptedException ie) { + tasksCancelled.countDown(); // used to ensure that they all were interrupted + } + } + } + + return i; + }) + ) + .toList(); + fail("This should not be reached"); + } catch (TestException te) { + assertEquals("expected", te.getMessage()); + try { tasksCancelled.await(); } + catch (InterruptedException ie) { + fail("Unexpected"); + } + return; + } + + fail("This should not be reached"); + } + + @ParameterizedTest + @MethodSource("small_atleast3_configurations") + public void cancelsStartedTasksIfShortCircuited(Config config) { + final var streamSize = config.streamSize(); + + assertTrue(streamSize > 2, "This test case won't work with tiny streams!"); + + final var tasksToCancel = streamSize - 2; + final var firstReady = new CountDownLatch(1); + final var lastDone = new CountDownLatch(1); + final var tasksCancelled = new CountDownLatch(tasksToCancel); + + final var tasksWaiting = new Semaphore(0); + + final var result = + config.stream().gather( + Gatherers.mapConcurrent(streamSize, i -> { + switch (i) { + case 1 -> { + firstReady.countDown(); + try { lastDone.await(); } + catch (InterruptedException ie) { + fail("Unexpected!"); + } + } + + case Integer n when n == streamSize -> { + try { firstReady.await(); } + catch (InterruptedException ie) { + fail("Unexpected!"); + } + while(tasksWaiting.getQueueLength() < tasksToCancel) { + try { + Thread.sleep(10); + } catch (InterruptedException ie) { + // Ignore + } + } + lastDone.countDown(); + } + + default -> { + try { + tasksWaiting.acquire(); + } catch (InterruptedException ie) { + tasksCancelled.countDown(); // used to ensure that they all were interrupted + } + } + } + + return i; + }) + ) + .gather(Gatherer.of((unused, state, downstream) -> downstream.push(state) && false)) // emulate limit(1) + .toList(); + assertEquals(List.of(1), result); + try { + tasksCancelled.await(); + } catch (InterruptedException ie) { + fail("Unexpected"); + } + } + + @ParameterizedTest + @MethodSource("concurrencyConfigurations") + public void behavesAsExpected(ConcurrencyConfig cc) { + final var expectedResult = cc.config().stream() + .map(x -> x * x) + .toList(); + + final var result = cc.config().stream() + .gather(Gatherers.mapConcurrent(cc.concurrencyLevel(), x -> x * x)) + .toList(); + + assertEquals(expectedResult, result); + } + + @ParameterizedTest + @MethodSource("concurrencyConfigurations") + public void behavesAsExpectedWhenShortCircuited(ConcurrencyConfig cc) { + final var limitTo = Math.max(cc.config().streamSize() / 2, 1); + + final var expectedResult = cc.config().stream() + .map(x -> x * x) + .limit(limitTo) + .toList(); + + final var result = cc.config().stream() + .gather(Gatherers.mapConcurrent(cc.concurrencyLevel(), x -> x * x)) + .limit(limitTo) + .toList(); + + assertEquals(expectedResult, result); + } +} diff --git a/test/jdk/java/util/stream/GatherersScanTest.java b/test/jdk/java/util/stream/GatherersScanTest.java new file mode 100644 index 0000000000000..993a616233c70 --- /dev/null +++ b/test/jdk/java/util/stream/GatherersScanTest.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Gatherers; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; + +/** + * @test + * @summary Tests the API and contract of Gatherers.scan + * @enablePreview + * @run junit GatherersScanTest + */ + +public class GatherersScanTest { + + record Config(int streamSize, boolean parallel) { + Stream stream() { + var stream = Stream.iterate(1, i -> i + 1).limit(streamSize); + stream = parallel ? stream.parallel() : stream.sequential(); + return stream; + } + } + + static final Stream sizes(){ + return Stream.of(0,1,10,33,99,9999); + } + + static final Stream sequentialAndParallel(int size) { + return Stream.of(false, true) + .map(parallel -> + new Config(size, parallel)); + } + + static final Stream configurations() { + return sizes().flatMap(i -> sequentialAndParallel(i)); + } + + @Test + public void throwsNPEWhenStateSupplierIsNull() { + assertThrows(NullPointerException.class, + () -> Gatherers.scan(null, (state, next) -> state)); + } + + @Test + public void throwsNPEWhenScannerFunctionIsNull() { + assertThrows(NullPointerException.class, + () -> Gatherers.scan(() -> "", null)); + } + + @ParameterizedTest + @MethodSource("configurations") + public void behavesAsExpected(Config config) { + final List expectedResult; + if (config.streamSize() == 0) { + expectedResult = List.of(); + } else { + expectedResult = config.stream() + .sequential() + .reduce( + new LinkedList(), + (acc, next) -> { + acc.addLast((acc.isEmpty() ? 0L : acc.getLast()) + next); + return acc; + }, + (l, r) -> { throw new IllegalStateException(); } + ); + } + + final var result = config.stream() + .gather(Gatherers.scan(() -> 0L, (acc, next) -> acc + next)) + .toList(); + + assertEquals(expectedResult, result); + } +} diff --git a/test/jdk/java/util/stream/GatherersWindowFixedTest.java b/test/jdk/java/util/stream/GatherersWindowFixedTest.java new file mode 100644 index 0000000000000..69426dfd768e9 --- /dev/null +++ b/test/jdk/java/util/stream/GatherersWindowFixedTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Gatherers; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; + +/** + * @test + * @summary Tests the API and contract of Gatherers.windowFixed + * @enablePreview + * @run junit GatherersWindowFixedTest + */ + +public class GatherersWindowFixedTest { + + record Config(int streamSize, boolean parallel) { + Stream stream() { + var stream = Stream.iterate(1, i -> i + 1).limit(streamSize); + stream = parallel ? stream.parallel() : stream.sequential(); + return stream; + } + } + + static final Stream sizes(){ + return Stream.of(0,1,10,33,99,9999); + } + + static final Stream sequentialAndParallel(int size) { + return Stream.of(false, true) + .map(parallel -> + new Config(size, parallel)); + } + + static final Stream configurations() { + return sizes().flatMap(i -> sequentialAndParallel(i)); + } + + static final Stream nonempty_configurations() { + return sizes().filter(i -> i > 0).flatMap(i -> sequentialAndParallel(i)); + } + + @ParameterizedTest + @ValueSource(ints = { Integer.MIN_VALUE, -999, -1, 0}) + public void throwsIAEWhenWindowSizeIsSmallerThanOne(int windowSize) { + assertThrows(IllegalArgumentException.class, + () -> Gatherers.windowFixed(windowSize)); + } + + @ParameterizedTest + @MethodSource("nonempty_configurations") + public void behavesAsExpectedWhenWindowSizeIsSizeOfStream(Config config) { + final var streamSize = config.streamSize(); + final var result = config.stream() + .gather(Gatherers.windowFixed(streamSize)) + .toList(); + assertEquals(1, result.size()); + assertEquals(config.stream().toList(), result.get(0)); + } + + @Test + public void toleratesNullElements() { + assertEquals( + List.of(Arrays.asList(null, null)), + Stream.of(null, null) + .gather(Gatherers.windowFixed(2)) + .toList()); + } + + @Test + public void throwsUOEWhenWindowsAreAttemptedToBeModified() { + var window = Stream.of(1) + .gather(Gatherers.windowFixed(1)) + .findFirst() + .get(); + assertThrows(UnsupportedOperationException.class, + () -> window.add(2)); + } + + @ParameterizedTest + @MethodSource("configurations") + public void behavesAsExpected(Config config) { + final var streamSize = config.streamSize(); + // Tests that the layout of the returned data is as expected + for (var windowSize : List.of(1, 2, 3, 10)) { + final var expectLastWindowSize = streamSize % windowSize == 0 ? windowSize : streamSize % windowSize; + final var expectedSize = (streamSize / windowSize) + ((streamSize % windowSize == 0) ? 0 : 1); + + final var expected = config.stream().toList().iterator(); + + final var result = config.stream() + .gather(Gatherers.windowFixed(windowSize)) + .toList(); + + int currentWindow = 0; + for (var window : result) { + ++currentWindow; + assertEquals(currentWindow < expectedSize ? windowSize : expectLastWindowSize, window.size()); + for (var element : window) + assertEquals(expected.next(), element); + } + + assertEquals(expectedSize, currentWindow); + } + } +} diff --git a/test/jdk/java/util/stream/GatherersWindowSlidingTest.java b/test/jdk/java/util/stream/GatherersWindowSlidingTest.java new file mode 100644 index 0000000000000..27ed6ecc4dde7 --- /dev/null +++ b/test/jdk/java/util/stream/GatherersWindowSlidingTest.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Gatherers; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; + +/** + * @test + * @summary Tests the API and contract of Gatherers.windowSliding + * @enablePreview + * @run junit GatherersWindowSlidingTest + */ + +public class GatherersWindowSlidingTest { + + record Config(int streamSize, boolean parallel) { + Stream stream() { + var stream = Stream.iterate(1, i -> i + 1).limit(streamSize); + stream = parallel ? stream.parallel() : stream.sequential(); + return stream; + } + } + + static final Stream sizes(){ + return Stream.of(0,1,10,33,99,9999); + } + + static final Stream sequentialAndParallel(int size) { + return Stream.of(false, true) + .map(parallel -> + new Config(size, parallel)); + } + + static final Stream configurations() { + return sizes().flatMap(i -> sequentialAndParallel(i)); + } + + static final Stream nonempty_configurations() { + return sizes().filter(i -> i > 0).flatMap(i -> sequentialAndParallel(i)); + } + + @ParameterizedTest + @ValueSource(ints = { Integer.MIN_VALUE, -999, -1, 0}) + public void throwsIAEWhenWindowSizeIsSmallerThanOne(int windowSize) { + assertThrows(IllegalArgumentException.class, () -> Gatherers.windowSliding(windowSize)); + } + + @ParameterizedTest + @MethodSource("nonempty_configurations") + public void behavesAsExpectedWhenWindowSizeIsLargerThanStreamSize(Config config) { + final var streamSize = config.streamSize(); + final var result = config.stream() + .gather(Gatherers.windowSliding(streamSize + 1)) + .toList(); + assertEquals(1, result.size()); + assertEquals(config.stream().toList(), result.get(0)); + } + + @Test + public void toleratesNullElements() { + assertEquals( + List.of( + Arrays.asList(null, null), + Arrays.asList(null, null) + ), + Stream.of(null, null, null) + .gather(Gatherers.windowSliding(2)) + .toList()); + } + + @Test + public void throwsUOEWhenWindowsAreAttemptedToBeModified() { + var window = Stream.of(1) + .gather(Gatherers.windowSliding(1)) + .findFirst() + .get(); + assertThrows(UnsupportedOperationException.class, + () -> window.add(2)); + } + + @ParameterizedTest + @MethodSource("configurations") + public void behavesAsExpected(Config config) { + final var streamSize = config.streamSize(); + // Tests that the layout of the returned data is as expected + for (var windowSize : List.of(1, 2, 3, 10)) { + final var expectLastWindowSize = streamSize < windowSize ? streamSize : windowSize; + final var expectedNumberOfWindows = streamSize == 0 ? 0 : Math.max(1, 1 + streamSize - windowSize); + + int expectedElement = 0; + int currentWindow = 0; + + final var result = config.stream() + .gather(Gatherers.windowSliding(windowSize)) + .toList(); + + for (var window : result) { + ++currentWindow; + assertEquals(currentWindow < expectedNumberOfWindows ? windowSize : expectLastWindowSize, window.size()); + for (var element : window) { + assertEquals(++expectedElement, element.intValue()); + } + // rewind for the sliding motion + expectedElement -= (window.size() - 1); + } + + assertEquals(expectedNumberOfWindows, currentWindow); + } + } +} diff --git a/test/jdk/java/util/stream/TEST.properties b/test/jdk/java/util/stream/TEST.properties new file mode 100644 index 0000000000000..74a024f2880ac --- /dev/null +++ b/test/jdk/java/util/stream/TEST.properties @@ -0,0 +1 @@ +maxOutputSize=2000000 diff --git a/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java b/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java index befdf4cac156e..04a1157a2f8d7 100644 --- a/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java +++ b/test/jdk/java/util/zip/ZipFile/CorruptedZipFiles.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4770745 6218846 6218848 6237956 8313765 + * @bug 4770745 6218846 6218848 6237956 8313765 8316141 * @summary test for correct detection and reporting of corrupted zip files * @author Martin Buchholz * @run junit CorruptedZipFiles @@ -262,7 +262,7 @@ public void insufficientFilenameLength() throws IOException { public void excessiveExtraFieldLength() throws IOException { buffer.put(cenpos+CENEXT, (byte) 0xff); buffer.put(cenpos+CENEXT+1, (byte) 0xff); - assertZipException(".*extra data field size too long.*"); + assertZipException(".*bad header size.*"); } /* @@ -273,7 +273,7 @@ public void excessiveExtraFieldLength() throws IOException { @Test public void excessiveExtraFieldLength2() throws IOException { buffer.putShort(cenpos+CENEXT, (short) 0xfdfd); - assertZipException(".*extra data field size too long.*"); + assertZipException(".*bad header size.*"); } /* diff --git a/test/jdk/javax/print/DialogMargins.java b/test/jdk/javax/print/DialogMargins.java index cb5b488369c6f..ca45a1690a61f 100644 --- a/test/jdk/javax/print/DialogMargins.java +++ b/test/jdk/javax/print/DialogMargins.java @@ -24,12 +24,12 @@ /** * @test * @bug 4485755 6361370 6448717 5080051 6939417 8016343 + * @key printer * @summary dialog doesn't have way to specify margins * for 6361370, verify exception for offline printer in Windows * for 6448717, faster display of print dialog * for 6500903, verify status of printer if accepting jobs or not * for 8016343, verify printing to non-default printer - * @author prr * @run main/manual DialogMargins */ diff --git a/test/jdk/javax/print/LookupServices.java b/test/jdk/javax/print/LookupServices.java index 7f6b9f1f6043f..a5685dbc57c17 100644 --- a/test/jdk/javax/print/LookupServices.java +++ b/test/jdk/javax/print/LookupServices.java @@ -24,6 +24,7 @@ /* * @test * @bug 4510477 6520186 + * @key printer * @summary No crash with HP OfficeJet 600 installed. * @run main LookupServices */ diff --git a/test/jdk/javax/print/PrintServiceLookup/GetPrintServices.java b/test/jdk/javax/print/PrintServiceLookup/GetPrintServices.java index 544428566cb9d..092f7f17da550 100644 --- a/test/jdk/javax/print/PrintServiceLookup/GetPrintServices.java +++ b/test/jdk/javax/print/PrintServiceLookup/GetPrintServices.java @@ -29,6 +29,7 @@ /* * @test + * @key printer * @bug 8013810 8025439 * @summary Test that print service returned without filter are of the same class * as with name filter diff --git a/test/jdk/javax/print/PrintSubInputStream/Example.java b/test/jdk/javax/print/PrintSubInputStream/Example.java index 27acae8af6eff..b2aa913dccb47 100644 --- a/test/jdk/javax/print/PrintSubInputStream/Example.java +++ b/test/jdk/javax/print/PrintSubInputStream/Example.java @@ -23,9 +23,9 @@ /** * @test + * key printer * @bug 4700712 4707777 * @summary Should submit only 1 job in Windows and print only 1 page. - * @author jgodinez * @run main/manual Example */ import java.awt.*; diff --git a/test/jdk/javax/print/ServiceUIPropBtnTest.java b/test/jdk/javax/print/ServiceUIPropBtnTest.java index ccb57ba40376a..189b9b3ac25e8 100644 --- a/test/jdk/javax/print/ServiceUIPropBtnTest.java +++ b/test/jdk/javax/print/ServiceUIPropBtnTest.java @@ -23,6 +23,7 @@ /* @test @bug 8246742 + @key printer @summary Verifies ServiceUI.printDialog does not support properties dialog @run main/manual ServiceUIPropBtnTest */ diff --git a/test/jdk/javax/print/TextFlavorTest.java b/test/jdk/javax/print/TextFlavorTest.java index f703e8aacc576..18b5e08f6b497 100644 --- a/test/jdk/javax/print/TextFlavorTest.java +++ b/test/jdk/javax/print/TextFlavorTest.java @@ -24,6 +24,7 @@ /* @test @bug 6334074 8022536 + @key printer @summary test supported text flavors reported properly @run main TextFlavorTest */ diff --git a/test/jdk/javax/print/attribute/Chroma.java b/test/jdk/javax/print/attribute/Chroma.java index 5968f95140950..60ce9f6719ac6 100644 --- a/test/jdk/javax/print/attribute/Chroma.java +++ b/test/jdk/javax/print/attribute/Chroma.java @@ -21,7 +21,7 @@ * questions. */ /* - * @test 1.3 01/05/11 + * @test * @bug 4456750 * @summary Test for supported chromaticity values with null DocFlavor. * No exception should be thrown. diff --git a/test/jdk/javax/print/attribute/CollateAttr.java b/test/jdk/javax/print/attribute/CollateAttr.java index 5ea8a78be3754..0c6cef60bce90 100644 --- a/test/jdk/javax/print/attribute/CollateAttr.java +++ b/test/jdk/javax/print/attribute/CollateAttr.java @@ -24,6 +24,7 @@ /** * @test * @bug 6574117 + * @key printer * @summary Verify no NPE testing service support of SheetCollate * @run main CollateAttr */ diff --git a/test/jdk/javax/print/attribute/PSCopiesFlavorTest.java b/test/jdk/javax/print/attribute/PSCopiesFlavorTest.java index 25b5d955fa555..3f78fa3853744 100644 --- a/test/jdk/javax/print/attribute/PSCopiesFlavorTest.java +++ b/test/jdk/javax/print/attribute/PSCopiesFlavorTest.java @@ -24,6 +24,7 @@ /** * @test * @bug 6527316 6732647 + * @key printer * @summary Copies isn't supported for PS flavors. * @run main PSCopiesFlavorTest */ diff --git a/test/jdk/javax/print/attribute/PrintResAttr.java b/test/jdk/javax/print/attribute/PrintResAttr.java index c5467b3253275..dee94ae1b78d0 100644 --- a/test/jdk/javax/print/attribute/PrintResAttr.java +++ b/test/jdk/javax/print/attribute/PrintResAttr.java @@ -23,6 +23,7 @@ /** * @test + * @key printer * @bug 8048328 * @summary CUPS Printing does not report supported printer resolutions. * @run main PrintResAttr diff --git a/test/jdk/javax/print/attribute/ServiceDialogTest.java b/test/jdk/javax/print/attribute/ServiceDialogTest.java index bce24e749cf68..626325ab1a417 100644 --- a/test/jdk/javax/print/attribute/ServiceDialogTest.java +++ b/test/jdk/javax/print/attribute/ServiceDialogTest.java @@ -25,6 +25,7 @@ /** * @test * @bug 4910388 4871089 4998624 + * @key printer * @summary Confirm that * 1. After choosing Reverse Landscape in the system default print * Print Service (2nd in the list), it diff --git a/test/jdk/javax/print/attribute/ServiceDialogValidateTest.java b/test/jdk/javax/print/attribute/ServiceDialogValidateTest.java index 929f76869cff3..3598d4ae7bd04 100644 --- a/test/jdk/javax/print/attribute/ServiceDialogValidateTest.java +++ b/test/jdk/javax/print/attribute/ServiceDialogValidateTest.java @@ -23,6 +23,7 @@ /* * @test * @bug 5049012 8163922 + * @key printer * @summary Verify if PrintToFile option is disabled for flavors that do not * support Destination * @requires (os.family == "linux") diff --git a/test/jdk/javax/print/attribute/ServiceDlgPageRangeTest.java b/test/jdk/javax/print/attribute/ServiceDlgPageRangeTest.java index bdf3368f5b0bc..f2982a13669bb 100644 --- a/test/jdk/javax/print/attribute/ServiceDlgPageRangeTest.java +++ b/test/jdk/javax/print/attribute/ServiceDlgPageRangeTest.java @@ -23,6 +23,7 @@ /* * @test * @bug 5080098 8164205 + * @key printer * @summary Verify if PageRanges option is disabled for Non service-formatted * flavors. * @run main/manual ServiceDlgPageRangeTest diff --git a/test/jdk/javax/print/attribute/ServiceDlgSheetCollateTest.java b/test/jdk/javax/print/attribute/ServiceDlgSheetCollateTest.java index 4f80acc29aab2..dd569639f2597 100644 --- a/test/jdk/javax/print/attribute/ServiceDlgSheetCollateTest.java +++ b/test/jdk/javax/print/attribute/ServiceDlgSheetCollateTest.java @@ -23,6 +23,7 @@ /* * @test * @bug 5080830 + * @key printer * @summary Verify if SheetCollate option is disabled for flavors that do not * support SheetCollate * @run main/manual ServiceDlgSheetCollateTest diff --git a/test/jdk/javax/print/attribute/Services_getDocFl.java b/test/jdk/javax/print/attribute/Services_getDocFl.java index ca926b3992834..63986e46a9383 100644 --- a/test/jdk/javax/print/attribute/Services_getDocFl.java +++ b/test/jdk/javax/print/attribute/Services_getDocFl.java @@ -28,6 +28,7 @@ /* * @test + * @key printer * @bug 4901243 8040139 8167291 * @summary JPG, GIF, and PNG DocFlavors (URL) should be supported if Postscript is supported. * @run main Services_getDocFl diff --git a/test/jdk/javax/print/attribute/SidesAttributeTest.java b/test/jdk/javax/print/attribute/SidesAttributeTest.java index 60454f304076d..09890c7211bce 100644 --- a/test/jdk/javax/print/attribute/SidesAttributeTest.java +++ b/test/jdk/javax/print/attribute/SidesAttributeTest.java @@ -25,6 +25,7 @@ /* * @test * @bug JDK-8311033 + * @key printer * @summary [macos] PrinterJob does not take into account Sides attribute * @run main/manual SidesAttributeTest */ diff --git a/test/jdk/javax/print/attribute/TestUnsupportedResolution.java b/test/jdk/javax/print/attribute/TestUnsupportedResolution.java index 0ecf842af2aa4..78e7e93c5f535 100644 --- a/test/jdk/javax/print/attribute/TestUnsupportedResolution.java +++ b/test/jdk/javax/print/attribute/TestUnsupportedResolution.java @@ -25,6 +25,7 @@ /** * @test * @bug 8033277 + * @key printer * @summary Confirm that scaling of printout is correct. Manual comparison with printout using a supported resolution is needed. * @run main/manual TestUnsupportedResolution */ diff --git a/test/jdk/javax/print/attribute/autosense/PrintAutoSenseData.java b/test/jdk/javax/print/attribute/autosense/PrintAutoSenseData.java index f5ddc0d15e275..008e0917342a3 100644 --- a/test/jdk/javax/print/attribute/autosense/PrintAutoSenseData.java +++ b/test/jdk/javax/print/attribute/autosense/PrintAutoSenseData.java @@ -24,6 +24,7 @@ /* * @test * @bug 4468109 8021583 + * @key printer * @summary Test for printing AUTOSENSE DocFlavor. No exception should be thrown. * @run main PrintAutoSenseData */ diff --git a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh index 21becec9f7134..e5d1a063840ba 100644 --- a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh +++ b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -56,5 +56,5 @@ fi echo "Running test without security manager ..." $JAVA ${TESTVMOPTS} -classpath \ - "${TESTCLASSES}${PS}${TESTCLASSES}/badfactoty.jar" \ + "${TESTCLASSES}${PS}${TESTCLASSES}/badfactory.jar" \ BadFactoryTest diff --git a/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java b/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java index 5e90ecf839cc0..2b6bc0519bcc8 100644 --- a/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java +++ b/test/jdk/javax/security/auth/login/modules/JaasModularClientTest.java @@ -43,10 +43,8 @@ * @test * @bug 8078813 8183310 * @summary Test custom JAAS login module with all possible modular option. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.module + * @enablePreview + * @modules java.base/jdk.internal.module * @library /test/lib * @build jdk.test.lib.util.JarUtils jdk.test.lib.util.ModuleInfoWriter * @build TestLoginModule JaasClient diff --git a/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java b/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java index 9f808b2caad07..2f2c43d03c585 100644 --- a/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java +++ b/test/jdk/javax/security/auth/login/modules/JaasModularDefaultHandlerTest.java @@ -42,10 +42,8 @@ * @test * @bug 8151654 8183310 * @summary Test default callback handler with all possible modular option. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.module + * @enablePreview + * @modules java.base/jdk.internal.module * @library /test/lib * @build jdk.test.lib.util.JarUtils jdk.test.lib.util.ModuleInfoWriter * @build TestCallbackHandler TestLoginModule JaasClientWithDefaultHandler diff --git a/test/jdk/javax/swing/JButton/HtmlButtonImageTest/HtmlButtonImageTest.java b/test/jdk/javax/swing/JButton/HtmlButtonImageTest/HtmlButtonImageTest.java deleted file mode 100644 index 105f2376ae994..0000000000000 --- a/test/jdk/javax/swing/JButton/HtmlButtonImageTest/HtmlButtonImageTest.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. -*/ - -/* - * @test - * @bug 8015854 - * @summary Tests HTML image as JButton text for unwanted padding - * @run main HtmlButtonImageTest - */ - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; - -import javax.imageio.ImageIO; -import javax.swing.JButton; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; - -import static java.awt.image.BufferedImage.TYPE_INT_ARGB; - -public final class HtmlButtonImageTest { - private static JButton button; - private static Path testDir; - private static BufferedImage image; - - private static final int BUTTON_HEIGHT = 37; - private static final int BUTTON_WIDTH = 37; - private static final int SQUARE_HEIGHT = 19; - private static final int SQUARE_WIDTH = 19; - private static final int centerX = BUTTON_WIDTH / 2; - private static final int centerY = BUTTON_HEIGHT / 2; - private static final int minX = centerX - (SQUARE_WIDTH / 2); - private static final int minY = centerY - (SQUARE_HEIGHT / 2); - private static final int maxX = centerX + (SQUARE_WIDTH / 2); - private static final int maxY = centerY + (SQUARE_HEIGHT / 2); - - private static boolean supportedLaf; - private static int failCount = 0; - private static String currentLaf = new String(); - private static StringBuffer failedLafs = new StringBuffer(); - - - public static void main(String[] args) throws Exception { - testDir = Path.of(System.getProperty("test.classes", ".")); - generateRedSquare(); - - for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { - SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf)); - if(supportedLaf) { - currentLaf = laf.getName(); - SwingUtilities.invokeAndWait(HtmlButtonImageTest::createButton); - SwingUtilities.invokeAndWait(HtmlButtonImageTest::paintButton); - - testImageCentering(image.getRGB(centerX, centerY), - image.getRGB(minX, minY), - image.getRGB(minX, maxY), - image.getRGB(maxX, minY), - image.getRGB(maxX, maxY)); - } - } - - if(!failedLafs.isEmpty()) { - if(failCount > 1) { - failedLafs.setLength(failedLafs.length() - 2); - } - throw new RuntimeException("HTML image not centered in button " + - "for these L&F's: " + failedLafs); - } - } - - private static void generateRedSquare() throws IOException { - BufferedImage bImg = new BufferedImage(SQUARE_WIDTH, SQUARE_HEIGHT, - TYPE_INT_ARGB); - Graphics2D cg = bImg.createGraphics(); - cg.setColor(Color.RED); - cg.fillRect(0, 0, SQUARE_WIDTH, SQUARE_HEIGHT); - ImageIO.write(bImg, "png", new File(testDir + "/red_square.png")); - } - - private static void createButton() { - button = new JButton(); - button.setSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT)); - button.setText(""); - } - - private static void paintButton() { - image = new BufferedImage(BUTTON_HEIGHT, BUTTON_WIDTH, TYPE_INT_ARGB); - Graphics2D graphics2D = image.createGraphics(); - button.paint(graphics2D); - graphics2D.dispose(); - } - - private static boolean checkRedColor(int rgb) { - return (rgb == Color.RED.getRGB()); - } - - private static void testImageCentering(int... colors) throws IOException { - for (int c : colors) { - if (!checkRedColor(c)) { - failCount++; - ImageIO.write(image, "png", new File(testDir + "/fail_image_" + - currentLaf.replaceAll("[^\\w\\s]","") + ".png")); - failedLafs.append(currentLaf + ", "); - break; - } - } - } - - private static void setLookAndFeel(UIManager.LookAndFeelInfo laf) { - try { - UIManager.setLookAndFeel(laf.getClassName()); - supportedLaf = true; - } catch (UnsupportedLookAndFeelException | ClassNotFoundException | - InstantiationException | IllegalAccessException e) { - supportedLaf = false; - } - } -} diff --git a/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java b/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java index 15ac95bc198d1..4736e73e61df9 100644 --- a/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java +++ b/test/jdk/javax/swing/JFileChooser/FileChooserSymLinkTest.java @@ -22,14 +22,12 @@ */ import java.awt.BorderLayout; -import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.util.Arrays; -import java.util.List; import javax.swing.JCheckBox; import javax.swing.JFileChooser; @@ -118,7 +116,7 @@ public static void main(String[] args) throws Exception { .awaitAndCheck(); } - private static List createTestUI() { + private static JFrame createTestUI() { frame = new JFrame("JFileChooser Symbolic Link test"); panel = new JPanel(new BorderLayout()); multiSelection = new JCheckBox("Enable Multi-Selection"); @@ -159,6 +157,6 @@ public void propertyChange(PropertyChangeEvent evt) { frame.add(panel, BorderLayout.NORTH); frame.add(jfc, BorderLayout.CENTER); frame.pack(); - return List.of(frame); + return frame; } } diff --git a/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java b/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java index 560c5d82331d9..784cd00c24473 100644 --- a/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java +++ b/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,6 +83,7 @@ private void createUI() { public void runTest() throws Exception { Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); robot.setAutoDelay(100); for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { try { @@ -100,6 +101,8 @@ public void runTest() throws Exception { createUI(); }); robot.waitForIdle(); + robot.delay(1000); + robot.keyPress(KeyEvent.VK_ENTER); robot.keyRelease(KeyEvent.VK_ENTER); robot.waitForIdle(); diff --git a/test/jdk/javax/swing/JTabbedPane/TestJTabbedPaneArrowDirection.java b/test/jdk/javax/swing/JTabbedPane/TestJTabbedPaneArrowDirection.java new file mode 100644 index 0000000000000..50df3933f36e7 --- /dev/null +++ b/test/jdk/javax/swing/JTabbedPane/TestJTabbedPaneArrowDirection.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.GridLayout; +import javax.swing.AbstractAction; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/* + * @test + * @bug 8225220 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @requires (os.family == "linux") + * @summary JTabbedPane arrow should point to left or right direction + * when tab layout policy is set to SCROLL_TAB_LAYOUT and tab + * placement is set to either TOP or BOTTOM + * @run main/manual TestJTabbedPaneArrowDirection + */ + +public class TestJTabbedPaneArrowDirection { + private static JFrame frame; + private static JTabbedPane tabPane; + private static final String INSTRUCTIONS = + "1. Observe the arrows are ponting to left and right direction\n" + + " for tab placement set to TOP. Default tab placement is TOP.\n\n" + + "2. Press BOTTOM to change the tab placement to bottom.\n\n" + + "3. Observe arrows are pointing to the left and right direction.\n\n" + + "4. If the behaviour is correct, press Pass else Fail."; + + public static void main(String[] args) throws Exception { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); + PassFailJFrame passFailJFrame = new PassFailJFrame.Builder() + .title("JTabbedPane Arrow Direction Test Instructions") + .instructions(INSTRUCTIONS) + .testTimeOut(5) + .rows(12) + .columns(40) + .screenCapture() + .build(); + SwingUtilities.invokeAndWait( + TestJTabbedPaneArrowDirection::createAndShowUI); + passFailJFrame.awaitAndCheck(); + } + + private static void createAndShowUI() { + int NUM_TABS = 15; + frame = new JFrame("Test JTabbedPane Arrow Direction"); + JTabbedPane tabPane = new JTabbedPane(); + tabPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); + tabPane.setTabPlacement(JTabbedPane.TOP); + PassFailJFrame.addTestWindow(frame); + PassFailJFrame.positionTestWindow( + frame, PassFailJFrame.Position.HORIZONTAL); + for( int i = 0; i < NUM_TABS; ++i) { + tabPane.addTab("Tab " + i , new JLabel("Content Area")); + } + JPanel panel = new JPanel(new BorderLayout()); + panel.add(tabPane, BorderLayout.CENTER); + JButton topButton = new JButton(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + tabPane.setTabPlacement(JTabbedPane.TOP); + } + }); + topButton.setText("TOP"); + JButton bottomButton = new JButton(new AbstractAction() { + public void actionPerformed(ActionEvent e) { + tabPane.setTabPlacement(JTabbedPane.BOTTOM); + } + }); + bottomButton.setText("BOTTOM"); + JPanel buttonPanel = new JPanel(new GridLayout(1, 2)); + buttonPanel.add(topButton); + buttonPanel.add(bottomButton); + panel.add(buttonPanel, BorderLayout.SOUTH); + frame.add(panel); + frame.setSize(500, 500); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setVisible(true); + } +} diff --git a/test/jdk/javax/swing/JTable/JTableRightOrientationTest.java b/test/jdk/javax/swing/JTable/JTableRightOrientationTest.java new file mode 100644 index 0000000000000..0f63c739bce68 --- /dev/null +++ b/test/jdk/javax/swing/JTable/JTableRightOrientationTest.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.ComponentOrientation; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.table.AbstractTableModel; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +import javax.imageio.ImageIO; +/* + * @test + * @key headful + * @bug 5108458 + * @summary Test to check Right alignment of JTable data + * @run main JTableRightOrientationTest + */ + +public class JTableRightOrientationTest { + static JFrame frame; + static CustomTable customTableObj; + static volatile Rectangle tableBounds; + + public static void main(String[] args) throws Exception { + Robot robot = new Robot(); + for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { + System.out.println("Testing LAF : " + laf.getClassName()); + SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf)); + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("JTable RTL column layout"); + JPanel panel = new JPanel(new GridBagLayout()); + frame.setContentPane(panel); + customTableObj = new CustomTable(); + panel.add(new JScrollPane(customTableObj.table), + new GridBagConstraints(0, 0, -1, -1, 1.0, 1.0, + GridBagConstraints.PAGE_START, GridBagConstraints.BOTH, + new Insets(2, 2, 2, 2), 0, 0)); + frame.pack(); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); + frame.setVisible(true); + }); + + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + int allColumnWidths = 0; + for (int i = 0; i < customTableObj.table.getColumnCount(); i++) { + allColumnWidths += customTableObj.table.getTableHeader().getColumnModel() + .getColumn(i) + .getWidth(); + } + Point tableLocation = customTableObj.table.getLocationOnScreen(); + Dimension tableSize = customTableObj.table.getSize(); + tableSize.width -= allColumnWidths; + tableBounds = new Rectangle(tableLocation, tableSize); + }); + + BufferedImage bufferedImage = robot.createScreenCapture(tableBounds); + + int expectedRGB = bufferedImage.getRGB(0, 0); + for (int x = 0; x < bufferedImage.getWidth(); x++) { + for (int y = 0; y < bufferedImage.getHeight(); y++) { + if (expectedRGB != bufferedImage.getRGB(x, y)) { + saveImage(bufferedImage); + throw new RuntimeException("Test Failed at <" + x + ", " + y + ">"); + } + } + } + + System.out.println("Test Passed!"); + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + robot.waitForIdle(); + robot.delay(200); + } + } + + private static void saveImage(BufferedImage image) { + try { + ImageIO.write(image, "png", new File("failureImage.png")); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private static void setLookAndFeel(UIManager.LookAndFeelInfo laf) { + try { + UIManager.setLookAndFeel(laf.getClassName()); + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Unsupported LAF: " + laf.getClassName()); + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} + +class CustomTable { + private static final int COL_FIRSTNAME = 0; + private static final int COL_LASTNAME = 1; + private static final int COL_SALARY = 2; + + static final Class[] classes = { + String.class, + String.class, + Float.class, + }; + + String[] cols = { + "First name", + "Last name", + "Salary", + }; + List data = new ArrayList<>(); + JTable table; + + public CustomTable() { + data.add(new CustomTable.Data("First1", "Last1", 10000f)); + data.add(new CustomTable.Data("First2", "Last2", 10000f)); + data.add(new CustomTable.Data("First3", "Last3", 10000f)); + table = new JTable(new CustomTable.Model()); + table.getColumnModel().getColumn(COL_FIRSTNAME).setMaxWidth(90); + table.getColumnModel().getColumn(COL_LASTNAME).setMaxWidth(90); + table.getColumnModel().getColumn(COL_SALARY).setMaxWidth(90); + } + + record Data(String firstName, String lastName, float salary) {} + + class Model extends AbstractTableModel { + + public int getColumnCount() { + return cols.length; + } + + public int getRowCount() { + return data.size(); + } + + public Object getValueAt(int rowIndex, int columnIndex) { + CustomTable.Data item = data.get(rowIndex); + switch (columnIndex) { + case COL_FIRSTNAME: + return item.firstName; + case COL_LASTNAME: + return item.lastName; + case COL_SALARY: + return item.salary; + } + return null; + } + + public String getColumnName(int column) { + return cols[column]; + } + + public Class getColumnClass(int columnIndex) { + return classes[columnIndex]; + } + } +} diff --git a/test/jdk/javax/swing/JTree/8003400/Test8003400.java b/test/jdk/javax/swing/JTree/8003400/Test8003400.java index 95f5e826aa9b3..dcc9b0fce6ee9 100644 --- a/test/jdk/javax/swing/JTree/8003400/Test8003400.java +++ b/test/jdk/javax/swing/JTree/8003400/Test8003400.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -109,6 +109,10 @@ public void run() { Robot robot = new Robot(); robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + robot.waitForIdle(); + robot.delay(500); + SwingUtilities.invokeAndWait(() -> { point = tree.getLocationOnScreen(); rect = tree.getBounds(); diff --git a/test/jdk/jdk/classfile/AccessFlagsTest.java b/test/jdk/jdk/classfile/AccessFlagsTest.java index 6a4b8dbe6f67a..97c0d97f8f9f1 100644 --- a/test/jdk/jdk/classfile/AccessFlagsTest.java +++ b/test/jdk/jdk/classfile/AccessFlagsTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile AccessFlags. + * @summary Testing ClassFile AccessFlags. * @run junit AccessFlagsTest */ import java.util.EnumSet; @@ -33,7 +33,7 @@ import java.util.function.Function; import java.util.function.IntFunction; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.AccessFlags; +import java.lang.classfile.AccessFlags; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.provider.EnumSource; diff --git a/test/jdk/jdk/classfile/AdaptCodeTest.java b/test/jdk/jdk/classfile/AdaptCodeTest.java index e7710318396cb..2fd9fcb2c9589 100644 --- a/test/jdk/jdk/classfile/AdaptCodeTest.java +++ b/test/jdk/jdk/classfile/AdaptCodeTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile Code Adaptation. + * @summary Testing ClassFile Code Adaptation. * @run junit AdaptCodeTest */ @@ -35,13 +35,13 @@ import java.nio.file.Path; import java.nio.file.Paths; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.ClassFile; import helpers.ByteArrayClassLoader; import helpers.TestUtil; import helpers.Transforms; -import jdk.internal.classfile.instruction.ConstantInstruction; +import java.lang.classfile.instruction.ConstantInstruction; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.params.ParameterizedTest; @@ -56,7 +56,7 @@ class AdaptCodeTest { @Test void testNullAdaptIterator() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(testClassPath); for (ClassTransform t : Transforms.noops) { byte[] newBytes = cc.transform(cm, t); @@ -76,7 +76,7 @@ void testNullAdaptIterator() throws Exception { }) void testNullAdaptIterator2(String path) throws Exception { FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(fs.getPath(path)); for (ClassTransform t : Transforms.noops) { byte[] newBytes = cc.transform(cm, t); @@ -85,7 +85,7 @@ void testNullAdaptIterator2(String path) throws Exception { @Test void testSevenOfThirteenIterator() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(testClassPath); var transform = ClassTransform.transformingMethodBodies((codeB, codeE) -> { @@ -112,7 +112,7 @@ void testSevenOfThirteenIterator() throws Exception { @Test void testCopy() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(testClassPath); byte[] newBytes = cc.build(cm.thisClass().asSymbol(), cb -> cm.forEachElement(cb)); // TestUtil.writeClass(newBytes, "TestClass.class"); diff --git a/test/jdk/jdk/classfile/AdvancedTransformationsTest.java b/test/jdk/jdk/classfile/AdvancedTransformationsTest.java index 595d92262455d..9b4609fe8bc48 100644 --- a/test/jdk/jdk/classfile/AdvancedTransformationsTest.java +++ b/test/jdk/jdk/classfile/AdvancedTransformationsTest.java @@ -23,21 +23,21 @@ /* * @test - * @summary Testing Classfile advanced transformations. + * @summary Testing ClassFile advanced transformations. * @run junit AdvancedTransformationsTest */ import helpers.ByteArrayClassLoader; import java.util.Map; import java.util.Set; -import jdk.internal.classfile.ClassHierarchyResolver; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeElement; -import jdk.internal.classfile.CodeModel; -import jdk.internal.classfile.MethodModel; -import jdk.internal.classfile.TypeKind; +import java.lang.classfile.ClassHierarchyResolver; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeElement; +import java.lang.classfile.CodeModel; +import java.lang.classfile.MethodModel; +import java.lang.classfile.TypeKind; import jdk.internal.classfile.impl.StackMapGenerator; -import jdk.internal.classfile.components.ClassRemapper; -import jdk.internal.classfile.components.CodeLocalsShifter; +import java.lang.classfile.components.ClassRemapper; +import java.lang.classfile.components.CodeLocalsShifter; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import static helpers.TestUtil.assertEmpty; @@ -45,22 +45,22 @@ import java.lang.constant.ConstantDescs; import java.util.function.Predicate; import java.util.stream.Collectors; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.CodeBuilder; -import jdk.internal.classfile.CodeTransform; -import jdk.internal.classfile.FieldModel; -import jdk.internal.classfile.Signature; -import jdk.internal.classfile.attribute.ModuleAttribute; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.CodeTransform; +import java.lang.classfile.FieldModel; +import java.lang.classfile.Signature; +import java.lang.classfile.attribute.ModuleAttribute; import jdk.internal.classfile.impl.RawBytecodeHelper; -import jdk.internal.classfile.instruction.InvokeInstruction; -import jdk.internal.classfile.instruction.ReturnInstruction; -import jdk.internal.classfile.instruction.StoreInstruction; +import java.lang.classfile.instruction.InvokeInstruction; +import java.lang.classfile.instruction.ReturnInstruction; +import java.lang.classfile.instruction.StoreInstruction; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.components.CodeRelabeler; +import java.lang.classfile.components.CodeRelabeler; import java.lang.constant.ModuleDesc; -import jdk.internal.classfile.components.ClassPrinter; +import java.lang.classfile.components.ClassPrinter; import static java.lang.annotation.ElementType.*; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -73,9 +73,9 @@ class AdvancedTransformationsTest { @Test void testShiftLocals() throws Exception { try (var in = StackMapGenerator.class.getResourceAsStream("StackMapGenerator.class")) { - var cc = Classfile.of(); + var cc = ClassFile.of(); var clm = cc.parse(in.readAllBytes()); - var remapped = cc.parse(cc.transform(clm, (clb, cle) -> { + cc.verify(cc.transform(clm, (clb, cle) -> { if (cle instanceof MethodModel mm) { clb.transformMethod(mm, (mb, me) -> { if (me instanceof CodeModel com) { @@ -99,7 +99,6 @@ public void accept(CodeBuilder builder, CodeElement element) { else clb.with(cle); })); - remapped.verify(null); } } @@ -112,15 +111,15 @@ void testRemapClass() throws Exception { ClassDesc.ofDescriptor(StackMapGenerator.class.descriptorString()), ClassDesc.of("remapped.StackMapGenerator") ); try (var in = StackMapGenerator.class.getResourceAsStream("StackMapGenerator.class")) { - var cc = Classfile.of(); + var cc = ClassFile.of(); var clm = cc.parse(in.readAllBytes()); var remapped = cc.parse(ClassRemapper.of(map).remapClass(cc, clm)); - assertEmpty(remapped.verify( + assertEmpty(ClassFile.of(ClassFile.ClassHierarchyResolverOption.of( ClassHierarchyResolver.of(Set.of(ClassDesc.of("remapped.List")), Map.of( ClassDesc.of("remapped.RemappedBytecode"), ConstantDescs.CD_Object, ClassDesc.ofDescriptor(RawBytecodeHelper.class.descriptorString()), ClassDesc.of("remapped.RemappedBytecode"))) .orElse(ClassHierarchyResolver.defaultResolver()) - , null)); //System.out::print)); + )).verify(remapped)); remapped.fields().forEach(f -> f.findAttribute(Attributes.SIGNATURE).ifPresent(sa -> verifySignature(f.fieldTypeSymbol(), sa.asTypeSignature()))); remapped.methods().forEach(m -> m.findAttribute(Attributes.SIGNATURE).ifPresent(sa -> { @@ -167,7 +166,7 @@ public Rec(Foo foo) { void testRemapModule() throws Exception { var foo = ClassDesc.ofDescriptor(Foo.class.descriptorString()); var bar = ClassDesc.ofDescriptor(Bar.class.descriptorString()); - var cc = Classfile.of(); + var cc = ClassFile.of(); var ma = cc.parse( ClassRemapper.of(Map.of(foo, bar)).remapClass( cc, @@ -188,7 +187,7 @@ void testRemapDetails() throws Exception { var fooAnno = ClassDesc.ofDescriptor(FooAnno.class.descriptorString()); var barAnno = ClassDesc.ofDescriptor(BarAnno.class.descriptorString()); var rec = ClassDesc.ofDescriptor(Rec.class.descriptorString()); - var cc = Classfile.of(); + var cc = ClassFile.of(); var remapped = cc.parse( ClassRemapper.of(Map.of(foo, bar, fooAnno, barAnno)).remapClass( cc, @@ -235,11 +234,11 @@ private static void verifySignature(ClassDesc desc, Signature sig) { @Test void testInstrumentClass() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); var instrumentor = cc.parse(AdvancedTransformationsTest.class.getResourceAsStream("AdvancedTransformationsTest$InstrumentorClass.class").readAllBytes()); var target = cc.parse(AdvancedTransformationsTest.class.getResourceAsStream("AdvancedTransformationsTest$TargetClass.class").readAllBytes()); var instrumentedBytes = instrument(target, instrumentor, mm -> mm.methodName().stringValue().equals("instrumentedMethod")); - assertEmpty(cc.parse(instrumentedBytes).verify(null)); //System.out::print)); + assertEmpty(cc.verify(instrumentedBytes)); var targetClass = new ByteArrayClassLoader(AdvancedTransformationsTest.class.getClassLoader(), "AdvancedTransformationsTest$TargetClass", instrumentedBytes).loadClass("AdvancedTransformationsTest$TargetClass"); assertEquals(targetClass.getDeclaredMethod("instrumentedMethod", Boolean.class).invoke(targetClass.getDeclaredConstructor().newInstance(), false), 34); } @@ -300,7 +299,7 @@ private static byte[] instrument(ClassModel target, ClassModel instrumentor, Pre var targetFieldNames = target.fields().stream().map(f -> f.fieldName().stringValue()).collect(Collectors.toSet()); var targetMethods = target.methods().stream().map(m -> m.methodName().stringValue() + m.methodType().stringValue()).collect(Collectors.toSet()); var instrumentorClassRemapper = ClassRemapper.of(Map.of(instrumentor.thisClass().asSymbol(), target.thisClass().asSymbol())); - return Classfile.of().transform(target, + return ClassFile.of().transform(target, ClassTransform.transformingMethods( instrumentedMethodsFilter, (mb, me) -> { diff --git a/test/jdk/jdk/classfile/AnnotationModelTest.java b/test/jdk/jdk/classfile/AnnotationModelTest.java index 260ac0e0b8192..ed647784219fc 100644 --- a/test/jdk/jdk/classfile/AnnotationModelTest.java +++ b/test/jdk/jdk/classfile/AnnotationModelTest.java @@ -23,11 +23,11 @@ /* * @test - * @summary Testing Classfile annotation model. + * @summary Testing ClassFile annotation model. * @run junit AnnotationModelTest */ -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.Attributes; +import java.lang.classfile.ClassFile; +import java.lang.classfile.Attributes; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -53,7 +53,7 @@ class AnnotationModelTest { @Test void readAnnos() { - var model = Classfile.of().parse(fileBytes); + var model = ClassFile.of().parse(fileBytes); var annotations = model.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).get().annotations(); assertEquals(annotations.size(), 3); diff --git a/test/jdk/jdk/classfile/AnnotationTest.java b/test/jdk/jdk/classfile/AnnotationTest.java index f7b8637e570fa..0226affe7c260 100644 --- a/test/jdk/jdk/classfile/AnnotationTest.java +++ b/test/jdk/jdk/classfile/AnnotationTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile annotations. + * @summary Testing ClassFile annotations. * @run junit AnnotationTest */ import java.lang.constant.ClassDesc; @@ -36,9 +36,9 @@ import java.util.Map; import java.util.Set; -import jdk.internal.classfile.attribute.RuntimeVisibleAnnotationsAttribute; -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.ConstantPoolBuilder; +import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.ConstantPoolBuilder; import org.junit.jupiter.api.Test; import static java.util.stream.Collectors.toList; @@ -125,7 +125,7 @@ private static RuntimeVisibleAnnotationsAttribute buildAnnotationsWithCPB(Consta @Test void testAnnos() { - var cc = Classfile.of(); + var cc = ClassFile.of(); byte[] bytes = cc.build(ClassDesc.of("Foo"), cb -> { ((DirectClassBuilder) cb).writeAttribute(buildAnnotationsWithCPB(cb.constantPool())); cb.withMethod("foo", MethodTypeDesc.of(CD_void), 0, mb -> mb.with(buildAnnotationsWithCPB(mb.constantPool()))); @@ -171,7 +171,7 @@ private static RuntimeVisibleAnnotationsAttribute buildAnnotations() { @Test void testAnnosNoCPB() { - var cc = Classfile.of(); + var cc = ClassFile.of(); byte[] bytes = cc.build(ClassDesc.of("Foo"), cb -> { ((DirectClassBuilder) cb).writeAttribute(buildAnnotations()); cb.withMethod("foo", MethodTypeDesc.of(CD_void), 0, mb -> mb.with(buildAnnotations())); diff --git a/test/jdk/jdk/classfile/ArrayTest.java b/test/jdk/jdk/classfile/ArrayTest.java index a547f65a4ed96..56b6d39a593c8 100644 --- a/test/jdk/jdk/classfile/ArrayTest.java +++ b/test/jdk/jdk/classfile/ArrayTest.java @@ -23,18 +23,18 @@ /* * @test - * @summary Testing Classfile arrays. + * @summary Testing ClassFile arrays. * @run junit ArrayTest */ -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.CodeElement; -import jdk.internal.classfile.MethodModel; -import jdk.internal.classfile.Opcode; -import jdk.internal.classfile.TypeKind; -import jdk.internal.classfile.instruction.NewMultiArrayInstruction; -import jdk.internal.classfile.instruction.NewPrimitiveArrayInstruction; -import jdk.internal.classfile.instruction.NewReferenceArrayInstruction; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.CodeElement; +import java.lang.classfile.MethodModel; +import java.lang.classfile.Opcode; +import java.lang.classfile.TypeKind; +import java.lang.classfile.instruction.NewMultiArrayInstruction; +import java.lang.classfile.instruction.NewPrimitiveArrayInstruction; +import java.lang.classfile.instruction.NewReferenceArrayInstruction; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -51,7 +51,7 @@ class ArrayTest { @Test void testArrayNew() throws Exception { - ClassModel cm = Classfile.of().parse(testClassPath); + ClassModel cm = ClassFile.of().parse(testClassPath); for (MethodModel mm : cm.methods()) { mm.code().ifPresent(code -> { diff --git a/test/jdk/jdk/classfile/BSMTest.java b/test/jdk/jdk/classfile/BSMTest.java index 89bd1e281d5c9..79ecfb2f53e68 100644 --- a/test/jdk/jdk/classfile/BSMTest.java +++ b/test/jdk/jdk/classfile/BSMTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile bootstrap methods. + * @summary Testing ClassFile bootstrap methods. * @run junit BSMTest */ import java.lang.constant.ClassDesc; @@ -35,14 +35,14 @@ import java.util.ArrayList; import java.util.List; -import jdk.internal.classfile.*; +import java.lang.classfile.*; import helpers.ByteArrayClassLoader; -import jdk.internal.classfile.instruction.ConstantInstruction; -import jdk.internal.classfile.constantpool.ConstantDynamicEntry; -import jdk.internal.classfile.constantpool.ConstantPoolBuilder; -import jdk.internal.classfile.constantpool.LoadableConstantEntry; -import jdk.internal.classfile.constantpool.MemberRefEntry; -import jdk.internal.classfile.constantpool.MethodHandleEntry; +import java.lang.classfile.instruction.ConstantInstruction; +import java.lang.classfile.constantpool.ConstantDynamicEntry; +import java.lang.classfile.constantpool.ConstantPoolBuilder; +import java.lang.classfile.constantpool.LoadableConstantEntry; +import java.lang.classfile.constantpool.MemberRefEntry; +import java.lang.classfile.constantpool.MethodHandleEntry; import org.junit.jupiter.api.Test; import static java.lang.constant.ConstantDescs.CD_String; @@ -58,7 +58,7 @@ public class BSMTest { @Test void testSevenOfThirteenIterator() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(testClassPath); byte[] newBytes = cc.transform(cm, (cb, ce) -> { if (ce instanceof MethodModel mm) { diff --git a/test/jdk/jdk/classfile/BasicBlockTest.java b/test/jdk/jdk/classfile/BasicBlockTest.java index 696d9b1e8526d..9c4b931857e15 100644 --- a/test/jdk/jdk/classfile/BasicBlockTest.java +++ b/test/jdk/jdk/classfile/BasicBlockTest.java @@ -23,12 +23,12 @@ /* * @test - * @summary Testing Classfile complex basic blocks affecting SM generator. + * @summary Testing ClassFile complex basic blocks affecting SM generator. * @run junit BasicBlockTest */ import java.io.InputStream; import java.io.IOException; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import org.junit.jupiter.api.Test; class BasicBlockTest { @@ -55,7 +55,7 @@ void exponentialComplexityInJointNeedLocalPartial(boolean a) { @Test void testPatternsCausingBasicBlockTroubles() throws IOException { try (InputStream in = BasicBlockTest.class.getResourceAsStream("BasicBlockTest.class")) { - var cc = Classfile.of(); + var cc = ClassFile.of(); var classModel = cc.parse(in.readAllBytes()); cc.build(classModel.thisClass().asSymbol(), cb -> classModel.forEachElement(cb)); } diff --git a/test/jdk/jdk/classfile/BoundAttributeTest.java b/test/jdk/jdk/classfile/BoundAttributeTest.java index c3e3fbae2391f..8a25146bab951 100644 --- a/test/jdk/jdk/classfile/BoundAttributeTest.java +++ b/test/jdk/jdk/classfile/BoundAttributeTest.java @@ -27,12 +27,12 @@ * @summary Testing BoundAttributes * @run junit BoundAttributeTest */ -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeBuilder; -import jdk.internal.classfile.attribute.MethodParameterInfo; -import jdk.internal.classfile.attribute.MethodParametersAttribute; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.attribute.MethodParameterInfo; +import java.lang.classfile.attribute.MethodParametersAttribute; import org.junit.jupiter.api.Test; import org.opentest4j.AssertionFailedError; @@ -49,7 +49,7 @@ class BoundAttributeTest { @Test void testReadMethodParametersAttributeWithoutParameterName() { - var cc = Classfile.of(); + var cc = ClassFile.of(); // build a simple method: void method(int) MethodTypeDesc methodTypeDesc = MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_int); byte[] raw = cc.build(ClassDesc.of("TestClass"), builder -> { diff --git a/test/jdk/jdk/classfile/BuilderBlockTest.java b/test/jdk/jdk/classfile/BuilderBlockTest.java index 8d5f1b7e22162..c75869f740fa1 100644 --- a/test/jdk/jdk/classfile/BuilderBlockTest.java +++ b/test/jdk/jdk/classfile/BuilderBlockTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile builder blocks. + * @summary Testing ClassFile builder blocks. * @run junit BuilderBlockTest */ import java.lang.constant.ClassDesc; @@ -36,12 +36,12 @@ import java.nio.file.Paths; import helpers.ByteArrayClassLoader; -import jdk.internal.classfile.AccessFlags; +import java.lang.classfile.AccessFlags; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.Label; -import jdk.internal.classfile.Opcode; -import jdk.internal.classfile.TypeKind; +import java.lang.classfile.ClassFile; +import java.lang.classfile.Label; +import java.lang.classfile.Opcode; +import java.lang.classfile.TypeKind; import jdk.internal.classfile.impl.LabelImpl; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; @@ -59,7 +59,7 @@ void testStartEnd() throws Exception { // Ensure that start=0 at top level, end is undefined until code is done, then end=1 Label startEnd[] = new Label[2]; - byte[] bytes = Classfile.of().build(ClassDesc.of("Foo"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("Foo"), cb -> { cb.withMethod("foo", MethodTypeDesc.of(CD_void), 0, mb -> mb.withCode(xb -> { startEnd[0] = xb.startLabel(); @@ -78,7 +78,7 @@ void testStartEnd() throws Exception { void testStartEndBlock() throws Exception { Label startEnd[] = new Label[4]; - byte[] bytes = Classfile.of().build(ClassDesc.of("Foo"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("Foo"), cb -> { cb.withMethod("foo", MethodTypeDesc.of(CD_void), 0, mb -> mb.withCode(xb -> { startEnd[0] = xb.startLabel(); @@ -101,7 +101,7 @@ void testStartEndBlock() throws Exception { @Test void testIfThenReturn() throws Exception { - byte[] bytes = Classfile.of().build(ClassDesc.of("Foo"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("Foo"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withMethod("foo", MethodTypeDesc.of(CD_int, CD_int), AccessFlags.ofMethod(AccessFlag.PUBLIC, AccessFlag.STATIC).flagsMask(), @@ -120,7 +120,7 @@ void testIfThenReturn() throws Exception { @Test void testIfThenElseReturn() throws Exception { - byte[] bytes = Classfile.of().build(ClassDesc.of("Foo"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("Foo"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withMethod("foo", MethodTypeDesc.of(CD_int, CD_int), AccessFlags.ofMethod(AccessFlag.PUBLIC, AccessFlag.STATIC).flagsMask(), @@ -138,7 +138,7 @@ void testIfThenElseReturn() throws Exception { @Test void testIfThenBadOpcode() { - Classfile.of().build(ClassDesc.of("Foo"), cb -> { + ClassFile.of().build(ClassDesc.of("Foo"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withMethod("foo", MethodTypeDesc.of(CD_int, CD_int, CD_int), AccessFlags.ofMethod(AccessFlag.PUBLIC, AccessFlag.STATIC).flagsMask(), @@ -158,7 +158,7 @@ void testIfThenBadOpcode() { @Test void testIfThenElseImplicitBreak() throws Exception { - byte[] bytes = Classfile.of().build(ClassDesc.of("Foo"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("Foo"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withMethod("foo", MethodTypeDesc.of(CD_int, CD_int), AccessFlags.ofMethod(AccessFlag.PUBLIC, AccessFlag.STATIC).flagsMask(), @@ -178,7 +178,7 @@ void testIfThenElseImplicitBreak() throws Exception { @Test void testIfThenElseExplicitBreak() throws Exception { - byte[] bytes = Classfile.of().build(ClassDesc.of("Foo"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("Foo"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withMethod("foo", MethodTypeDesc.of(CD_int, CD_int), AccessFlags.ofMethod(AccessFlag.PUBLIC, AccessFlag.STATIC).flagsMask(), @@ -197,7 +197,7 @@ void testIfThenElseExplicitBreak() throws Exception { @Test void testIfThenElseOpcode() throws Exception { - byte[] bytes = Classfile.of().build(ClassDesc.of("Foo"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("Foo"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withMethod("foo", MethodTypeDesc.of(CD_int, CD_int, CD_int), AccessFlags.ofMethod(AccessFlag.PUBLIC, AccessFlag.STATIC).flagsMask(), @@ -222,7 +222,7 @@ void testIfThenElseOpcode() throws Exception { @Test void testIfThenElseBadOpcode() { - Classfile.of().build(ClassDesc.of("Foo"), cb -> { + ClassFile.of().build(ClassDesc.of("Foo"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withMethod("foo", MethodTypeDesc.of(CD_int, CD_int, CD_int), AccessFlags.ofMethod(AccessFlag.PUBLIC, AccessFlag.STATIC).flagsMask(), @@ -243,8 +243,8 @@ void testIfThenElseBadOpcode() { @Test void testAllocateLocal() { - Classfile.of().build(ClassDesc.of("Foo"), cb -> { - cb.withMethod("foo", MethodTypeDesc.ofDescriptor("(IJI)V"), Classfile.ACC_STATIC, + ClassFile.of().build(ClassDesc.of("Foo"), cb -> { + cb.withMethod("foo", MethodTypeDesc.ofDescriptor("(IJI)V"), ClassFile.ACC_STATIC, mb -> mb.withCode(xb -> { int slot1 = xb.allocateLocal(TypeKind.IntType); int slot2 = xb.allocateLocal(TypeKind.LongType); @@ -260,8 +260,8 @@ void testAllocateLocal() { @Test void testAllocateLocalBlock() { - Classfile.of().build(ClassDesc.of("Foo"), cb -> { - cb.withMethod("foo", MethodTypeDesc.ofDescriptor("(IJI)V"), Classfile.ACC_STATIC, + ClassFile.of().build(ClassDesc.of("Foo"), cb -> { + cb.withMethod("foo", MethodTypeDesc.ofDescriptor("(IJI)V"), ClassFile.ACC_STATIC, mb -> mb.withCode(xb -> { xb.block(bb -> { int slot1 = bb.allocateLocal(TypeKind.IntType); @@ -281,8 +281,8 @@ void testAllocateLocalBlock() { @Test void testAllocateLocalIfThen() { - Classfile.of().build(ClassDesc.of("Foo"), cb -> { - cb.withMethod("foo", MethodTypeDesc.ofDescriptor("(IJI)V"), Classfile.ACC_STATIC, + ClassFile.of().build(ClassDesc.of("Foo"), cb -> { + cb.withMethod("foo", MethodTypeDesc.ofDescriptor("(IJI)V"), ClassFile.ACC_STATIC, mb -> mb.withCode(xb -> { xb.iconst_0(); xb.ifThenElse(bb -> { diff --git a/test/jdk/jdk/classfile/BuilderParamTest.java b/test/jdk/jdk/classfile/BuilderParamTest.java index 7e3b541272eef..9809f5f71c37a 100644 --- a/test/jdk/jdk/classfile/BuilderParamTest.java +++ b/test/jdk/jdk/classfile/BuilderParamTest.java @@ -23,17 +23,17 @@ /* * @test - * @summary Testing Classfile builder parameters. + * @summary Testing ClassFile builder parameters. * @run junit BuilderParamTest */ import java.lang.constant.ClassDesc; import java.lang.constant.MethodTypeDesc; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import org.junit.jupiter.api.Test; import static java.lang.constant.ConstantDescs.CD_void; -import static jdk.internal.classfile.Classfile.ACC_STATIC; +import static java.lang.classfile.ClassFile.ACC_STATIC; import static org.junit.jupiter.api.Assertions.*; /** @@ -42,7 +42,7 @@ class BuilderParamTest { @Test void testDirectBuilder() { - var cc = Classfile.of(); + var cc = ClassFile.of(); cc.build(ClassDesc.of("Foo"), cb -> { cb.withMethod("foo", MethodTypeDesc.ofDescriptor("(IJI)V"), 0, mb -> mb.withCode(xb -> { diff --git a/test/jdk/jdk/classfile/BuilderTryCatchTest.java b/test/jdk/jdk/classfile/BuilderTryCatchTest.java index 7947dc9c4f996..89117d4abd15b 100644 --- a/test/jdk/jdk/classfile/BuilderTryCatchTest.java +++ b/test/jdk/jdk/classfile/BuilderTryCatchTest.java @@ -23,18 +23,18 @@ /* * @test - * @summary Testing Classfile builder blocks. + * @summary Testing ClassFile builder blocks. * @run junit BuilderTryCatchTest */ -import jdk.internal.classfile.AccessFlags; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeBuilder; -import jdk.internal.classfile.CompoundElement; -import jdk.internal.classfile.Opcode; -import jdk.internal.classfile.TypeKind; -import jdk.internal.classfile.instruction.BranchInstruction; -import jdk.internal.classfile.instruction.ExceptionCatch; +import java.lang.classfile.AccessFlags; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.CompoundElement; +import java.lang.classfile.Opcode; +import java.lang.classfile.TypeKind; +import java.lang.classfile.instruction.BranchInstruction; +import java.lang.classfile.instruction.ExceptionCatch; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; @@ -171,7 +171,7 @@ void testTryCatchAll() throws Throwable { void testTryEmptyCatch() { byte[] bytes = generateTryCatchMethod(catchBuilder -> {}); - boolean anyGotos = Classfile.of().parse(bytes).methods().stream() + boolean anyGotos = ClassFile.of().parse(bytes).methods().stream() .flatMap(mm -> mm.code().stream()) .flatMap(CompoundElement::elementStream) .anyMatch(codeElement -> @@ -182,7 +182,7 @@ void testTryEmptyCatch() { @Test void testEmptyTry() { - byte[] bytes = Classfile.of().build(ClassDesc.of("C"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("C"), cb -> { cb.withMethod("main", MethodTypeDesc.of(CD_String, CD_String.arrayType()), AccessFlags.ofMethod(AccessFlag.PUBLIC, AccessFlag.STATIC).flagsMask(), mb -> { mb.withCode(xb -> { @@ -213,7 +213,7 @@ void testEmptyTry() { @Test void testLocalAllocation() throws Throwable { - byte[] bytes = Classfile.of().build(ClassDesc.of("C"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("C"), cb -> { cb.withMethod("main", MethodTypeDesc.of(CD_String, CD_String.arrayType()), AccessFlags.ofMethod(AccessFlag.PUBLIC, AccessFlag.STATIC).flagsMask(), mb -> { mb.withCode(xb -> { @@ -276,7 +276,7 @@ void testLocalAllocation() throws Throwable { } static byte[] generateTryCatchMethod(Consumer c) { - byte[] bytes = Classfile.of().build(ClassDesc.of("C"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("C"), cb -> { cb.withMethod("main", MethodTypeDesc.of(CD_String, CD_String.arrayType()), AccessFlags.ofMethod(AccessFlag.PUBLIC, AccessFlag.STATIC).flagsMask(), mb -> { mb.withCode(xb -> { diff --git a/test/jdk/jdk/classfile/ClassBuildingTest.java b/test/jdk/jdk/classfile/ClassBuildingTest.java index 1cae262584c40..83c794ae87997 100644 --- a/test/jdk/jdk/classfile/ClassBuildingTest.java +++ b/test/jdk/jdk/classfile/ClassBuildingTest.java @@ -29,13 +29,13 @@ * @run junit ClassBuildingTest */ -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.MethodTransform; -import jdk.internal.classfile.attribute.MethodParametersAttribute; -import jdk.internal.classfile.attribute.SignatureAttribute; -import jdk.internal.classfile.components.ClassRemapper; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.ClassFile; +import java.lang.classfile.MethodTransform; +import java.lang.classfile.attribute.MethodParametersAttribute; +import java.lang.classfile.attribute.SignatureAttribute; +import java.lang.classfile.components.ClassRemapper; import org.junit.jupiter.api.Test; import java.lang.constant.ClassDesc; @@ -47,7 +47,7 @@ public class ClassBuildingTest { @Test public void test() throws Throwable { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm; try (var in = ClassBuildingTest.class.getResourceAsStream("/Outer$1Local.class")) { cm = cc.parse(Objects.requireNonNull(in).readAllBytes()); diff --git a/test/jdk/jdk/classfile/ClassHierarchyInfoTest.java b/test/jdk/jdk/classfile/ClassHierarchyInfoTest.java index 2f7eedd0d7134..b8eadeda5e12b 100644 --- a/test/jdk/jdk/classfile/ClassHierarchyInfoTest.java +++ b/test/jdk/jdk/classfile/ClassHierarchyInfoTest.java @@ -23,17 +23,12 @@ /* * @test - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.impl - * java.base/jdk.internal.classfile.impl.verifier - * java.base/jdk.internal.classfile.components + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * java.base/java.util:open * @comment Opens java.util so HashMap bytecode generation can access its nested * classes with a proper Lookup object - * @summary Testing Classfile class hierarchy resolution SPI. + * @summary Testing ClassFile class hierarchy resolution SPI. * @run junit ClassHierarchyInfoTest */ import java.io.IOException; @@ -47,11 +42,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; -import jdk.internal.classfile.ClassHierarchyResolver; +import java.lang.classfile.ClassHierarchyResolver; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeModel; -import jdk.internal.classfile.MethodModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeModel; +import java.lang.classfile.MethodModel; import jdk.internal.classfile.impl.Util; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -126,8 +121,8 @@ void transformAndVerify(ClassHierarchyResolver res) throws Exception { void transformAndVerifySingle(ClassHierarchyResolver res) throws Exception { Path path = FileSystems.getFileSystem(URI.create("jrt:/")).getPath("modules/java.base/java/util/HashMap.class"); - var classModel = Classfile.of().parse(path); - byte[] newBytes = Classfile.of(Classfile.ClassHierarchyResolverOption.of(res)).transform(classModel, + var classModel = ClassFile.of().parse(path); + byte[] newBytes = ClassFile.of(ClassFile.ClassHierarchyResolverOption.of(res)).transform(classModel, (clb, cle) -> { if (cle instanceof MethodModel mm) { clb.transformMethod(mm, (mb, me) -> { @@ -141,7 +136,7 @@ void transformAndVerifySingle(ClassHierarchyResolver res) throws Exception { else clb.with(cle); }); - var errors = Classfile.of().parse(newBytes).verify(null); + var errors = ClassFile.of().verify(newBytes); if (!errors.isEmpty()) { var itr = errors.iterator(); var thrown = itr.next(); diff --git a/test/jdk/jdk/classfile/ClassPrinterTest.java b/test/jdk/jdk/classfile/ClassPrinterTest.java index 75c1819da54c1..b75beee4f8881 100644 --- a/test/jdk/jdk/classfile/ClassPrinterTest.java +++ b/test/jdk/jdk/classfile/ClassPrinterTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile ClassPrinter. + * @summary Testing ClassFile ClassPrinter. * @run junit ClassPrinterTest */ import java.io.IOException; @@ -32,25 +32,25 @@ import java.lang.constant.MethodTypeDesc; import java.util.List; import java.util.Optional; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.components.ClassPrinter; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.components.ClassPrinter; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; class ClassPrinterTest { ClassModel getClassModel() { - var cc = Classfile.of(); + var cc = ClassFile.of(); return cc.parse(cc.build(ClassDesc.of("Foo"), clb -> clb.withVersion(61, 0) - .withFlags(Classfile.ACC_PUBLIC) + .withFlags(ClassFile.ACC_PUBLIC) .with(SourceFileAttribute.of("Foo.java")) .withSuperclass(ClassDesc.of("Boo")) .withInterfaceSymbols(ClassDesc.of("Phee"), ClassDesc.of("Phoo")) .with(InnerClassesAttribute.of( - InnerClassInfo.of(ClassDesc.of("Phee"), Optional.of(ClassDesc.of("Phoo")), Optional.of("InnerName"), Classfile.ACC_PROTECTED), - InnerClassInfo.of(ClassDesc.of("Phoo"), Optional.empty(), Optional.empty(), Classfile.ACC_PRIVATE))) + InnerClassInfo.of(ClassDesc.of("Phee"), Optional.of(ClassDesc.of("Phoo")), Optional.of("InnerName"), ClassFile.ACC_PROTECTED), + InnerClassInfo.of(ClassDesc.of("Phoo"), Optional.empty(), Optional.empty(), ClassFile.ACC_PRIVATE))) .with(EnclosingMethodAttribute.of(ClassDesc.of("Phee"), Optional.of("enclosingMethod"), Optional.of(MethodTypeDesc.of(ConstantDescs.CD_Double, ConstantDescs.CD_Collection)))) .with(SyntheticAttribute.of()) .with(SignatureAttribute.of(ClassSignature.of(Signature.ClassTypeSig.of(ClassDesc.of("Boo")), Signature.ClassTypeSig.of(ClassDesc.of("Phee")), Signature.ClassTypeSig.of(ClassDesc.of("Phoo"))))) @@ -66,9 +66,9 @@ ClassModel getClassModel() { .with(RuntimeInvisibleAnnotationsAttribute.of(Annotation.of(ClassDesc.of("Phoo"), AnnotationElement.ofFloat("flfl", 2), AnnotationElement.ofFloat("frfl", 3)))) .with(PermittedSubclassesAttribute.ofSymbols(ClassDesc.of("Boo"), ClassDesc.of("Phoo"))) .withField("f", ConstantDescs.CD_String, fb -> fb - .withFlags(Classfile.ACC_PRIVATE) + .withFlags(ClassFile.ACC_PRIVATE) .with(RuntimeVisibleAnnotationsAttribute.of(Annotation.of(ClassDesc.of("Phoo"), AnnotationElement.ofFloat("flfl", 0), AnnotationElement.ofFloat("frfl", 1))))) - .withMethod("m", MethodTypeDesc.of(ConstantDescs.CD_Void, ConstantDescs.CD_boolean, ConstantDescs.CD_Throwable), Classfile.ACC_PROTECTED, mb -> mb + .withMethod("m", MethodTypeDesc.of(ConstantDescs.CD_Void, ConstantDescs.CD_boolean, ConstantDescs.CD_Throwable), ClassFile.ACC_PROTECTED, mb -> mb .with(AnnotationDefaultAttribute.of(AnnotationValue.ofArray( AnnotationValue.ofBoolean(true), AnnotationValue.ofByte((byte)12), diff --git a/test/jdk/jdk/classfile/ConstantPoolCopyTest.java b/test/jdk/jdk/classfile/ConstantPoolCopyTest.java index 9d910275dfcaa..87a056dfcdf6e 100644 --- a/test/jdk/jdk/classfile/ConstantPoolCopyTest.java +++ b/test/jdk/jdk/classfile/ConstantPoolCopyTest.java @@ -23,36 +23,36 @@ /* * @test - * @summary Testing Classfile constant pool cloning. + * @summary Testing ClassFile constant pool cloning. * @run junit ConstantPoolCopyTest */ -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassReader; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.constantpool.ClassEntry; -import jdk.internal.classfile.constantpool.ConstantDynamicEntry; -import jdk.internal.classfile.constantpool.DoubleEntry; -import jdk.internal.classfile.constantpool.DynamicConstantPoolEntry; -import jdk.internal.classfile.constantpool.FieldRefEntry; -import jdk.internal.classfile.constantpool.FloatEntry; -import jdk.internal.classfile.constantpool.IntegerEntry; -import jdk.internal.classfile.constantpool.InterfaceMethodRefEntry; -import jdk.internal.classfile.constantpool.InvokeDynamicEntry; -import jdk.internal.classfile.constantpool.LongEntry; -import jdk.internal.classfile.constantpool.MemberRefEntry; -import jdk.internal.classfile.constantpool.MethodHandleEntry; -import jdk.internal.classfile.constantpool.MethodRefEntry; -import jdk.internal.classfile.constantpool.MethodTypeEntry; -import jdk.internal.classfile.constantpool.ModuleEntry; -import jdk.internal.classfile.constantpool.NameAndTypeEntry; -import jdk.internal.classfile.constantpool.PackageEntry; -import jdk.internal.classfile.constantpool.PoolEntry; -import jdk.internal.classfile.constantpool.StringEntry; -import jdk.internal.classfile.constantpool.Utf8Entry; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassReader; +import java.lang.classfile.ClassFile; +import java.lang.classfile.constantpool.ClassEntry; +import java.lang.classfile.constantpool.ConstantDynamicEntry; +import java.lang.classfile.constantpool.DoubleEntry; +import java.lang.classfile.constantpool.DynamicConstantPoolEntry; +import java.lang.classfile.constantpool.FieldRefEntry; +import java.lang.classfile.constantpool.FloatEntry; +import java.lang.classfile.constantpool.IntegerEntry; +import java.lang.classfile.constantpool.InterfaceMethodRefEntry; +import java.lang.classfile.constantpool.InvokeDynamicEntry; +import java.lang.classfile.constantpool.LongEntry; +import java.lang.classfile.constantpool.MemberRefEntry; +import java.lang.classfile.constantpool.MethodHandleEntry; +import java.lang.classfile.constantpool.MethodRefEntry; +import java.lang.classfile.constantpool.MethodTypeEntry; +import java.lang.classfile.constantpool.ModuleEntry; +import java.lang.classfile.constantpool.NameAndTypeEntry; +import java.lang.classfile.constantpool.PackageEntry; +import java.lang.classfile.constantpool.PoolEntry; +import java.lang.classfile.constantpool.StringEntry; +import java.lang.classfile.constantpool.Utf8Entry; import jdk.internal.classfile.impl.SplitConstantPool; -import jdk.internal.classfile.constantpool.ConstantPoolBuilder; -import jdk.internal.classfile.BootstrapMethodEntry; -import jdk.internal.classfile.constantpool.ConstantPool; +import java.lang.classfile.constantpool.ConstantPoolBuilder; +import java.lang.classfile.BootstrapMethodEntry; +import java.lang.classfile.constantpool.ConstantPool; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -69,7 +69,7 @@ class ConstantPoolCopyTest { private static ClassModel[] rtJarToClassLow(FileSystem fs) { try { - var cc = Classfile.of(); + var cc = ClassFile.of(); var modules = Stream.of( Files.walk(fs.getPath("modules/java.base/java")), Files.walk(fs.getPath("modules"), 2).filter(p -> p.endsWith("module-info.class"))) diff --git a/test/jdk/jdk/classfile/CorpusTest.java b/test/jdk/jdk/classfile/CorpusTest.java index b54036d821e2b..450643dda2901 100644 --- a/test/jdk/jdk/classfile/CorpusTest.java +++ b/test/jdk/jdk/classfile/CorpusTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile on small Corpus. + * @summary Testing ClassFile on small Corpus. * @build helpers.* testdata.* * @run junit/othervm/timeout=480 -Djunit.jupiter.execution.parallel.enabled=true CorpusTest */ @@ -52,19 +52,19 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.stream.Stream; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.BufWriter; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.CodeTransform; -import jdk.internal.classfile.constantpool.ConstantPool; -import jdk.internal.classfile.constantpool.PoolEntry; -import jdk.internal.classfile.constantpool.Utf8Entry; +import java.lang.classfile.Attributes; +import java.lang.classfile.BufWriter; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.CodeTransform; +import java.lang.classfile.constantpool.ConstantPool; +import java.lang.classfile.constantpool.PoolEntry; +import java.lang.classfile.constantpool.Utf8Entry; import jdk.internal.classfile.impl.DirectCodeBuilder; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.classfile.instruction.LineNumber; -import jdk.internal.classfile.instruction.LocalVariable; -import jdk.internal.classfile.instruction.LocalVariableType; +import java.lang.classfile.instruction.LineNumber; +import java.lang.classfile.instruction.LocalVariable; +import java.lang.classfile.instruction.LocalVariableType; /** * CorpusTest @@ -77,7 +77,7 @@ class CorpusTest { static void splitTableAttributes(String sourceClassFile, String targetClassFile) throws IOException, URISyntaxException { var root = Paths.get(URI.create(CorpusTest.class.getResource("CorpusTest.class").toString())).getParent(); - var cc = Classfile.of(); + var cc = ClassFile.of(); Files.write(root.resolve(targetClassFile), cc.transform(cc.parse(root.resolve(sourceClassFile)), ClassTransform.transformingMethodBodies((cob, coe) -> { var dcob = (DirectCodeBuilder)cob; var curPc = dcob.curPc(); @@ -144,8 +144,8 @@ void testNullAdaptations(Path path) throws Exception { try { byte[] transformed = m.shared && m.classTransform != null - ? Classfile.of(Classfile.StackMapsOption.DROP_STACK_MAPS) - .transform(Classfile.of().parse(bytes), m.classTransform) + ? ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS) + .transform(ClassFile.of().parse(bytes), m.classTransform) : m.transform.apply(bytes); Map newDups = findDups(transformed); oldRecord = m.classRecord(bytes); @@ -195,7 +195,7 @@ void testNullAdaptations(Path path) throws Exception { @MethodSource("corpus") void testReadAndTransform(Path path) throws IOException { byte[] bytes = Files.readAllBytes(path); - var cc = Classfile.of(); + var cc = ClassFile.of(); var classModel = cc.parse(bytes); assertEqualsDeep(ClassRecord.ofClassModel(classModel), ClassRecord.ofStreamingElements(classModel), "ClassModel (actual) vs StreamingElements (expected)"); @@ -208,10 +208,10 @@ void testReadAndTransform(Path path) throws IOException { ClassRecord.ofClassModel(classModel, CompatibilityFilter.By_ClassBuilder), "ClassModel[%s] transformed by ClassBuilder (actual) vs ClassModel before transformation (expected)".formatted(path)); - assertEmpty(newModel.verify(null)); + assertEmpty(cc.verify(newModel)); //testing maxStack and maxLocals are calculated identically by StackMapGenerator and StackCounter - byte[] noStackMaps = Classfile.of(Classfile.StackMapsOption.DROP_STACK_MAPS) + byte[] noStackMaps = ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS) .transform(newModel, ClassTransform.transformingMethodBodies(CodeTransform.ACCEPT_ALL)); var noStackModel = cc.parse(noStackMaps); @@ -244,7 +244,7 @@ void testReadAndTransform(Path path) throws IOException { // } private void compareCp(byte[] orig, byte[] transformed) { - var cc = Classfile.of(); + var cc = ClassFile.of(); var cp1 = cc.parse(orig).constantPool(); var cp2 = cc.parse(transformed).constantPool(); @@ -269,7 +269,7 @@ private static String cpiToString(PoolEntry e) { private static Map findDups(byte[] bytes) { Map dups = new HashMap<>(); - var cf = Classfile.of().parse(bytes); + var cf = ClassFile.of().parse(bytes); var pool = cf.constantPool(); Set entryStrings = new HashSet<>(); for (int i = 1; i < pool.size(); i += pool.entryByIndex(i).width()) { diff --git a/test/jdk/jdk/classfile/DiscontinuedInstructionsTest.java b/test/jdk/jdk/classfile/DiscontinuedInstructionsTest.java index 642d9a10e7ad2..8d5b11c28e6f2 100644 --- a/test/jdk/jdk/classfile/DiscontinuedInstructionsTest.java +++ b/test/jdk/jdk/classfile/DiscontinuedInstructionsTest.java @@ -23,20 +23,20 @@ /* * @test - * @summary Testing Classfile handling JSR and RET instructions. + * @summary Testing ClassFile handling JSR and RET instructions. * @run junit DiscontinuedInstructionsTest */ import java.lang.constant.ClassDesc; import java.lang.constant.MethodTypeDesc; import java.util.ArrayList; import java.util.List; -import jdk.internal.classfile.*; -import jdk.internal.classfile.instruction.DiscontinuedInstruction; +import java.lang.classfile.*; +import java.lang.classfile.instruction.DiscontinuedInstruction; import helpers.ByteArrayClassLoader; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import static java.lang.constant.ConstantDescs.*; -import static jdk.internal.classfile.Classfile.*; +import static java.lang.classfile.ClassFile.*; class DiscontinuedInstructionsTest { @@ -45,7 +45,7 @@ void testJsrAndRetProcessing() throws Exception { var testClass = "JsrAndRetSample"; var testMethod = "testMethod"; var cd_list = ArrayList.class.describeConstable().get(); - var cc = Classfile.of(); + var cc = ClassFile.of(); var bytes = cc.build(ClassDesc.of(testClass), clb -> clb .withVersion(JAVA_5_VERSION, 0) .withMethodBody(testMethod, MethodTypeDesc.of(CD_void, cd_list), ACC_PUBLIC | ACC_STATIC, cob -> cob @@ -94,7 +94,7 @@ void testJsrAndRetProcessing() throws Exception { //test failure of stack map generation when enforced to generate assertThrows(IllegalArgumentException.class, () -> - Classfile.of(Classfile.StackMapsOption.GENERATE_STACK_MAPS) + ClassFile.of(ClassFile.StackMapsOption.GENERATE_STACK_MAPS) .transform(clm, ClassTransform.transformingMethodBodies(CodeTransform.ACCEPT_ALL))); } } diff --git a/test/jdk/jdk/classfile/FilterDeadLabelsTest.java b/test/jdk/jdk/classfile/FilterDeadLabelsTest.java index ac8a04dd322c1..be527d7bc1139 100644 --- a/test/jdk/jdk/classfile/FilterDeadLabelsTest.java +++ b/test/jdk/jdk/classfile/FilterDeadLabelsTest.java @@ -27,15 +27,15 @@ * @run junit FilterDeadLabelsTest */ -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import java.lang.constant.ClassDesc; import java.lang.constant.ConstantDescs; import java.lang.constant.MethodTypeDesc; import java.util.List; import java.util.function.Consumer; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.CodeBuilder; -import jdk.internal.classfile.Signature; +import java.lang.classfile.Attributes; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.Signature; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.params.ParameterizedTest; @@ -58,7 +58,7 @@ static List> deadLabelFragments() { @Test void testFilterDeadLabels() { - var cc = Classfile.of(Classfile.DeadLabelsOption.DROP_DEAD_LABELS); + var cc = ClassFile.of(ClassFile.DeadLabelsOption.DROP_DEAD_LABELS); var code = cc.parse(cc.build(ClassDesc.of("cls"), clb -> clb.withMethodBody("m", MethodTypeDesc.of(ConstantDescs.CD_void), 0, cob -> { cob.return_(); @@ -74,7 +74,7 @@ void testFilterDeadLabels() { @ParameterizedTest @MethodSource("deadLabelFragments") void testThrowOnDeadLabels(Consumer fragment) { - assertThrows(IllegalArgumentException.class, () -> Classfile.of().build(ClassDesc.of("cls"), clb -> + assertThrows(IllegalArgumentException.class, () -> ClassFile.of().build(ClassDesc.of("cls"), clb -> clb.withMethodBody("m", MethodTypeDesc.of(ConstantDescs.CD_void), 0, cob -> { cob.return_(); fragment.accept(cob); diff --git a/test/jdk/jdk/classfile/LDCTest.java b/test/jdk/jdk/classfile/LDCTest.java index d8f83a49a6ba9..1ece89675767f 100644 --- a/test/jdk/jdk/classfile/LDCTest.java +++ b/test/jdk/jdk/classfile/LDCTest.java @@ -23,28 +23,28 @@ /* * @test - * @summary Testing Classfile LDC instructions. + * @summary Testing ClassFile LDC instructions. * @run junit LDCTest */ import java.lang.constant.ClassDesc; import static java.lang.constant.ConstantDescs.*; import java.lang.constant.MethodTypeDesc; -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.ConstantPoolBuilder; -import jdk.internal.classfile.constantpool.StringEntry; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.ConstantPoolBuilder; +import java.lang.classfile.constantpool.StringEntry; import java.lang.reflect.AccessFlag; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import static helpers.TestConstants.MTD_VOID; -import static jdk.internal.classfile.Opcode.*; -import static jdk.internal.classfile.TypeKind.VoidType; -import jdk.internal.classfile.instruction.ConstantInstruction; +import static java.lang.classfile.Opcode.*; +import static java.lang.classfile.TypeKind.VoidType; +import java.lang.classfile.instruction.ConstantInstruction; class LDCTest { @Test void testLDCisConvertedToLDCW() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); byte[] bytes = cc.build(ClassDesc.of("MyClass"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withVersion(52, 0); diff --git a/test/jdk/jdk/classfile/LimitsTest.java b/test/jdk/jdk/classfile/LimitsTest.java index 856583832fd17..b89a312a67fd9 100644 --- a/test/jdk/jdk/classfile/LimitsTest.java +++ b/test/jdk/jdk/classfile/LimitsTest.java @@ -23,13 +23,13 @@ /* * @test - * @summary Testing Classfile limits. + * @summary Testing ClassFile limits. * @run junit LimitsTest */ import java.lang.constant.ClassDesc; import java.lang.constant.ConstantDescs; import java.lang.constant.MethodTypeDesc; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import jdk.internal.classfile.impl.LabelContext; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -38,7 +38,7 @@ class LimitsTest { @Test void testCPSizeLimit() { - Classfile.of().build(ClassDesc.of("BigClass"), cb -> { + ClassFile.of().build(ClassDesc.of("BigClass"), cb -> { for (int i = 1; i < 65000; i++) { cb.withField("field" + i, ConstantDescs.CD_int, fb -> {}); } @@ -47,7 +47,7 @@ void testCPSizeLimit() { @Test void testCPOverLimit() { - assertThrows(IllegalArgumentException.class, () -> Classfile.of().build(ClassDesc.of("BigClass"), cb -> { + assertThrows(IllegalArgumentException.class, () -> ClassFile.of().build(ClassDesc.of("BigClass"), cb -> { for (int i = 1; i < 66000; i++) { cb.withField("field" + i, ConstantDescs.CD_int, fb -> {}); } @@ -56,7 +56,7 @@ void testCPOverLimit() { @Test void testCodeOverLimit() { - assertThrows(IllegalArgumentException.class, () -> Classfile.of().build(ClassDesc.of("BigClass"), cb -> cb.withMethodBody( + assertThrows(IllegalArgumentException.class, () -> ClassFile.of().build(ClassDesc.of("BigClass"), cb -> cb.withMethodBody( "bigMethod", MethodTypeDesc.of(ConstantDescs.CD_void), 0, cob -> { for (int i = 0; i < 65535; i++) { cob.nop(); @@ -67,16 +67,22 @@ void testCodeOverLimit() { @Test void testEmptyCode() { - assertThrows(IllegalArgumentException.class, () -> Classfile.of().build(ClassDesc.of("EmptyClass"), cb -> cb.withMethodBody( + assertThrows(IllegalArgumentException.class, () -> ClassFile.of().build(ClassDesc.of("EmptyClass"), cb -> cb.withMethodBody( "emptyMethod", MethodTypeDesc.of(ConstantDescs.CD_void), 0, cob -> {}))); } @Test void testCodeRange() { - var cf = Classfile.of(); + var cf = ClassFile.of(); var lc = (LabelContext)cf.parse(cf.build(ClassDesc.of("EmptyClass"), cb -> cb.withMethodBody( "aMethod", MethodTypeDesc.of(ConstantDescs.CD_void), 0, cob -> cob.return_()))).methods().get(0).code().get(); assertThrows(IllegalArgumentException.class, () -> lc.getLabel(-1)); assertThrows(IllegalArgumentException.class, () -> lc.getLabel(10)); } + + @Test + void testSupportedClassVersion() { + var cf = ClassFile.of(); + assertThrows(IllegalArgumentException.class, () -> cf.parse(cf.build(ClassDesc.of("ClassFromFuture"), cb -> cb.withVersion(ClassFile.latestMajorVersion() + 1, 0)))); + } } diff --git a/test/jdk/jdk/classfile/LowAdaptTest.java b/test/jdk/jdk/classfile/LowAdaptTest.java index f3f78a9413ebc..4be4a259ac060 100644 --- a/test/jdk/jdk/classfile/LowAdaptTest.java +++ b/test/jdk/jdk/classfile/LowAdaptTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile low adaptation. + * @summary Testing ClassFile low adaptation. * @run junit LowAdaptTest */ import java.lang.constant.ClassDesc; @@ -35,14 +35,14 @@ import java.net.URI; import java.nio.file.Paths; -import jdk.internal.classfile.AccessFlags; +import java.lang.classfile.AccessFlags; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.Opcode; -import jdk.internal.classfile.TypeKind; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.Opcode; +import java.lang.classfile.TypeKind; import helpers.ByteArrayClassLoader; -import jdk.internal.classfile.attribute.SourceFileAttribute; +import java.lang.classfile.attribute.SourceFileAttribute; import jdk.internal.classfile.impl.DirectClassBuilder; import org.junit.jupiter.api.Test; @@ -54,7 +54,7 @@ class LowAdaptTest { @Test void testAdapt() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cl = cc.parse(Paths.get(URI.create(LowAdaptTest.class.getResource(test + ".class").toString()))); DirectMethodHandleDesc bsm = MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.STATIC, diff --git a/test/jdk/jdk/classfile/LowJCovAttributeTest.java b/test/jdk/jdk/classfile/LowJCovAttributeTest.java index 25bd9039d6e4a..9bc1e29155ea3 100644 --- a/test/jdk/jdk/classfile/LowJCovAttributeTest.java +++ b/test/jdk/jdk/classfile/LowJCovAttributeTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile low JCov attributes. + * @summary Testing ClassFile low JCov attributes. * @compile -Xjcov LowJCovAttributeTest.java * @run junit LowJCovAttributeTest */ @@ -32,14 +32,14 @@ import java.nio.file.Path; import java.nio.file.Paths; -import jdk.internal.classfile.Attribute; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeModel; -import jdk.internal.classfile.MethodModel; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.Utf8Entry; +import java.lang.classfile.Attribute; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeModel; +import java.lang.classfile.MethodModel; +import java.lang.classfile.Attributes; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.Utf8Entry; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -59,7 +59,7 @@ class LowJCovAttributeTest { LowJCovAttributeTest() throws IOException { this.path = Paths.get(URI.create(LowJCovAttributeTest.class.getResource(TEST_FILE).toString())); - this.classLow = Classfile.of().parse(path); + this.classLow = ClassFile.of().parse(path); } @Test diff --git a/test/jdk/jdk/classfile/LowModuleTest.java b/test/jdk/jdk/classfile/LowModuleTest.java index 7dc19aec32337..e78eff74d1d4c 100644 --- a/test/jdk/jdk/classfile/LowModuleTest.java +++ b/test/jdk/jdk/classfile/LowModuleTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile low module attribute. + * @summary Testing ClassFile low module attribute. * @run junit LowModuleTest */ import java.io.IOException; @@ -32,15 +32,15 @@ import java.nio.file.Files; import java.nio.file.Path; -import jdk.internal.classfile.Attribute; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.ClassEntry; -import jdk.internal.classfile.constantpool.ModuleEntry; -import jdk.internal.classfile.constantpool.PackageEntry; -import jdk.internal.classfile.constantpool.Utf8Entry; +import java.lang.classfile.Attribute; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.Attributes; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.ClassEntry; +import java.lang.classfile.constantpool.ModuleEntry; +import java.lang.classfile.constantpool.PackageEntry; +import java.lang.classfile.constantpool.Utf8Entry; import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -66,7 +66,7 @@ static Path[] corpus() throws IOException { void testRead(Path path, TestInfo test) throws Exception { try { printf("%nCHECK %s%n", test.getDisplayName()); - ClassModel classLow = Classfile.of().parse(path); + ClassModel classLow = ClassFile.of().parse(path); testRead0(classLow); } catch(Exception ex) { System.err.printf("%nFAIL %s - %s%n", path, ex); diff --git a/test/jdk/jdk/classfile/LvtTest.java b/test/jdk/jdk/classfile/LvtTest.java index 880f7b5bd2486..1c35b071cc206 100644 --- a/test/jdk/jdk/classfile/LvtTest.java +++ b/test/jdk/jdk/classfile/LvtTest.java @@ -23,13 +23,13 @@ /* * @test - * @summary Testing Classfile local variable table. + * @summary Testing ClassFile local variable table. * @compile -g testdata/Lvt.java * @run junit LvtTest */ import helpers.ClassRecord; import helpers.Transforms; -import jdk.internal.classfile.*; +import java.lang.classfile.*; import java.io.*; import java.lang.constant.ClassDesc; @@ -41,13 +41,13 @@ import java.util.Arrays; import java.util.List; -import jdk.internal.classfile.AccessFlags; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.attribute.SourceFileAttribute; -import jdk.internal.classfile.constantpool.ConstantPoolBuilder; -import jdk.internal.classfile.constantpool.Utf8Entry; -import jdk.internal.classfile.instruction.LocalVariable; -import jdk.internal.classfile.instruction.LocalVariableType; +import java.lang.classfile.AccessFlags; +import java.lang.classfile.Attributes; +import java.lang.classfile.attribute.SourceFileAttribute; +import java.lang.classfile.constantpool.ConstantPoolBuilder; +import java.lang.classfile.constantpool.Utf8Entry; +import java.lang.classfile.instruction.LocalVariable; +import java.lang.classfile.instruction.LocalVariableType; import java.lang.reflect.AccessFlag; import org.junit.jupiter.api.Test; @@ -60,9 +60,9 @@ import static helpers.TestUtil.ExpectedLvtRecord; import static java.lang.constant.ConstantDescs.*; import java.lang.constant.MethodTypeDesc; -import static jdk.internal.classfile.Opcode.*; -import static jdk.internal.classfile.Opcode.INVOKEVIRTUAL; -import static jdk.internal.classfile.TypeKind.VoidType; +import static java.lang.classfile.Opcode.*; +import static java.lang.classfile.Opcode.INVOKEVIRTUAL; +import static java.lang.classfile.TypeKind.VoidType; import static org.junit.jupiter.api.Assertions.*; class LvtTest { @@ -79,7 +79,7 @@ class LvtTest { @Test void getLVTEntries() { - ClassModel c = Classfile.of().parse(fileBytes); + ClassModel c = ClassFile.of().parse(fileBytes); CodeModel co = c.methods().stream() .filter(mm -> mm.methodName().stringValue().equals("m")) .map(MethodModel::code) @@ -104,7 +104,7 @@ void getLVTEntries() { @Test void buildLVTEntries() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel c = cc.parse(fileBytes); // Compare transformed model and original with CodeBuilder filter @@ -116,7 +116,7 @@ void buildLVTEntries() throws Exception { @Test void testCreateLoadLVT() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); byte[] bytes = cc.build(ClassDesc.of("MyClass"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withVersion(52, 0); @@ -189,7 +189,7 @@ void testCreateLoadLVT() throws Exception { @Test void getLVTTEntries() { - ClassModel c = Classfile.of().parse(fileBytes); + ClassModel c = ClassFile.of().parse(fileBytes); CodeModel co = c.methods().stream() .filter(mm -> mm.methodName().stringValue().equals("n")) .map(MethodModel::code) @@ -229,7 +229,7 @@ void getLVTTEntries() { @Test void testCreateLoadLVTT() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); byte[] bytes = cc.build(ClassDesc.of("MyClass"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withVersion(52, 0); @@ -243,7 +243,7 @@ void testCreateLoadLVTT() throws Exception { ) .withMethod("m", MethodTypeDesc.of(CD_Object, CD_Object.arrayType()), - Classfile.ACC_PUBLIC, + ClassFile.ACC_PUBLIC, mb -> mb.withFlags(AccessFlag.PUBLIC) .withCode(c0 -> { ConstantPoolBuilder cpb = cb.constantPool(); @@ -302,7 +302,7 @@ void testCreateLoadLVTT() throws Exception { @Test void skipDebugSkipsLVT() { - ClassModel c = Classfile.of(Classfile.DebugElementsOption.DROP_DEBUG).parse(fileBytes); + ClassModel c = ClassFile.of(ClassFile.DebugElementsOption.DROP_DEBUG).parse(fileBytes); c.forEachElement(e -> { if (e instanceof MethodModel m) { diff --git a/test/jdk/jdk/classfile/MassAdaptCopyCodeTest.java b/test/jdk/jdk/classfile/MassAdaptCopyCodeTest.java index 749be11aac235..423ea91802aa3 100644 --- a/test/jdk/jdk/classfile/MassAdaptCopyCodeTest.java +++ b/test/jdk/jdk/classfile/MassAdaptCopyCodeTest.java @@ -23,15 +23,15 @@ /* * @test - * @summary Testing Classfile massive class adaptation. + * @summary Testing ClassFile massive class adaptation. * @run junit MassAdaptCopyCodeTest */ import helpers.ByteArrayClassLoader; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeModel; -import jdk.internal.classfile.CodeTransform; -import jdk.internal.classfile.MethodModel; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeModel; +import java.lang.classfile.CodeTransform; +import java.lang.classfile.MethodModel; import org.junit.jupiter.api.Test; import java.io.File; @@ -74,13 +74,13 @@ void copy(File f) throws Exception { } void copy(String name, byte[] bytes) throws Exception { - byte[] newBytes = adaptCopy(Classfile.of().parse(bytes)); + byte[] newBytes = adaptCopy(ClassFile.of().parse(bytes)); classNameToClass.put(name, new ByteArrayClassLoader.ClassData(name, newBytes)); if (name.contains("/")) throw new RuntimeException(name); } public byte[] adaptCopy(ClassModel cm) { - return Classfile.of().transform(cm, (cb, ce) -> { + return ClassFile.of().transform(cm, (cb, ce) -> { if (ce instanceof MethodModel mm) { cb.transformMethod(mm, (mb, me) -> { if (me instanceof CodeModel xm) { diff --git a/test/jdk/jdk/classfile/MassAdaptCopyPrimitiveMatchCodeTest.java b/test/jdk/jdk/classfile/MassAdaptCopyPrimitiveMatchCodeTest.java index afa6f23d04c80..825394bff0af7 100644 --- a/test/jdk/jdk/classfile/MassAdaptCopyPrimitiveMatchCodeTest.java +++ b/test/jdk/jdk/classfile/MassAdaptCopyPrimitiveMatchCodeTest.java @@ -23,20 +23,20 @@ /* * @test - * @summary Testing Classfile massive class adaptation. + * @summary Testing ClassFile massive class adaptation. * @run junit MassAdaptCopyPrimitiveMatchCodeTest */ import helpers.InstructionModelToCodeBuilder; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.CodeElement; -import jdk.internal.classfile.CodeModel; -import jdk.internal.classfile.Instruction; -import jdk.internal.classfile.MethodModel; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.ClassFile; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassModel; +import java.lang.classfile.CodeElement; +import java.lang.classfile.CodeModel; +import java.lang.classfile.Instruction; +import java.lang.classfile.MethodModel; +import java.lang.classfile.instruction.InvokeInstruction; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -94,7 +94,7 @@ public void testCodeMatch() throws Exception { void copy(String name, byte[] bytes) throws Exception { //System.err.printf("MassAdaptCopyPrimitiveMatchCodeTest - %s%n", name); - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm =cc.parse(bytes); Map m2b = new HashMap<>(); Map m2c = new HashMap<>(); diff --git a/test/jdk/jdk/classfile/ModuleBuilderTest.java b/test/jdk/jdk/classfile/ModuleBuilderTest.java index e0734c5a23a47..68dd16ab03af4 100644 --- a/test/jdk/jdk/classfile/ModuleBuilderTest.java +++ b/test/jdk/jdk/classfile/ModuleBuilderTest.java @@ -23,19 +23,19 @@ /* * @test - * @summary Testing Classfile building module. + * @summary Testing ClassFile building module. * @run junit ModuleBuilderTest */ -import jdk.internal.classfile.*; - -import jdk.internal.classfile.attribute.ModuleAttribute; -import jdk.internal.classfile.attribute.ModuleExportInfo; -import jdk.internal.classfile.attribute.ModuleMainClassAttribute; -import jdk.internal.classfile.attribute.ModuleOpenInfo; -import jdk.internal.classfile.attribute.ModulePackagesAttribute; -import jdk.internal.classfile.attribute.ModuleProvideInfo; -import jdk.internal.classfile.attribute.ModuleRequireInfo; -import jdk.internal.classfile.Attributes; +import java.lang.classfile.*; + +import java.lang.classfile.attribute.ModuleAttribute; +import java.lang.classfile.attribute.ModuleExportInfo; +import java.lang.classfile.attribute.ModuleMainClassAttribute; +import java.lang.classfile.attribute.ModuleOpenInfo; +import java.lang.classfile.attribute.ModulePackagesAttribute; +import java.lang.classfile.attribute.ModuleProvideInfo; +import java.lang.classfile.attribute.ModuleRequireInfo; +import java.lang.classfile.Attributes; import java.lang.constant.ModuleDesc; import java.lang.constant.PackageDesc; import org.junit.jupiter.api.Test; @@ -62,7 +62,7 @@ class ModuleBuilderTest { private final ModuleAttribute attr; public ModuleBuilderTest() { - var cc = Classfile.of(); + var cc = ClassFile.of(); byte[] modInfo = cc.buildModule( ModuleAttribute.of(modName, mb -> mb .moduleVersion(modVsn) @@ -97,7 +97,7 @@ public ModuleBuilderTest() { @Test void testCreateModuleInfo() { // Build the module-info.class bytes - var cc = Classfile.of(); + var cc = ClassFile.of(); byte[] modBytes = cc.buildModule(ModuleAttribute.of(modName, mb -> mb.moduleVersion(modVsn))); // Verify @@ -195,7 +195,7 @@ void verifyMainclass() { void verifyIsModuleInfo() throws Exception { assertTrue(moduleModel.isModuleInfo()); - ClassModel m = Classfile.of().parse(Paths.get(URI.create(ModuleBuilderTest.class.getResource("ModuleBuilderTest.class").toString()))); + ClassModel m = ClassFile.of().parse(Paths.get(URI.create(ModuleBuilderTest.class.getResource("ModuleBuilderTest.class").toString()))); assertFalse(m.isModuleInfo()); } } diff --git a/test/jdk/jdk/classfile/OneToOneTest.java b/test/jdk/jdk/classfile/OneToOneTest.java index f9465c292d497..5db0489ac3e32 100644 --- a/test/jdk/jdk/classfile/OneToOneTest.java +++ b/test/jdk/jdk/classfile/OneToOneTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile class writing and reading. + * @summary Testing ClassFile class writing and reading. * @run junit OneToOneTest */ import java.lang.constant.ClassDesc; @@ -31,37 +31,37 @@ import java.lang.constant.MethodTypeDesc; import java.util.List; -import jdk.internal.classfile.AccessFlags; +import java.lang.classfile.AccessFlags; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.Instruction; -import jdk.internal.classfile.Label; -import jdk.internal.classfile.MethodModel; -import jdk.internal.classfile.TypeKind; -import jdk.internal.classfile.attribute.SourceFileAttribute; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.Instruction; +import java.lang.classfile.Label; +import java.lang.classfile.MethodModel; +import java.lang.classfile.TypeKind; +import java.lang.classfile.attribute.SourceFileAttribute; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; -import jdk.internal.classfile.instruction.ConstantInstruction; -import jdk.internal.classfile.instruction.StoreInstruction; -import jdk.internal.classfile.instruction.BranchInstruction; -import jdk.internal.classfile.instruction.LoadInstruction; -import jdk.internal.classfile.instruction.OperatorInstruction; -import jdk.internal.classfile.instruction.FieldInstruction; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.instruction.ConstantInstruction; +import java.lang.classfile.instruction.StoreInstruction; +import java.lang.classfile.instruction.BranchInstruction; +import java.lang.classfile.instruction.LoadInstruction; +import java.lang.classfile.instruction.OperatorInstruction; +import java.lang.classfile.instruction.FieldInstruction; +import java.lang.classfile.instruction.InvokeInstruction; import static helpers.TestConstants.CD_PrintStream; import static helpers.TestConstants.CD_System; import static helpers.TestConstants.MTD_INT_VOID; import static helpers.TestConstants.MTD_VOID; -import static jdk.internal.classfile.Opcode.*; +import static java.lang.classfile.Opcode.*; class OneToOneTest { @Test void testClassWriteRead() { - var cc = Classfile.of(); + var cc = ClassFile.of(); byte[] bytes = cc.build(ClassDesc.of("MyClass"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withVersion(52, 0); diff --git a/test/jdk/jdk/classfile/OpcodesValidationTest.java b/test/jdk/jdk/classfile/OpcodesValidationTest.java index 34829d74de7e2..085ba631349b5 100644 --- a/test/jdk/jdk/classfile/OpcodesValidationTest.java +++ b/test/jdk/jdk/classfile/OpcodesValidationTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile constant instruction opcodes. + * @summary Testing ClassFile constant instruction opcodes. * @run junit OpcodesValidationTest */ import java.lang.constant.ClassDesc; @@ -32,12 +32,12 @@ import java.lang.constant.MethodTypeDesc; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.Opcode; +import java.lang.classfile.ClassFile; +import java.lang.classfile.Opcode; import org.junit.jupiter.api.*; import static org.junit.jupiter.api.DynamicTest.dynamicTest; import static org.junit.jupiter.api.Assertions.*; -import static jdk.internal.classfile.Opcode.*; +import static java.lang.classfile.Opcode.*; import java.util.stream.Stream; public class OpcodesValidationTest { @@ -103,7 +103,7 @@ Stream testPositiveCases() { } private void testPositiveCase(Opcode opcode, Object constant) { - Classfile.of().build(ClassDesc.of("MyClass"), + ClassFile.of().build(ClassDesc.of("MyClass"), cb -> cb.withFlags(AccessFlag.PUBLIC) .withMethod("", MethodTypeDesc.of(CD_void), 0, mb -> mb.withCode( @@ -120,7 +120,7 @@ Stream testNegativeCases() { } private void testNegativeCase(Opcode opcode, Object constant) { - Classfile.of().build(ClassDesc.of("MyClass"), + ClassFile.of().build(ClassDesc.of("MyClass"), cb -> cb.withFlags(AccessFlag.PUBLIC) .withMethod("", MethodTypeDesc.of(CD_void), 0, mb -> mb .withCode( diff --git a/test/jdk/jdk/classfile/OptionsTest.java b/test/jdk/jdk/classfile/OptionsTest.java index 12d3ccf757078..4a47c899d8ec2 100644 --- a/test/jdk/jdk/classfile/OptionsTest.java +++ b/test/jdk/jdk/classfile/OptionsTest.java @@ -25,7 +25,7 @@ /* * @test - * @summary Testing Classfile options on small Corpus. + * @summary Testing ClassFile options on small Corpus. * @run junit/othervm -Djunit.jupiter.execution.parallel.enabled=true OptionsTest */ import org.junit.jupiter.params.ParameterizedTest; @@ -44,16 +44,7 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; -import jdk.internal.classfile.AttributeMapper; -import jdk.internal.classfile.AttributedElement; -import jdk.internal.classfile.BufWriter; -import jdk.internal.classfile.ClassReader; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.ClassfileElement; -import jdk.internal.classfile.CodeTransform; -import jdk.internal.classfile.CompoundElement; -import jdk.internal.classfile.CustomAttribute; +import java.lang.classfile.*; /** * OptionsTest @@ -72,9 +63,9 @@ static Path[] corpus() throws IOException, URISyntaxException { @ParameterizedTest @MethodSource("corpus") void testAttributesProcessingOptionOnTransform(Path path) throws Exception { - testNoUnstable(path, Classfile.of().parse( - Classfile.of(Classfile.AttributesProcessingOption.DROP_UNSTABLE_ATRIBUTES).transform( - Classfile.of().parse(path), + testNoUnstable(path, ClassFile.of().parse( + ClassFile.of(ClassFile.AttributesProcessingOption.DROP_UNSTABLE_ATRIBUTES).transform( + ClassFile.of().parse(path), ClassTransform.transformingMethodBodies(CodeTransform.ACCEPT_ALL)))); } @@ -110,24 +101,24 @@ public AttributeMapper.AttributeStability stability() { @Test void testUnknownAttribute() throws Exception { - var classBytes = Classfile.of(Classfile.AttributeMapperOption.of(e -> { + var classBytes = ClassFile.of(ClassFile.AttributeMapperOption.of(e -> { return e.equalsString(STRANGE_ATTRIBUTE_MAPPER.name()) ? STRANGE_ATTRIBUTE_MAPPER : null; })).build(ClassDesc.of("StrangeClass"), clb -> clb.with(new StrangeAttribute())); //test default - assertFalse(Classfile.of().parse(classBytes).attributes().isEmpty()); + assertFalse(ClassFile.of().parse(classBytes).attributes().isEmpty()); //test drop unknown at transform - assertTrue(Classfile.of().parse( - Classfile.of(Classfile.AttributesProcessingOption.DROP_UNKNOWN_ATTRIBUTES).transform( - Classfile.of().parse(classBytes), + assertTrue(ClassFile.of().parse( + ClassFile.of(ClassFile.AttributesProcessingOption.DROP_UNKNOWN_ATTRIBUTES).transform( + ClassFile.of().parse(classBytes), ClassTransform.ACCEPT_ALL)).attributes().isEmpty()); } - void testNoUnstable(Path path, ClassfileElement e) { + void testNoUnstable(Path path, ClassFileElement e) { if (e instanceof AttributedElement ae) ae.attributes().forEach(a -> assertTrue(AttributeMapper.AttributeStability.UNSTABLE.ordinal() >= a.attributeMapper().stability().ordinal(), () -> "class " + path + " contains unexpected " + a)); - if (e instanceof CompoundElement ce) ce.forEachElement(ee -> testNoUnstable(path, (ClassfileElement)ee)); + if (e instanceof CompoundElement ce) ce.forEachElement(ee -> testNoUnstable(path, (ClassFileElement)ee)); } } diff --git a/test/jdk/jdk/classfile/PreviewMinorVersionTest.java b/test/jdk/jdk/classfile/PreviewMinorVersionTest.java index 19951d1ec279a..6cbff76f6d9cf 100644 --- a/test/jdk/jdk/classfile/PreviewMinorVersionTest.java +++ b/test/jdk/jdk/classfile/PreviewMinorVersionTest.java @@ -20,20 +20,20 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import org.junit.jupiter.api.Test; import java.lang.constant.ClassDesc; import static java.lang.constant.ConstantDescs.*; -import static jdk.internal.classfile.Classfile.*; +import static java.lang.classfile.ClassFile.*; import static org.junit.jupiter.api.Assertions.*; /* * @test * @bug 8311172 * @run junit PreviewMinorVersionTest - * @summary Ensures Classfile.PREVIEW_MINOR_VERSION equals that of classes with + * @summary Ensures ClassFile.PREVIEW_MINOR_VERSION equals that of classes with * preview minor version from ClassModel::minorVersion */ public class PreviewMinorVersionTest { @@ -42,7 +42,7 @@ public class PreviewMinorVersionTest { public void testMinorVersionMatches() { // compile a class with --enable-preview // uses Record feature to trigger forcePreview - var cf = Classfile.of(); + var cf = ClassFile.of(); var cd = ClassDesc.of("Test"); var bytes = cf.build(cd, cb -> cb .withSuperclass(CD_Object) @@ -51,7 +51,7 @@ public void testMinorVersionMatches() { .withVersion(JAVA_17_VERSION, -1) ); - var cm = Classfile.of().parse(bytes); - assertEquals(Classfile.PREVIEW_MINOR_VERSION, cm.minorVersion()); + var cm = ClassFile.of().parse(bytes); + assertEquals(ClassFile.PREVIEW_MINOR_VERSION, cm.minorVersion()); } } diff --git a/test/jdk/jdk/classfile/PrimitiveClassConstantTest.java b/test/jdk/jdk/classfile/PrimitiveClassConstantTest.java index 7b89d4701ec1f..376fe3898269b 100644 --- a/test/jdk/jdk/classfile/PrimitiveClassConstantTest.java +++ b/test/jdk/jdk/classfile/PrimitiveClassConstantTest.java @@ -33,7 +33,7 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.util.function.Supplier; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -43,7 +43,7 @@ import static java.lang.constant.ConstantDescs.CD_long; import static java.lang.constant.ConstantDescs.INIT_NAME; import static java.lang.constant.ConstantDescs.MTD_void; -import static jdk.internal.classfile.Classfile.ACC_PUBLIC; +import static java.lang.classfile.ClassFile.ACC_PUBLIC; public final class PrimitiveClassConstantTest { @@ -51,7 +51,7 @@ public final class PrimitiveClassConstantTest { public void test() throws Throwable { ClassDesc ape = ClassDesc.of("Ape"); var lookup = MethodHandles.lookup(); - Class a = lookup.defineClass(Classfile.of().build(ape, clb -> { + Class a = lookup.defineClass(ClassFile.of().build(ape, clb -> { clb.withSuperclass(CD_Object); clb.withInterfaceSymbols(Supplier.class.describeConstable().orElseThrow()); clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> { diff --git a/test/jdk/jdk/classfile/ShortJumpsFixTest.java b/test/jdk/jdk/classfile/ShortJumpsFixTest.java index 5a60ca1e22e33..15a777bf713f4 100644 --- a/test/jdk/jdk/classfile/ShortJumpsFixTest.java +++ b/test/jdk/jdk/classfile/ShortJumpsFixTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile short to long jumps extension. + * @summary Testing ClassFile short to long jumps extension. * @run junit ShortJumpsFixTest */ import java.lang.constant.ClassDesc; @@ -31,15 +31,15 @@ import java.lang.constant.MethodTypeDesc; import java.util.LinkedList; import java.util.List; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.Instruction; -import jdk.internal.classfile.MethodTransform; -import jdk.internal.classfile.Opcode; -import static jdk.internal.classfile.Opcode.*; -import jdk.internal.classfile.instruction.ConstantInstruction; -import jdk.internal.classfile.instruction.NopInstruction; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.ClassFile; +import java.lang.classfile.Instruction; +import java.lang.classfile.MethodTransform; +import java.lang.classfile.Opcode; +import static java.lang.classfile.Opcode.*; +import java.lang.classfile.instruction.ConstantInstruction; +import java.lang.classfile.instruction.NopInstruction; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.*; @@ -98,11 +98,11 @@ static Sample[] provideBack() { }; } - static final Classfile - CC_Fixed_Jumps = Classfile.of(Classfile.ShortJumpsOption.FIX_SHORT_JUMPS), - CC_Not_Fixed_Jumps = Classfile.of(Classfile.ShortJumpsOption.FAIL_ON_SHORT_JUMPS), - CC_No_Stack_No_Patch = Classfile.of(Classfile.StackMapsOption.DROP_STACK_MAPS, - Classfile.DeadCodeOption.KEEP_DEAD_CODE); + static final ClassFile + CC_Fixed_Jumps = ClassFile.of(ClassFile.ShortJumpsOption.FIX_SHORT_JUMPS), + CC_Not_Fixed_Jumps = ClassFile.of(ClassFile.ShortJumpsOption.FAIL_ON_SHORT_JUMPS), + CC_No_Stack_No_Patch = ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS, + ClassFile.DeadCodeOption.KEEP_DEAD_CODE); @ParameterizedTest @MethodSource("provideFwd") @@ -204,7 +204,7 @@ void testFailBackJumpsChainedTransform(Sample sample) throws Exception { ClassTransform.ACCEPT_ALL.andThen(overflow()))); //involve BufferedCodeBuilder here } - private static ClassModel generateFwd(Classfile cc, Sample sample, boolean overflow) { + private static ClassModel generateFwd(ClassFile cc, Sample sample, boolean overflow) { return cc.parse(cc.build(ClassDesc.of("WhateverClass"), cb -> cb.withMethod("whateverMethod", MethodTypeDesc.of(ConstantDescs.CD_void), 0, mb -> mb.withCode(cob -> { @@ -219,7 +219,7 @@ private static ClassModel generateFwd(Classfile cc, Sample sample, boolean overf })))); } - private static ClassModel generateBack(Classfile cc, Sample sample, boolean overflow) { + private static ClassModel generateBack(ClassFile cc, Sample sample, boolean overflow) { return cc.parse(cc.build(ClassDesc.of("WhateverClass"), cb -> cb.withMethod("whateverMethod", MethodTypeDesc.of(ConstantDescs.CD_void), 0, mb -> mb.withCode(cob -> { @@ -250,7 +250,7 @@ private static ClassTransform overflow() { } private static void assertFixed(Sample sample, byte[] classFile) { - assertFixed(sample, Classfile.of().parse(classFile)); + assertFixed(sample, ClassFile.of().parse(classFile)); } private static void assertFixed(Sample sample, ClassModel clm) { diff --git a/test/jdk/jdk/classfile/SignaturesTest.java b/test/jdk/jdk/classfile/SignaturesTest.java index 932f8c7e80d1c..9f5fbe8adcae2 100644 --- a/test/jdk/jdk/classfile/SignaturesTest.java +++ b/test/jdk/jdk/classfile/SignaturesTest.java @@ -38,12 +38,12 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; -import jdk.internal.classfile.ClassSignature; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.MethodSignature; -import jdk.internal.classfile.Signature; -import jdk.internal.classfile.Signature.*; -import jdk.internal.classfile.Attributes; +import java.lang.classfile.ClassSignature; +import java.lang.classfile.ClassFile; +import java.lang.classfile.MethodSignature; +import java.lang.classfile.Signature; +import java.lang.classfile.Signature.*; +import java.lang.classfile.Attributes; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static helpers.ClassRecord.assertEqualsDeep; @@ -128,7 +128,7 @@ void testParseAndPrintSignatures() throws Exception { .flatMap(p -> p) .filter(p -> Files.isRegularFile(p) && p.toString().endsWith(".class")).forEach(path -> { try { - var cm = Classfile.of().parse(path); + var cm = ClassFile.of().parse(path); cm.findAttribute(Attributes.SIGNATURE).ifPresent(csig -> { assertEquals( ClassSignature.parseFrom(csig.signature().stringValue()).signatureString(), @@ -177,7 +177,7 @@ static class Observer extends ArrayList.Inner>{} @Test void testClassSignatureClassDesc() throws IOException { - var observerCf = Classfile.of().parse(Path.of(System.getProperty("test.classes"), "SignaturesTest$Observer.class")); + var observerCf = ClassFile.of().parse(Path.of(System.getProperty("test.classes"), "SignaturesTest$Observer.class")); var sig = observerCf.findAttribute(Attributes.SIGNATURE).orElseThrow().asClassSignature(); var innerSig = (ClassTypeSig) ((ClassTypeSig) sig.superclassSignature()) // ArrayList .typeArgs().getFirst() // Outer.Inner diff --git a/test/jdk/jdk/classfile/SnippetsTest.java b/test/jdk/jdk/classfile/SnippetsTest.java index abb4c773fde70..6999ef2a0aef1 100644 --- a/test/jdk/jdk/classfile/SnippetsTest.java +++ b/test/jdk/jdk/classfile/SnippetsTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Compile Classfile API snippets + * @summary Compile ClassFile API snippets * @run junit SnippetsTest */ @@ -40,8 +40,8 @@ public class SnippetsTest { @ParameterizedTest @ValueSource(strings = { - "src/java.base/share/classes/jdk/internal/classfile/snippet-files/PackageSnippets.java", - "src/java.base/share/classes/jdk/internal/classfile/components/snippet-files/PackageSnippets.java"}) + "src/java.base/share/classes/java/lang/classfile/snippet-files/PackageSnippets.java", + "src/java.base/share/classes/java/lang/classfile/components/snippet-files/PackageSnippets.java"}) void testSnippet(String source) throws Exception { var p = Paths.get(System.getProperty("test.src", ".")).toAbsolutePath(); while ((p = p.getParent()) != null) { @@ -53,11 +53,8 @@ void testSnippet(String source) throws Exception { fileManager.setLocation(StandardLocation.CLASS_OUTPUT, List.of(Paths.get(System.getProperty("test.classes", ".")).toFile())); var task = compiler.getTask(null, fileManager, null, List.of( - "--add-exports", "java.base/jdk.internal.classfile=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.attribute=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.components=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.instruction=ALL-UNNAMED"), + "--enable-preview", + "--source", String.valueOf(Runtime.version().feature())), null, compilationUnits); if (task.call()) return; throw new RuntimeException("Error compiling " + source); diff --git a/test/jdk/jdk/classfile/StackMapsTest.java b/test/jdk/jdk/classfile/StackMapsTest.java index 3950540500144..88858ce839481 100644 --- a/test/jdk/jdk/classfile/StackMapsTest.java +++ b/test/jdk/jdk/classfile/StackMapsTest.java @@ -29,8 +29,8 @@ * @run junit StackMapsTest */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.components.ClassPrinter; +import java.lang.classfile.*; +import java.lang.classfile.components.ClassPrinter; import java.net.URI; import java.nio.file.FileSystem; import java.nio.file.FileSystems; @@ -38,7 +38,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import static helpers.TestUtil.assertEmpty; -import static jdk.internal.classfile.Classfile.ACC_STATIC; +import static java.lang.classfile.ClassFile.ACC_STATIC; import java.lang.constant.ClassDesc; import java.lang.constant.ConstantDescs; @@ -51,8 +51,8 @@ class StackMapsTest { private byte[] buildDeadCode() { - return Classfile.of(Classfile.StackMapsOption.DROP_STACK_MAPS, - Classfile.DeadCodeOption.KEEP_DEAD_CODE).build( + return ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS, + ClassFile.DeadCodeOption.KEEP_DEAD_CODE).build( ClassDesc.of("DeadCodePattern"), clb -> clb.withMethodBody( "twoReturns", @@ -94,7 +94,7 @@ void testDeadCodePatternPatch() throws Exception { @Test void testDeadCodePatternFail() throws Exception { - var error = assertThrows(IllegalArgumentException.class, () -> testTransformedStackMaps(buildDeadCode(), Classfile.DeadCodeOption.KEEP_DEAD_CODE)); + var error = assertThrows(IllegalArgumentException.class, () -> testTransformedStackMaps(buildDeadCode(), ClassFile.DeadCodeOption.KEEP_DEAD_CODE)); assertLinesMatch( """ Unable to generate stack map frame for dead code at bytecode offset 1 of method twoReturns() @@ -169,7 +169,7 @@ void testPattern10() throws Exception { @Test void testFrameOutOfBytecodeRange() { - var cc = Classfile.of(); + var cc = ClassFile.of(); var error = assertThrows(IllegalArgumentException.class, () -> cc.parse( cc.build(ClassDesc.of("TestClass"), clb -> @@ -192,7 +192,7 @@ void testFrameOutOfBytecodeRange() { @Test void testMethodSwitchFromStatic() { assertThrows(IllegalArgumentException.class, () -> - Classfile.of().build(ClassDesc.of("TestClass"), clb -> + ClassFile.of().build(ClassDesc.of("TestClass"), clb -> clb.withMethod("testMethod", MethodTypeDesc.of(ConstantDescs.CD_Object, ConstantDescs.CD_int), ACC_STATIC, mb -> mb.withCode(cob -> { @@ -205,7 +205,7 @@ void testMethodSwitchFromStatic() { @Test void testMethodSwitchToStatic() { assertThrows(IllegalArgumentException.class, () -> - Classfile.of().build(ClassDesc.of("TestClass"), clb -> + ClassFile.of().build(ClassDesc.of("TestClass"), clb -> clb.withMethod("testMethod", MethodTypeDesc.of(ConstantDescs.CD_int, ConstantDescs.CD_int), 0, mb -> mb.withCode(cob -> { @@ -217,7 +217,7 @@ void testMethodSwitchToStatic() { @Test void testClassVersions() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); var actualVersion = cc.parse(StackMapsTest.class.getResourceAsStream("/testdata/Pattern1.class").readAllBytes()); //test transformation to class version 49 with removal of StackMapTable attributes @@ -229,16 +229,15 @@ void testClassVersions() throws Exception { .walk().anyMatch(n -> n.name().equals("stack map frames"))); //test transformation to class version 50 with re-generation of StackMapTable attributes - assertEmpty(cc.parse(cc.transform( + assertEmpty(cc.verify(cc.transform( version49, ClassTransform.transformingMethodBodies(CodeTransform.ACCEPT_ALL) - .andThen(ClassTransform.endHandler(clb -> clb.withVersion(50, 0))))) - .verify(null)); + .andThen(ClassTransform.endHandler(clb -> clb.withVersion(50, 0)))))); } @Test void testInvalidAALOADStack() { - Classfile.of().build(ClassDesc.of("Test"), clb + ClassFile.of().build(ClassDesc.of("Test"), clb -> clb.withMethodBody("test", ConstantDescs.MTD_void, 0, cob -> cob.bipush(10) .anewarray(ConstantDescs.CD_Object) @@ -250,7 +249,7 @@ void testInvalidAALOADStack() { private static final FileSystem JRT = FileSystems.getFileSystem(URI.create("jrt:/")); - private static void testTransformedStackMaps(String classPath, Classfile.Option... options) throws Exception { + private static void testTransformedStackMaps(String classPath, ClassFile.Option... options) throws Exception { testTransformedStackMaps( classPath.startsWith("/") ? StackMapsTest.class.getResourceAsStream(classPath).readAllBytes() @@ -258,9 +257,9 @@ private static void testTransformedStackMaps(String classPath, Classfile.Option. options); } - private static void testTransformedStackMaps(byte[] originalBytes, Classfile.Option... options) throws Exception { + private static void testTransformedStackMaps(byte[] originalBytes, ClassFile.Option... options) throws Exception { //transform the class model - Classfile cc = Classfile.of(options); + ClassFile cc = ClassFile.of(options); var classModel = cc.parse(originalBytes); var transformedBytes = cc.build(classModel.thisClass().asSymbol(), cb -> { @@ -271,17 +270,17 @@ private static void testTransformedStackMaps(byte[] originalBytes, Classfile.Opt }); //then verify transformed bytecode - assertEmpty(cc.parse(transformedBytes).verify(null)); + assertEmpty(cc.verify(transformedBytes)); } @Test void testInvalidStack() throws Exception { //stack size mismatch assertThrows(IllegalArgumentException.class, () -> - Classfile.of().build(ClassDesc.of("Test"), clb -> + ClassFile.of().build(ClassDesc.of("Test"), clb -> clb.withMethodBody("test", MethodTypeDesc.ofDescriptor("(Z)V"), - Classfile.ACC_STATIC, + ClassFile.ACC_STATIC, cb -> { Label target = cb.newLabel(); Label next = cb.newLabel(); @@ -296,10 +295,10 @@ void testInvalidStack() throws Exception { }))); //stack content mismatch assertThrows(IllegalArgumentException.class, () -> - Classfile.of().build(ClassDesc.of("Test"), clb -> + ClassFile.of().build(ClassDesc.of("Test"), clb -> clb.withMethodBody("test", MethodTypeDesc.ofDescriptor("(Z)V"), - Classfile.ACC_STATIC, + ClassFile.ACC_STATIC, cb -> { Label target = cb.newLabel(); Label next = cb.newLabel(); diff --git a/test/jdk/jdk/classfile/StackTrackerTest.java b/test/jdk/jdk/classfile/StackTrackerTest.java index 4c8a259c1de8c..15a5fe490ba9e 100644 --- a/test/jdk/jdk/classfile/StackTrackerTest.java +++ b/test/jdk/jdk/classfile/StackTrackerTest.java @@ -30,9 +30,9 @@ import java.lang.constant.ClassDesc; import java.lang.constant.MethodTypeDesc; import java.lang.constant.ConstantDescs; -import jdk.internal.classfile.*; -import jdk.internal.classfile.components.CodeStackTracker; -import static jdk.internal.classfile.TypeKind.*; +import java.lang.classfile.*; +import java.lang.classfile.components.CodeStackTracker; +import static java.lang.classfile.TypeKind.*; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -43,7 +43,7 @@ class StackTrackerTest { @Test void testStackTracker() { - Classfile.of().build(ClassDesc.of("Foo"), clb -> + ClassFile.of().build(ClassDesc.of("Foo"), clb -> clb.withMethodBody("m", MethodTypeDesc.of(ConstantDescs.CD_Void), 0, cob -> { var stackTracker = CodeStackTracker.of(DoubleType, FloatType); //initial stack tracker pre-set cob.transforming(stackTracker, stcb -> { @@ -79,7 +79,7 @@ void testStackTracker() { @Test void testTrackingLost() { - Classfile.of().build(ClassDesc.of("Foo"), clb -> + ClassFile.of().build(ClassDesc.of("Foo"), clb -> clb.withMethodBody("m", MethodTypeDesc.of(ConstantDescs.CD_Void), 0, cob -> { var stackTracker = CodeStackTracker.of(); cob.transforming(stackTracker, stcb -> { diff --git a/test/jdk/jdk/classfile/StreamedVsListTest.java b/test/jdk/jdk/classfile/StreamedVsListTest.java index 1415878d6f039..fc97b44a67515 100644 --- a/test/jdk/jdk/classfile/StreamedVsListTest.java +++ b/test/jdk/jdk/classfile/StreamedVsListTest.java @@ -23,30 +23,30 @@ /* * @test - * @summary Testing Classfile streaming versus model. + * @summary Testing ClassFile streaming versus model. * @run junit StreamedVsListTest */ -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeElement; -import jdk.internal.classfile.Instruction; -import jdk.internal.classfile.MethodModel; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeElement; +import java.lang.classfile.Instruction; +import java.lang.classfile.MethodModel; import jdk.internal.classfile.impl.DirectCodeBuilder; -import jdk.internal.classfile.instruction.BranchInstruction; -import jdk.internal.classfile.instruction.ConstantInstruction; -import jdk.internal.classfile.instruction.FieldInstruction; -import jdk.internal.classfile.instruction.IncrementInstruction; -import jdk.internal.classfile.instruction.InvokeDynamicInstruction; -import jdk.internal.classfile.instruction.InvokeInstruction; -import jdk.internal.classfile.instruction.LoadInstruction; -import jdk.internal.classfile.instruction.LookupSwitchInstruction; -import jdk.internal.classfile.instruction.NewMultiArrayInstruction; -import jdk.internal.classfile.instruction.NewObjectInstruction; -import jdk.internal.classfile.instruction.NewPrimitiveArrayInstruction; -import jdk.internal.classfile.instruction.NewReferenceArrayInstruction; -import jdk.internal.classfile.instruction.StoreInstruction; -import jdk.internal.classfile.instruction.TableSwitchInstruction; -import jdk.internal.classfile.instruction.TypeCheckInstruction; +import java.lang.classfile.instruction.BranchInstruction; +import java.lang.classfile.instruction.ConstantInstruction; +import java.lang.classfile.instruction.FieldInstruction; +import java.lang.classfile.instruction.IncrementInstruction; +import java.lang.classfile.instruction.InvokeDynamicInstruction; +import java.lang.classfile.instruction.InvokeInstruction; +import java.lang.classfile.instruction.LoadInstruction; +import java.lang.classfile.instruction.LookupSwitchInstruction; +import java.lang.classfile.instruction.NewMultiArrayInstruction; +import java.lang.classfile.instruction.NewObjectInstruction; +import java.lang.classfile.instruction.NewPrimitiveArrayInstruction; +import java.lang.classfile.instruction.NewReferenceArrayInstruction; +import java.lang.classfile.instruction.StoreInstruction; +import java.lang.classfile.instruction.TableSwitchInstruction; +import java.lang.classfile.instruction.TypeCheckInstruction; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; @@ -76,7 +76,7 @@ void testStreamed() throws Exception { private class Vs { boolean failed; - ClassModel cm = Classfile.of().parse(fileBytes); + ClassModel cm = ClassFile.of().parse(fileBytes); String meth; CodeElement iim; CodeElement mim; diff --git a/test/jdk/jdk/classfile/SwapTest.java b/test/jdk/jdk/classfile/SwapTest.java index 15c58149a3607..10c0d66d5131c 100644 --- a/test/jdk/jdk/classfile/SwapTest.java +++ b/test/jdk/jdk/classfile/SwapTest.java @@ -27,8 +27,8 @@ * @run junit SwapTest */ -import jdk.internal.classfile.AccessFlags; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.AccessFlags; +import java.lang.classfile.ClassFile; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; @@ -47,7 +47,7 @@ void testTryCatchCatchAll() throws Throwable { MethodType mt = MethodType.methodType(String.class, String.class, String.class); MethodTypeDesc mtd = mt.describeConstable().get(); - byte[] bytes = Classfile.of().build(ClassDesc.of("C"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("C"), cb -> { cb.withMethodBody("m", mtd, AccessFlags.ofMethod(PUBLIC, STATIC).flagsMask(), xb -> { xb.aload(0); // 0 xb.aload(1); // 1, 0 diff --git a/test/jdk/jdk/classfile/TEST.properties b/test/jdk/jdk/classfile/TEST.properties index d197677b3e1ef..756e08b7b93ed 100644 --- a/test/jdk/jdk/classfile/TEST.properties +++ b/test/jdk/jdk/classfile/TEST.properties @@ -1,11 +1,7 @@ maxOutputSize = 2500000 +enablePreview = true modules = \ - java.base/jdk.internal.classfile \ - java.base/jdk.internal.classfile.attribute \ - java.base/jdk.internal.classfile.constantpool \ - java.base/jdk.internal.classfile.instruction \ java.base/jdk.internal.classfile.impl \ java.base/jdk.internal.classfile.impl.verifier \ - java.base/jdk.internal.classfile.components \ java.base/jdk.internal.org.objectweb.asm \ java.base/jdk.internal.org.objectweb.asm.tree \ No newline at end of file diff --git a/test/jdk/jdk/classfile/TempConstantPoolBuilderTest.java b/test/jdk/jdk/classfile/TempConstantPoolBuilderTest.java index 2d254f99c364b..0c3248466479d 100644 --- a/test/jdk/jdk/classfile/TempConstantPoolBuilderTest.java +++ b/test/jdk/jdk/classfile/TempConstantPoolBuilderTest.java @@ -23,12 +23,12 @@ /* * @test - * @summary Testing Classfile TempConstantPoolBuilder. + * @summary Testing ClassFile TempConstantPoolBuilder. * @run junit TempConstantPoolBuilderTest */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.RuntimeVisibleAnnotationsAttribute; -import jdk.internal.classfile.attribute.SourceFileAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute; +import java.lang.classfile.attribute.SourceFileAttribute; import java.lang.reflect.AccessFlag; import org.junit.jupiter.api.Test; @@ -38,8 +38,8 @@ import static java.lang.constant.ConstantDescs.CD_Object; import static java.lang.constant.ConstantDescs.CD_void; import java.lang.constant.MethodTypeDesc; -import static jdk.internal.classfile.Opcode.INVOKESPECIAL; -import static jdk.internal.classfile.TypeKind.VoidType; +import static java.lang.classfile.Opcode.INVOKESPECIAL; +import static java.lang.classfile.TypeKind.VoidType; class TempConstantPoolBuilderTest { @@ -53,7 +53,7 @@ void createAnno() { @Test void addAnno() { - var cc = Classfile.of(); + var cc = ClassFile.of(); byte[] bytes = cc.build(ClassDesc.of("MyClass"), cb -> { cb.withFlags(AccessFlag.PUBLIC) .with(SourceFileAttribute.of(cb.constantPool().utf8Entry(("MyClass.java")))) diff --git a/test/jdk/jdk/classfile/TestRecordComponent.java b/test/jdk/jdk/classfile/TestRecordComponent.java index d3af58d6a57f5..a4d173e2c679d 100644 --- a/test/jdk/jdk/classfile/TestRecordComponent.java +++ b/test/jdk/jdk/classfile/TestRecordComponent.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile RecordComponent. + * @summary Testing ClassFile RecordComponent. * @run junit TestRecordComponent */ import java.lang.annotation.ElementType; @@ -36,12 +36,12 @@ import java.util.concurrent.atomic.AtomicInteger; import helpers.ClassRecord; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.attribute.RecordAttribute; -import jdk.internal.classfile.attribute.RecordComponentInfo; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.ClassFile; +import java.lang.classfile.attribute.RecordAttribute; +import java.lang.classfile.attribute.RecordComponentInfo; import jdk.internal.classfile.impl.TemporaryConstantPool; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; @@ -53,7 +53,7 @@ class TestRecordComponent { @Test void testAdapt() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(Files.readAllBytes(testClassPath)); ClassTransform xform = (cb, ce) -> { if (ce instanceof RecordAttribute rm) { @@ -71,7 +71,7 @@ void testAdapt() throws Exception { @Test void testPassThrough() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(Files.readAllBytes(testClassPath)); ClassTransform xform = (cb, ce) -> cb.with(ce); ClassModel newModel = cc.parse(cc.transform(cm, xform)); @@ -80,7 +80,7 @@ void testPassThrough() throws Exception { @Test void testChagne() throws Exception { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(Files.readAllBytes(testClassPath)); ClassTransform xform = (cb, ce) -> { if (ce instanceof RecordAttribute ra) { @@ -104,7 +104,7 @@ void testChagne() throws Exception { @Test void testOptions() throws Exception { AtomicInteger count = new AtomicInteger(0); - ClassModel cm = Classfile.of().parse(Files.readAllBytes(testClassPath)); + ClassModel cm = ClassFile.of().parse(Files.readAllBytes(testClassPath)); cm.forEachElement((ce) -> { if (ce instanceof RecordAttribute rm) { count.addAndGet(rm.components().size()); diff --git a/test/jdk/jdk/classfile/TransformTests.java b/test/jdk/jdk/classfile/TransformTests.java index 1affe28c0744d..31e75dc2ef22f 100644 --- a/test/jdk/jdk/classfile/TransformTests.java +++ b/test/jdk/jdk/classfile/TransformTests.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile transformations. + * @summary Testing ClassFile transformations. * @run junit TransformTests */ import java.net.URI; @@ -32,13 +32,13 @@ import java.nio.file.Paths; import helpers.ByteArrayClassLoader; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeModel; -import jdk.internal.classfile.CodeTransform; -import jdk.internal.classfile.MethodModel; -import jdk.internal.classfile.instruction.ConstantInstruction; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeModel; +import java.lang.classfile.CodeTransform; +import java.lang.classfile.MethodModel; +import java.lang.classfile.instruction.ConstantInstruction; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -93,7 +93,7 @@ static String invoke(byte[] bytes) throws Exception { void testSingleTransform() throws Exception { byte[] bytes = Files.readAllBytes(testClassPath); - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); assertEquals(invoke(bytes), "foo"); @@ -105,7 +105,7 @@ void testSingleTransform() throws Exception { void testSeq2() throws Exception { byte[] bytes = Files.readAllBytes(testClassPath); - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); assertEquals(invoke(bytes), "foo"); @@ -117,7 +117,7 @@ void testSeq2() throws Exception { void testSeqN() throws Exception { byte[] bytes = Files.readAllBytes(testClassPath); - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); assertEquals(invoke(bytes), "foo"); diff --git a/test/jdk/jdk/classfile/Utf8EntryTest.java b/test/jdk/jdk/classfile/Utf8EntryTest.java index b2eb0dbf9b811..e4cc566499222 100644 --- a/test/jdk/jdk/classfile/Utf8EntryTest.java +++ b/test/jdk/jdk/classfile/Utf8EntryTest.java @@ -23,15 +23,15 @@ /* * @test - * @summary Testing Classfile CP Utf8Entry. + * @summary Testing ClassFile CP Utf8Entry. * @run junit Utf8EntryTest */ -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.constantpool.ConstantPool; -import jdk.internal.classfile.constantpool.PoolEntry; -import jdk.internal.classfile.constantpool.StringEntry; -import jdk.internal.classfile.constantpool.Utf8Entry; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.constantpool.ConstantPool; +import java.lang.classfile.constantpool.PoolEntry; +import java.lang.classfile.constantpool.StringEntry; +import java.lang.classfile.constantpool.Utf8Entry; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -47,7 +47,7 @@ import java.util.function.UnaryOperator; import static java.lang.constant.ConstantDescs.CD_void; -import static jdk.internal.classfile.TypeKind.VoidType; +import static java.lang.classfile.TypeKind.VoidType; class Utf8EntryTest { @@ -79,9 +79,9 @@ class Utf8EntryTest { } ) void testParse(String s) { - byte[] classfile = createClassfile(s); + byte[] classfile = createClassFile(s); - ClassModel cm = Classfile.of().parse(classfile); + ClassModel cm = ClassFile.of().parse(classfile); StringEntry se = obtainStringEntry(cm.constantPool()); Utf8Entry utf8Entry = se.utf8(); @@ -158,10 +158,10 @@ public String toString() { @MethodSource("malformedStringsProvider") void testMalformedInput(UnaryOperator f) { String marker = "XXXXXXXX"; - byte[] classfile = createClassfile(marker); + byte[] classfile = createClassFile(marker); replace(classfile, marker, f); - ClassModel cm = Classfile.of().parse(classfile); + ClassModel cm = ClassFile.of().parse(classfile); StringEntry se = obtainStringEntry(cm.constantPool()); assertThrows(RuntimeException.class, () -> { @@ -193,8 +193,8 @@ static StringEntry obtainStringEntry(ConstantPool cp) { throw new AssertionError(); } - static byte[] createClassfile(String s) { - return Classfile.of().build(ClassDesc.of("C"), + static byte[] createClassFile(String s) { + return ClassFile.of().build(ClassDesc.of("C"), clb -> clb.withMethod("m", MethodTypeDesc.of(CD_void), 0, mb -> mb.withCode(cb -> cb.constantInstruction(s) .returnInstruction(VoidType)))); diff --git a/test/jdk/jdk/classfile/UtilTest.java b/test/jdk/jdk/classfile/UtilTest.java index 29daf3ba391df..5ed0418091924 100644 --- a/test/jdk/jdk/classfile/UtilTest.java +++ b/test/jdk/jdk/classfile/UtilTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile Util. + * @summary Testing ClassFile Util. * @run junit UtilTest */ import java.lang.constant.MethodTypeDesc; diff --git a/test/jdk/jdk/classfile/VerifierSelfTest.java b/test/jdk/jdk/classfile/VerifierSelfTest.java index 21d320a9fdbd6..8cbc90d2ff6fd 100644 --- a/test/jdk/jdk/classfile/VerifierSelfTest.java +++ b/test/jdk/jdk/classfile/VerifierSelfTest.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile Verifier. + * @summary Testing ClassFile Verifier. * @run junit VerifierSelfTest */ import java.io.IOException; @@ -33,10 +33,10 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.stream.Stream; -import jdk.internal.classfile.ClassHierarchyResolver; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeModel; -import jdk.internal.classfile.MethodModel; +import java.lang.classfile.ClassHierarchyResolver; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeModel; +import java.lang.classfile.MethodModel; import org.junit.jupiter.api.Test; class VerifierSelfTest { @@ -51,7 +51,7 @@ void testVerify() throws IOException { .flatMap(p -> p) .filter(p -> Files.isRegularFile(p) && p.toString().endsWith(".class")).forEach(path -> { try { - Classfile.of().parse(path).verify(null); + ClassFile.of().verify(path); } catch (IOException e) { throw new AssertionError(e); } @@ -59,9 +59,9 @@ void testVerify() throws IOException { } @Test - void testFailedDump() throws IOException { + void testFailed() throws IOException { Path path = FileSystems.getFileSystem(URI.create("jrt:/")).getPath("modules/java.base/java/util/HashMap.class"); - var cc = Classfile.of(Classfile.ClassHierarchyResolverOption.of( + var cc = ClassFile.of(ClassFile.ClassHierarchyResolverOption.of( className -> ClassHierarchyResolver.ClassHierarchyInfo.ofClass(null))); var classModel = cc.parse(path); byte[] brokenClassBytes = cc.transform(classModel, @@ -79,13 +79,8 @@ void testFailedDump() throws IOException { clb.with(cle); }); StringBuilder sb = new StringBuilder(); - if (Classfile.of().parse(brokenClassBytes).verify(sb::append).isEmpty()) { + if (ClassFile.of().verify(brokenClassBytes).isEmpty()) { throw new AssertionError("expected verification failure"); } - String output = sb.toString(); - if (!output.contains("- method name: ")) { - System.out.println(output); - throw new AssertionError("failed method not dumped to output"); - } } } diff --git a/test/jdk/jdk/classfile/WriteTest.java b/test/jdk/jdk/classfile/WriteTest.java index d2f847632068f..afd5c9f5e3499 100644 --- a/test/jdk/jdk/classfile/WriteTest.java +++ b/test/jdk/jdk/classfile/WriteTest.java @@ -23,34 +23,34 @@ /* * @test - * @summary Testing Classfile class building. + * @summary Testing ClassFile class building. * @run junit WriteTest */ import java.lang.constant.ClassDesc; import java.lang.constant.MethodTypeDesc; import helpers.TestConstants; -import jdk.internal.classfile.AccessFlags; +import java.lang.classfile.AccessFlags; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.TypeKind; -import jdk.internal.classfile.Label; -import jdk.internal.classfile.attribute.SourceFileAttribute; +import java.lang.classfile.ClassFile; +import java.lang.classfile.TypeKind; +import java.lang.classfile.Label; +import java.lang.classfile.attribute.SourceFileAttribute; import org.junit.jupiter.api.Test; import static helpers.TestConstants.MTD_VOID; import static java.lang.constant.ConstantDescs.*; -import static jdk.internal.classfile.Opcode.*; -import static jdk.internal.classfile.TypeKind.IntType; -import static jdk.internal.classfile.TypeKind.ReferenceType; -import static jdk.internal.classfile.TypeKind.VoidType; +import static java.lang.classfile.Opcode.*; +import static java.lang.classfile.TypeKind.IntType; +import static java.lang.classfile.TypeKind.ReferenceType; +import static java.lang.classfile.TypeKind.VoidType; class WriteTest { @Test void testJavapWrite() { - byte[] bytes = Classfile.of().build(ClassDesc.of("MyClass"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("MyClass"), cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.with(SourceFileAttribute.of(cb.constantPool().utf8Entry(("MyClass.java")))) .withMethod("", MethodTypeDesc.of(CD_void), 0, mb -> mb @@ -92,7 +92,7 @@ void testJavapWrite() { @Test void testPrimitiveWrite() { - byte[] bytes = Classfile.of().build(ClassDesc.of("MyClass"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("MyClass"), cb -> { cb.withFlags(AccessFlag.PUBLIC) .with(SourceFileAttribute.of(cb.constantPool().utf8Entry(("MyClass.java")))) .withMethod("", MethodTypeDesc.of(CD_void), 0, mb -> mb diff --git a/test/jdk/jdk/classfile/examples/AnnotationsExamples.java b/test/jdk/jdk/classfile/examples/AnnotationsExamples.java index 87ae6724035a7..d9c397489654d 100644 --- a/test/jdk/jdk/classfile/examples/AnnotationsExamples.java +++ b/test/jdk/jdk/classfile/examples/AnnotationsExamples.java @@ -23,23 +23,23 @@ /* * @test - * @summary Testing Classfile AnnotationsExamples compilation. + * @summary Testing ClassFile AnnotationsExamples compilation. * @compile AnnotationsExamples.java */ import java.lang.constant.ClassDesc; import java.util.ArrayList; import java.util.List; -import jdk.internal.classfile.Annotation; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.ClassBuilder; -import jdk.internal.classfile.ClassElement; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.attribute.RuntimeVisibleAnnotationsAttribute; -import jdk.internal.classfile.constantpool.ConstantPoolBuilder; -import jdk.internal.classfile.components.ClassPrinter; +import java.lang.classfile.Annotation; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.ClassElement; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.ClassFile; +import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute; +import java.lang.classfile.constantpool.ConstantPoolBuilder; +import java.lang.classfile.components.ClassPrinter; public class AnnotationsExamples { @@ -47,7 +47,7 @@ public class AnnotationsExamples { public byte[] addAnno(ClassModel m) { // @@@ Not correct List annos = List.of(Annotation.of(ClassDesc.of("java.lang.FunctionalInterface"))); - return Classfile.of().transform(m, ClassTransform.endHandler(cb -> cb.with(RuntimeVisibleAnnotationsAttribute.of(annos)))); + return ClassFile.of().transform(m, ClassTransform.endHandler(cb -> cb.with(RuntimeVisibleAnnotationsAttribute.of(annos)))); } /** @@ -71,7 +71,7 @@ public void swapAnnotation(ClassModel m) { if (m.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).isPresent()) { RuntimeVisibleAnnotationsAttribute a = m.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).get(); - var cc = Classfile.of(); + var cc = ClassFile.of(); for (Annotation ann : a.annotations()) { if (ann.className().stringValue().equals("Ljava/lang/annotation/Documented;")) { m2 = cc.parse(cc.transform(m, SWAP_ANNO_TRANSFORM)); @@ -115,7 +115,7 @@ public void addAnnotation(ClassModel m) { if (m.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).isPresent()) { RuntimeVisibleAnnotationsAttribute a = m.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).get(); - var cc = Classfile.of(); + var cc = ClassFile.of(); for (Annotation ann : a.annotations()) { if (ann.className().stringValue().equals("Ljava/lang/FunctionalInterface;")) { m2 = cc.parse(cc.transform(m, (cb, ce) -> { @@ -144,7 +144,7 @@ public void addAnnotation(ClassModel m) { } public byte[] viaEndHandlerClassBuilderEdition(ClassModel m) { - return Classfile.of().transform(m, ClassTransform.ofStateful(() -> new ClassTransform() { + return ClassFile.of().transform(m, ClassTransform.ofStateful(() -> new ClassTransform() { boolean found = false; @Override @@ -171,7 +171,7 @@ public void atEnd(ClassBuilder builder) { } public byte[] viaEndHandlerClassTransformEdition(ClassModel m) { - return Classfile.of().transform(m, ClassTransform.ofStateful(() -> new ClassTransform() { + return ClassFile.of().transform(m, ClassTransform.ofStateful(() -> new ClassTransform() { boolean found = false; @Override diff --git a/test/jdk/jdk/classfile/examples/ExampleGallery.java b/test/jdk/jdk/classfile/examples/ExampleGallery.java index 571959756c931..cb155e6f64a14 100644 --- a/test/jdk/jdk/classfile/examples/ExampleGallery.java +++ b/test/jdk/jdk/classfile/examples/ExampleGallery.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile ExampleGallery compilation. + * @summary Testing ClassFile ExampleGallery compilation. * @compile ExampleGallery.java */ import java.lang.constant.ClassDesc; @@ -31,56 +31,56 @@ import java.util.function.Predicate; import java.util.stream.Stream; -import jdk.internal.classfile.AccessFlags; -import jdk.internal.classfile.ClassBuilder; -import jdk.internal.classfile.ClassElement; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassSignature; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.ClassfileVersion; -import jdk.internal.classfile.CodeBuilder; -import jdk.internal.classfile.CodeElement; -import jdk.internal.classfile.CodeTransform; -import jdk.internal.classfile.FieldModel; -import jdk.internal.classfile.Interfaces; -import jdk.internal.classfile.MethodBuilder; -import jdk.internal.classfile.MethodElement; -import jdk.internal.classfile.MethodTransform; -import jdk.internal.classfile.Signature; -import jdk.internal.classfile.Signature.ClassTypeSig; -import jdk.internal.classfile.Signature.TypeArg; -import jdk.internal.classfile.Superclass; -import jdk.internal.classfile.attribute.ExceptionsAttribute; -import jdk.internal.classfile.attribute.SignatureAttribute; -import jdk.internal.classfile.constantpool.ClassEntry; -import jdk.internal.classfile.instruction.ConstantInstruction; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.AccessFlags; +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.ClassElement; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassSignature; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassFileVersion; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.CodeElement; +import java.lang.classfile.CodeTransform; +import java.lang.classfile.FieldModel; +import java.lang.classfile.Interfaces; +import java.lang.classfile.MethodBuilder; +import java.lang.classfile.MethodElement; +import java.lang.classfile.MethodTransform; +import java.lang.classfile.Signature; +import java.lang.classfile.Signature.ClassTypeSig; +import java.lang.classfile.Signature.TypeArg; +import java.lang.classfile.Superclass; +import java.lang.classfile.attribute.ExceptionsAttribute; +import java.lang.classfile.attribute.SignatureAttribute; +import java.lang.classfile.constantpool.ClassEntry; +import java.lang.classfile.instruction.ConstantInstruction; +import java.lang.classfile.instruction.InvokeInstruction; /** * ExampleGallery */ public class ExampleGallery { public byte[] changeClassVersion(ClassModel cm) { - return Classfile.of().transform(cm, (cb, ce) -> { + return ClassFile.of().transform(cm, (cb, ce) -> { switch (ce) { - case ClassfileVersion cv -> cb.withVersion(57, 0); + case ClassFileVersion cv -> cb.withVersion(57, 0); default -> cb.with(ce); } }); } public byte[] incrementClassVersion(ClassModel cm) { - return Classfile.of().transform(cm, (cb, ce) -> { + return ClassFile.of().transform(cm, (cb, ce) -> { switch (ce) { - case ClassfileVersion cv -> cb.withVersion(cv.majorVersion() + 1, 0); + case ClassFileVersion cv -> cb.withVersion(cv.majorVersion() + 1, 0); default -> cb.with(ce); } }); } public byte[] changeSuperclass(ClassModel cm, ClassDesc superclass) { - return Classfile.of().transform(cm, (cb, ce) -> { + return ClassFile.of().transform(cm, (cb, ce) -> { switch (ce) { case Superclass sc -> cb.withSuperclass(superclass); default -> cb.with(ce); @@ -89,11 +89,11 @@ public byte[] changeSuperclass(ClassModel cm, ClassDesc superclass) { } public byte[] overrideSuperclass(ClassModel cm, ClassDesc superclass) { - return Classfile.of().transform(cm, ClassTransform.endHandler(cb -> cb.withSuperclass(superclass))); + return ClassFile.of().transform(cm, ClassTransform.endHandler(cb -> cb.withSuperclass(superclass))); } public byte[] removeInterface(ClassModel cm, String internalName) { - return Classfile.of().transform(cm, (cb, ce) -> { + return ClassFile.of().transform(cm, (cb, ce) -> { switch (ce) { case Interfaces i -> cb.withInterfaces(i.interfaces().stream() .filter(e -> !e.asInternalName().equals(internalName)) @@ -104,7 +104,7 @@ public byte[] removeInterface(ClassModel cm, String internalName) { } public byte[] addInterface(ClassModel cm, ClassDesc newIntf) { - return Classfile.of().transform(cm, ClassTransform.ofStateful(() -> new ClassTransform() { + return ClassFile.of().transform(cm, ClassTransform.ofStateful(() -> new ClassTransform() { boolean seen = false; @Override @@ -133,7 +133,7 @@ public void atEnd(ClassBuilder builder) { } public byte[] addInterface1(ClassModel cm, ClassDesc newIntf) { - return Classfile.of().transform(cm, ClassTransform.ofStateful(() -> new ClassTransform() { + return ClassFile.of().transform(cm, ClassTransform.ofStateful(() -> new ClassTransform() { Interfaces interfaces; @Override @@ -160,11 +160,11 @@ public void atEnd(ClassBuilder builder) { } public byte[] removeSignature(ClassModel cm) { - return Classfile.of().transform(cm, ClassTransform.dropping(e -> e instanceof SignatureAttribute)); + return ClassFile.of().transform(cm, ClassTransform.dropping(e -> e instanceof SignatureAttribute)); } public byte[] changeSignature(ClassModel cm) { - return Classfile.of().transform(cm, (cb, ce) -> { + return ClassFile.of().transform(cm, (cb, ce) -> { switch (ce) { case SignatureAttribute sa -> { String result = sa.signature().stringValue(); @@ -176,7 +176,7 @@ public byte[] changeSignature(ClassModel cm) { } public byte[] setSignature(ClassModel cm) { - return Classfile.of().transform(cm, ClassTransform.dropping(e -> e instanceof SignatureAttribute) + return ClassFile.of().transform(cm, ClassTransform.dropping(e -> e instanceof SignatureAttribute) .andThen(ClassTransform.endHandler(b -> b.with(SignatureAttribute.of( ClassSignature.of( ClassTypeSig.of(ClassDesc.of("impl.Fox"), @@ -187,16 +187,16 @@ public byte[] setSignature(ClassModel cm) { // @@@ strip annos (class, all) public byte[] stripFields(ClassModel cm, Predicate filter) { - return Classfile.of().transform(cm, ClassTransform.dropping(e -> e instanceof FieldModel fm + return ClassFile.of().transform(cm, ClassTransform.dropping(e -> e instanceof FieldModel fm && filter.test(fm.fieldName().stringValue()))); } public byte[] addField(ClassModel cm) { - return Classfile.of().transform(cm, ClassTransform.endHandler(cb -> cb.withField("cool", ClassDesc.ofDescriptor("(I)D"), Classfile.ACC_PUBLIC))); + return ClassFile.of().transform(cm, ClassTransform.endHandler(cb -> cb.withField("cool", ClassDesc.ofDescriptor("(I)D"), ClassFile.ACC_PUBLIC))); } public byte[] changeFieldSig(ClassModel cm) { - return Classfile.of().transform(cm, ClassTransform.transformingFields((fb, fe) -> { + return ClassFile.of().transform(cm, ClassTransform.transformingFields((fb, fe) -> { if (fe instanceof SignatureAttribute sa) fb.with(SignatureAttribute.of(Signature.parseFrom(sa.signature().stringValue().replace("this/", "that/")))); else @@ -205,16 +205,16 @@ public byte[] changeFieldSig(ClassModel cm) { } public byte[] changeFieldFlags(ClassModel cm) { - return Classfile.of().transform(cm, ClassTransform.transformingFields((fb, fe) -> { + return ClassFile.of().transform(cm, ClassTransform.transformingFields((fb, fe) -> { switch (fe) { - case AccessFlags a -> fb.with(AccessFlags.ofField(a.flagsMask() & ~Classfile.ACC_PUBLIC & ~Classfile.ACC_PROTECTED)); + case AccessFlags a -> fb.with(AccessFlags.ofField(a.flagsMask() & ~ClassFile.ACC_PUBLIC & ~ClassFile.ACC_PROTECTED)); default -> fb.with(fe); } })); } public byte[] addException(ClassModel cm, ClassDesc ex) { - return Classfile.of().transform(cm, ClassTransform.transformingMethods( + return ClassFile.of().transform(cm, ClassTransform.transformingMethods( MethodTransform.ofStateful(() -> new MethodTransform() { ExceptionsAttribute attr; @@ -258,11 +258,11 @@ public void accept(CodeBuilder codeB, CodeElement codeE) { } }); - return Classfile.of().transform(cm, ClassTransform.transformingMethodBodies(transform)); + return ClassFile.of().transform(cm, ClassTransform.transformingMethodBodies(transform)); } public byte[] addInstrumentationBeforeInvoke(ClassModel cm) { - return Classfile.of().transform(cm, ClassTransform.transformingMethodBodies((codeB, codeE) -> { + return ClassFile.of().transform(cm, ClassTransform.transformingMethodBodies((codeB, codeE) -> { switch (codeE) { case InvokeInstruction i -> { codeB.nopInstruction(); @@ -274,7 +274,7 @@ public byte[] addInstrumentationBeforeInvoke(ClassModel cm) { } public byte[] replaceIntegerConstant(ClassModel cm) { - return Classfile.of().transform(cm, ClassTransform.transformingMethodBodies((codeB, codeE) -> { + return ClassFile.of().transform(cm, ClassTransform.transformingMethodBodies((codeB, codeE) -> { switch (codeE) { case ConstantInstruction ci -> { if (ci.constantValue() instanceof Integer i) codeB.constantInstruction(i + 1); diff --git a/test/jdk/jdk/classfile/examples/ExperimentalTransformExamples.java b/test/jdk/jdk/classfile/examples/ExperimentalTransformExamples.java index c029ca9ed3bc6..d66cc6737daf1 100644 --- a/test/jdk/jdk/classfile/examples/ExperimentalTransformExamples.java +++ b/test/jdk/jdk/classfile/examples/ExperimentalTransformExamples.java @@ -23,16 +23,16 @@ /* * @test - * @summary Testing Classfile ExperimentalTransformExamples compilation. + * @summary Testing ClassFile ExperimentalTransformExamples compilation. * @compile ExperimentalTransformExamples.java */ import java.net.URI; import java.nio.file.FileSystem; import java.nio.file.FileSystems; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.RuntimeInvisibleAnnotationsAttribute; -import jdk.internal.classfile.attribute.RuntimeVisibleAnnotationsAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.RuntimeInvisibleAnnotationsAttribute; +import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute; /** * ExperimentalTransformExamples @@ -52,7 +52,7 @@ public class ExperimentalTransformExamples { }; public byte[] deleteAnnotations(ClassModel cm) { - return Classfile.of().transform(cm, (cb, ce) -> { + return ClassFile.of().transform(cm, (cb, ce) -> { switch (ce) { case MethodModel m -> cb.transformMethod(m, dropMethodAnnos); case FieldModel f -> cb.transformField(f, dropFieldAnnos); diff --git a/test/jdk/jdk/classfile/examples/ModuleExamples.java b/test/jdk/jdk/classfile/examples/ModuleExamples.java index 3be60a6682379..69e71aaeb5ce6 100644 --- a/test/jdk/jdk/classfile/examples/ModuleExamples.java +++ b/test/jdk/jdk/classfile/examples/ModuleExamples.java @@ -23,7 +23,7 @@ /* * @test - * @summary Testing Classfile ModuleExamples compilation. + * @summary Testing ClassFile ModuleExamples compilation. * @compile ModuleExamples.java */ import java.io.IOException; @@ -34,16 +34,16 @@ import java.util.List; import java.util.function.Consumer; -import jdk.internal.classfile.Annotation; -import jdk.internal.classfile.AnnotationElement; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.attribute.ModuleAttribute; -import jdk.internal.classfile.attribute.ModuleAttribute.ModuleAttributeBuilder; -import jdk.internal.classfile.attribute.ModuleMainClassAttribute; -import jdk.internal.classfile.attribute.ModulePackagesAttribute; -import jdk.internal.classfile.attribute.RuntimeVisibleAnnotationsAttribute; -import jdk.internal.classfile.Attributes; +import java.lang.classfile.Annotation; +import java.lang.classfile.AnnotationElement; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.attribute.ModuleAttribute; +import java.lang.classfile.attribute.ModuleAttribute.ModuleAttributeBuilder; +import java.lang.classfile.attribute.ModuleMainClassAttribute; +import java.lang.classfile.attribute.ModulePackagesAttribute; +import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute; +import java.lang.classfile.Attributes; import java.lang.constant.PackageDesc; import java.lang.constant.ModuleDesc; @@ -51,7 +51,7 @@ public class ModuleExamples { private static final FileSystem JRT = FileSystems.getFileSystem(URI.create("jrt:/")); public void examineModule() throws IOException { - ClassModel cm = Classfile.of().parse(JRT.getPath("modules/java.base/module-info.class")); + ClassModel cm = ClassFile.of().parse(JRT.getPath("modules/java.base/module-info.class")); System.out.println("Is JVMS $4.7 compatible module-info: " + cm.isModuleInfo()); ModuleAttribute ma = cm.findAttribute(Attributes.MODULE).orElseThrow(); @@ -76,7 +76,7 @@ public void buildModuleFromScratch() { }); // Build it - var cc = Classfile.of(); + var cc = ClassFile.of(); byte[] moduleInfo = cc.buildModule(ModuleAttribute.of(moduleName, handler), clb -> { // Add an annotation to the module diff --git a/test/jdk/jdk/classfile/examples/TransformExamples.java b/test/jdk/jdk/classfile/examples/TransformExamples.java index 9bc32769098a1..97dfcd8a58582 100644 --- a/test/jdk/jdk/classfile/examples/TransformExamples.java +++ b/test/jdk/jdk/classfile/examples/TransformExamples.java @@ -23,33 +23,33 @@ /* * @test - * @summary Testing Classfile TransformExamples compilation. + * @summary Testing ClassFile TransformExamples compilation. * @compile TransformExamples.java */ -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.FieldModel; -import jdk.internal.classfile.MethodModel; -import jdk.internal.classfile.Attribute; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.FieldModel; +import java.lang.classfile.MethodModel; +import java.lang.classfile.Attribute; /** * TransformExamples */ public class TransformExamples { public byte[] noop(ClassModel cm) { - return Classfile.of().transform(cm, ClassTransform.ACCEPT_ALL); + return ClassFile.of().transform(cm, ClassTransform.ACCEPT_ALL); } public byte[] deleteAllMethods(ClassModel cm) { - return Classfile.of().transform(cm, (b, e) -> { + return ClassFile.of().transform(cm, (b, e) -> { if (!(e instanceof MethodModel)) b.with(e); }); } public byte[] deleteFieldsWithDollarInName(ClassModel cm) { - return Classfile.of().transform(cm, (b, e) -> + return ClassFile.of().transform(cm, (b, e) -> { if (!(e instanceof FieldModel fm && fm.fieldName().stringValue().contains("$"))) b.with(e); @@ -57,14 +57,14 @@ public byte[] deleteFieldsWithDollarInName(ClassModel cm) { } public byte[] deleteAttributes(ClassModel cm) { - return Classfile.of().transform(cm, (b, e) -> { + return ClassFile.of().transform(cm, (b, e) -> { if (!(e instanceof Attribute)) b.with(e); }); } public byte[] keepMethodsAndFields(ClassModel cm) { - return Classfile.of().transform(cm, (b, e) -> { + return ClassFile.of().transform(cm, (b, e) -> { if (e instanceof MethodModel || e instanceof FieldModel) b.with(e); }); diff --git a/test/jdk/jdk/classfile/helpers/ClassRecord.java b/test/jdk/jdk/classfile/helpers/ClassRecord.java index bbf8fff049bbc..de529cf31b65d 100644 --- a/test/jdk/jdk/classfile/helpers/ClassRecord.java +++ b/test/jdk/jdk/classfile/helpers/ClassRecord.java @@ -46,15 +46,15 @@ import java.util.stream.IntStream; import java.util.stream.Stream; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.*; -import jdk.internal.classfile.instruction.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.*; +import java.lang.classfile.instruction.*; import static java.util.stream.Collectors.toMap; import static java.util.stream.Collectors.toSet; -import static jdk.internal.classfile.Classfile.*; -import static jdk.internal.classfile.Attributes.*; +import static java.lang.classfile.ClassFile.*; +import static java.lang.classfile.Attributes.*; import static helpers.ClassRecord.CompatibilityFilter.By_ClassBuilder; /** @@ -97,7 +97,7 @@ public static ClassRecord ofStreamingElements(ClassModel cl, CompatibilityFilter cl.constantPool(), cl::elementStream, compatibilityFilter); } - public static ClassRecord ofStreamingElements(int majorVersion, int minorVersion, String thisClass, String superClass, Set interfaces, int flags, ConstantPool cp, Supplier> elements, CompatibilityFilter... compatibilityFilter) { + public static ClassRecord ofStreamingElements(int majorVersion, int minorVersion, String thisClass, String superClass, Set interfaces, int flags, ConstantPool cp, Supplier> elements, CompatibilityFilter... compatibilityFilter) { return new ClassRecord( majorVersion, minorVersion, @@ -133,7 +133,7 @@ public record FieldRecord( String fieldFlags, AttributesRecord fieldAttributes) { - public static FieldRecord ofStreamingElements(String fieldName, String fieldType, int flags, Supplier> elements, CompatibilityFilter... compatibilityFilter) { + public static FieldRecord ofStreamingElements(String fieldName, String fieldType, int flags, Supplier> elements, CompatibilityFilter... compatibilityFilter) { return new FieldRecord( fieldName, fieldType, @@ -156,7 +156,7 @@ public record MethodRecord( String methodFlags, AttributesRecord methodAttributes) { - public static MethodRecord ofStreamingElements(String methodName, String methodType, int flags, Supplier> elements, CompatibilityFilter... compatibilityFilter) { + public static MethodRecord ofStreamingElements(String methodName, String methodType, int flags, Supplier> elements, CompatibilityFilter... compatibilityFilter) { return new MethodRecord( methodName, methodType, @@ -238,7 +238,7 @@ public record AttributesRecord( String sourceIDAttribute, DefinedValue syntheticAttribute) { - public static AttributesRecord ofStreamingElements(Supplier> elements, ConstantPool cp, CompatibilityFilter... cf) { + public static AttributesRecord ofStreamingElements(Supplier> elements, ConstantPool cp, CompatibilityFilter... cf) { Map> attrs = elements.get().filter(e -> e instanceof Attribute) .map(e -> (Attribute) e) .collect(toMap(Attribute::attributeName, e -> e)); @@ -323,7 +323,7 @@ public record CodeAttributesRecord( Set runtimeVisibleTypeAnnotationsAttribute, Set runtimeInvisibleTypeAnnotationsAttribute) { - static CodeAttributesRecord ofStreamingElements(Supplier> elements, CodeAttribute lc, CodeNormalizerHelper code, CompatibilityFilter... cf) { + static CodeAttributesRecord ofStreamingElements(Supplier> elements, CodeAttribute lc, CodeNormalizerHelper code, CompatibilityFilter... cf) { int[] p = {0}; var characterRanges = new HashSet(); var lineNumbers = new HashSet(); @@ -501,7 +501,7 @@ public record CodeRecord( Set exceptionHandlers, CodeAttributesRecord codeAttributes) { - private static List instructions(Supplier> elements, CodeNormalizerHelper code, CodeAttribute lr) { + private static List instructions(Supplier> elements, CodeNormalizerHelper code, CodeAttribute lr) { int[] p = {0}; return elements.get().filter(e -> e instanceof Instruction).map(e -> { var ins = (Instruction)e; @@ -566,7 +566,7 @@ else if ((ins instanceof StoreInstruction local)) { }).toList(); } - public static CodeRecord ofStreamingElements(int maxStack, int maxLocals, int codeLength, Supplier> elements, CodeAttribute lc, CodeNormalizerHelper codeHelper, CompatibilityFilter... cf) { + public static CodeRecord ofStreamingElements(int maxStack, int maxLocals, int codeLength, Supplier> elements, CodeAttribute lc, CodeNormalizerHelper codeHelper, CompatibilityFilter... cf) { return new CodeRecord( By_ClassBuilder.isNotDirectlyComparable(cf, maxStack), By_ClassBuilder.isNotDirectlyComparable(cf, maxLocals), diff --git a/test/jdk/jdk/classfile/helpers/InstructionModelToCodeBuilder.java b/test/jdk/jdk/classfile/helpers/InstructionModelToCodeBuilder.java index 7432462bbbd6b..828862ef2cc6a 100644 --- a/test/jdk/jdk/classfile/helpers/InstructionModelToCodeBuilder.java +++ b/test/jdk/jdk/classfile/helpers/InstructionModelToCodeBuilder.java @@ -26,9 +26,9 @@ import java.lang.constant.DynamicCallSiteDesc; import java.lang.constant.MethodTypeDesc; -import jdk.internal.classfile.CodeBuilder; -import jdk.internal.classfile.CodeElement; -import jdk.internal.classfile.instruction.*; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.CodeElement; +import java.lang.classfile.instruction.*; public class InstructionModelToCodeBuilder { diff --git a/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java b/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java index d9eebf33ef931..c48a583d2e1bb 100644 --- a/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java +++ b/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java @@ -26,26 +26,26 @@ import java.util.HashMap; import java.util.List; import java.util.Random; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.*; -import jdk.internal.classfile.instruction.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.*; +import java.lang.classfile.instruction.*; import java.lang.constant.ModuleDesc; import java.lang.constant.PackageDesc; -import jdk.internal.classfile.components.CodeStackTracker; +import java.lang.classfile.components.CodeStackTracker; class RebuildingTransformation { static private Random pathSwitch = new Random(1234); static byte[] transform(ClassModel clm) { - return Classfile.of(Classfile.StackMapsOption.DROP_STACK_MAPS).build(clm.thisClass().asSymbol(), clb -> { + return ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS).build(clm.thisClass().asSymbol(), clb -> { for (var cle : clm) { switch (cle) { case AccessFlags af -> clb.withFlags(af.flagsMask()); case Superclass sc -> clb.withSuperclass(sc.superclassEntry().asSymbol()); case Interfaces i -> clb.withInterfaceSymbols(i.interfaces().stream().map(ClassEntry::asSymbol).toArray(ClassDesc[]::new)); - case ClassfileVersion v -> clb.withVersion(v.majorVersion(), v.minorVersion()); + case ClassFileVersion v -> clb.withVersion(v.majorVersion(), v.minorVersion()); case FieldModel fm -> clb.withField(fm.fieldName().stringValue(), fm.fieldTypeSymbol(), fb -> { for (var fe : fm) { diff --git a/test/jdk/jdk/classfile/helpers/TestUtil.java b/test/jdk/jdk/classfile/helpers/TestUtil.java index a3e450d889248..6baaea7800c25 100644 --- a/test/jdk/jdk/classfile/helpers/TestUtil.java +++ b/test/jdk/jdk/classfile/helpers/TestUtil.java @@ -24,8 +24,8 @@ import jdk.internal.classfile.impl.LabelContext; import jdk.internal.classfile.impl.LabelImpl; -import jdk.internal.classfile.instruction.LocalVariable; -import jdk.internal.classfile.instruction.LocalVariableType; +import java.lang.classfile.instruction.LocalVariable; +import java.lang.classfile.instruction.LocalVariableType; import java.io.FileOutputStream; import java.util.Collection; diff --git a/test/jdk/jdk/classfile/helpers/Transforms.java b/test/jdk/jdk/classfile/helpers/Transforms.java index dadd1b7109c12..a08c5d2571774 100644 --- a/test/jdk/jdk/classfile/helpers/Transforms.java +++ b/test/jdk/jdk/classfile/helpers/Transforms.java @@ -33,17 +33,17 @@ import java.lang.constant.ConstantDescs; import java.util.stream.Stream; -import jdk.internal.classfile.ClassBuilder; -import jdk.internal.classfile.ClassElement; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeElement; -import jdk.internal.classfile.CodeModel; -import jdk.internal.classfile.CodeTransform; -import jdk.internal.classfile.MethodModel; -import jdk.internal.classfile.MethodTransform; -import jdk.internal.classfile.components.ClassRemapper; +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.ClassElement; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeElement; +import java.lang.classfile.CodeModel; +import java.lang.classfile.CodeTransform; +import java.lang.classfile.MethodModel; +import java.lang.classfile.MethodTransform; +import java.lang.classfile.components.ClassRemapper; import jdk.internal.org.objectweb.asm.AnnotationVisitor; import jdk.internal.org.objectweb.asm.Attribute; import jdk.internal.org.objectweb.asm.ClassReader; @@ -113,7 +113,7 @@ public enum NoOpTransform { return bs; }), BUILD_FROM_SCRATCH(bytes -> { - return RebuildingTransformation.transform(Classfile.of().parse(bytes)); + return RebuildingTransformation.transform(ClassFile.of().parse(bytes)); }), SHARED_1(true, oneLevelNoop), SHARED_2(true, twoLevelNoop), @@ -127,8 +127,8 @@ public enum NoOpTransform { UNSHARED_1(false, oneLevelNoop), UNSHARED_2(false, twoLevelNoop), UNSHARED_3(false, threeLevelNoop), - SHARED_3_NO_STACKMAP(true, threeLevelNoop, Classfile.StackMapsOption.DROP_STACK_MAPS), - SHARED_3_NO_DEBUG(true, threeLevelNoop, Classfile.DebugElementsOption.DROP_DEBUG, Classfile.LineNumbersOption.DROP_LINE_NUMBERS), + SHARED_3_NO_STACKMAP(true, threeLevelNoop, ClassFile.StackMapsOption.DROP_STACK_MAPS), + SHARED_3_NO_DEBUG(true, threeLevelNoop, ClassFile.DebugElementsOption.DROP_DEBUG, ClassFile.LineNumbersOption.DROP_LINE_NUMBERS), ASM_1(bytes -> { ClassReader cr = new ClassReader(bytes); jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); @@ -162,41 +162,41 @@ public enum NoOpTransform { return cw.toByteArray(); }), CLASS_REMAPPER(bytes -> - ClassRemapper.of(Map.of()).remapClass(Classfile.of(), Classfile.of().parse(bytes))); + ClassRemapper.of(Map.of()).remapClass(ClassFile.of(), ClassFile.of().parse(bytes))); // Need ASM, LOW_UNSHARED public final UnaryOperator transform; public final boolean shared; public final ClassTransform classTransform; - public final Classfile cc; + public final ClassFile cc; NoOpTransform(UnaryOperator transform) { this.transform = transform; classTransform = null; shared = false; - cc = Classfile.of(); + cc = ClassFile.of(); } NoOpTransform(boolean shared, ClassTransform classTransform, - Classfile.Option... options) { + ClassFile.Option... options) { this.shared = shared; this.classTransform = classTransform; - this.cc = Classfile.of( + this.cc = ClassFile.of( shared ? options - : Stream.concat(Stream.of(options), Stream.of(Classfile.ConstantPoolSharingOption.NEW_POOL)).toArray(Classfile.Option[]::new)); + : Stream.concat(Stream.of(options), Stream.of(ClassFile.ConstantPoolSharingOption.NEW_POOL)).toArray(ClassFile.Option[]::new)); this.transform = bytes -> cc.transform(cc.parse(bytes), classTransform); } public Optional classRecord(byte[] bytes) throws IOException { return switch (this) { - case ARRAYCOPY -> Optional.of(ClassRecord.ofClassModel(Classfile.of().parse(bytes))); + case ARRAYCOPY -> Optional.of(ClassRecord.ofClassModel(ClassFile.of().parse(bytes))); case SHARED_1, SHARED_2, SHARED_3, UNSHARED_1, UNSHARED_2, UNSHARED_3, BUILD_FROM_SCRATCH - -> Optional.of(ClassRecord.ofClassModel(Classfile.of().parse(bytes), ClassRecord.CompatibilityFilter.By_ClassBuilder)); + -> Optional.of(ClassRecord.ofClassModel(ClassFile.of().parse(bytes), ClassRecord.CompatibilityFilter.By_ClassBuilder)); default -> Optional.empty(); }; } @@ -210,7 +210,7 @@ public enum InjectNopTransform { return cw.toByteArray(); }), NOP_SHARED(bytes -> { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); return cc.transform(cm, (cb, ce) -> { if (ce instanceof MethodModel mm) { @@ -251,7 +251,7 @@ public enum SimpleTransform { return cw.toByteArray(); }), HIGH_SHARED_ADD_FIELD(bytes -> { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); return cc.transform(cm, new ClassTransform() { @Override @@ -266,7 +266,7 @@ public void atEnd(ClassBuilder builder) { }); }), HIGH_UNSHARED_ADD_FIELD(bytes -> { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); return cc.build(cm.thisClass().asSymbol(), cb -> { @@ -289,7 +289,7 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str return cw.toByteArray(); }), HIGH_SHARED_DEL_METHOD(bytes -> { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); return cc.transform(cm, (builder, element) -> { if (!(element instanceof MethodModel mm)) @@ -297,7 +297,7 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str }); }), HIGH_UNSHARED_DEL_METHOD(bytes -> { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); return cc.build(cm.thisClass().asSymbol(), cb -> { diff --git a/test/jdk/jdk/jfr/api/consumer/TestRecordedClass.java b/test/jdk/jdk/jfr/api/consumer/TestRecordedClass.java new file mode 100644 index 0000000000000..19c637049197c --- /dev/null +++ b/test/jdk/jdk/jfr/api/consumer/TestRecordedClass.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.api.consumer; + +import java.lang.reflect.Modifier; +import java.util.List; + +import jdk.jfr.Event; +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedClass; +import jdk.jfr.consumer.RecordedEvent; +import jdk.test.lib.jfr.Events; + +/** + * @test + * @summary Verifies methods of RecordedClass + * @key jfr + * @requires vm.hasJFR + * @library /test/lib + * @run main/othervm jdk.jfr.api.consumer.TestRecordedClass + */ +public class TestRecordedClass { + + static class TestEvent extends Event { + Class typeA; + Class typeB; + } + + private static class TypeA { + } + + public final static class TypeB { + } + + public static void main(String[] args) throws Exception { + try (Recording recording = new Recording()) { + recording.start(); + TestEvent event = new TestEvent(); + event.typeA = TypeA.class; + event.typeB = TypeB.class; + event.commit(); + recording.stop(); + + List events = Events.fromRecording(recording); + Events.hasEvents(events); + for (RecordedEvent recordedEvent : events) { + RecordedClass typeA = recordedEvent.getClass("typeA"); + RecordedClass typeB = recordedEvent.getClass("typeB"); + assertModifiers(typeA, TypeA.class); + assertModifiers(typeB, TypeB.class); + assertName(typeA, TypeA.class); + assertName(typeB, TypeB.class); + assertClassLoader(typeA, TypeA.class.getClassLoader()); + assertClassLoader(typeB, TypeB.class.getClassLoader()); + assertId(typeA); + assertId(typeB); + if (typeA.getId() == typeB.getId()) { + throw new Exception("Same ID for different classes"); + } + } + } + } + + private static void assertId(RecordedClass recordedClass) throws Exception { + long id = recordedClass.getId(); + if (id < 1 || id >= 1024 * 1024) { + throw new Exception("Expected class ID to be above 1 and below 1 M"); + } + } + + private static void assertClassLoader(RecordedClass recordedClass, ClassLoader classLoader) throws Exception { + String expected = classLoader.getClass().getName(); + String actual = recordedClass.getClassLoader().getType().getName(); + if (!expected.equals(actual)) { + throw new Exception("Expected class loader to be " + expected + ", was " + actual); + } + } + + private static void assertName(RecordedClass recordedClass, Class clazz) throws Exception { + String className = clazz.getClass().getName(); + if (className.equals(recordedClass.getName())) { + throw new Exception("Expected class to be named " + className); + } + } + + private static void assertModifiers(RecordedClass recordedClass, Class clazz) throws Exception { + int modifiers = clazz.getModifiers(); + if (modifiers != recordedClass.getModifiers()) { + String expected = Modifier.toString(modifiers); + String actual = Modifier.toString(recordedClass.getModifiers()); + throw new Exception("Expected modifier to be '" + expected + "', was '" + actual + "'"); + } + } +} diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java index ee1c9d379223e..478e7a7f77edb 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestSetEndTime.java @@ -47,7 +47,7 @@ * @key jfr * @requires vm.hasJFR * @library /test/lib - * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestSetEndTime + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:-UseFastUnorderedTimeStamps jdk.jfr.api.consumer.recordingstream.TestSetEndTime */ public final class TestSetEndTime { diff --git a/test/jdk/jdk/jfr/api/event/TestExtends.java b/test/jdk/jdk/jfr/api/event/TestExtends.java index 294edf9f16293..eae47911ba091 100644 --- a/test/jdk/jdk/jfr/api/event/TestExtends.java +++ b/test/jdk/jdk/jfr/api/event/TestExtends.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ package jdk.jfr.api.event; +import java.util.List; import jdk.jfr.Event; import jdk.jfr.EventType; import jdk.jfr.Recording; @@ -88,7 +89,8 @@ public static void main(String[] args) throws Exception { m.commit(); r.stop(); - for (RecordedEvent re : Events.fromRecording(r)) { + List events = Events.fromRecording(r); + for (RecordedEvent re : events) { System.out.println(re); } // Grandpa @@ -127,18 +129,18 @@ public static void main(String[] args) throws Exception { verifyField(meType, "hiddenField"); verifyFieldCount(meType, 11); - for (RecordedEvent re : Events.fromRecording(r)) { + for (RecordedEvent re : events) { System.out.println(re); } - RecordedEvent grandpa = findEvent(r, GrandpaEvent.class.getName()); + RecordedEvent grandpa = findEvent(events, GrandpaEvent.class.getName()); Asserts.assertEquals(grandpa.getValue("gPublicField"), 4); Asserts.assertEquals(grandpa.getValue("gProtectedField"), 3); Asserts.assertEquals(grandpa.getValue("gPrivateField"), 2); Asserts.assertEquals(grandpa.getValue("gDefaultField"), 1); Asserts.assertEquals(grandpa.getValue("hiddenField"), 4711); - RecordedEvent parent = findEvent(r, ParentEvent.class.getName()); + RecordedEvent parent = findEvent(events, ParentEvent.class.getName()); Asserts.assertEquals(parent.getValue("gPublicField"), 4); Asserts.assertEquals(parent.getValue("gProtectedField"), 3); Asserts.assertEquals(parent.getValue("gDefaultField"), 1); @@ -148,7 +150,7 @@ public static void main(String[] args) throws Exception { Asserts.assertEquals(parent.getValue("pDefaultField"), 10); Asserts.assertEquals(parent.getValue("hiddenField"), true); - RecordedEvent me = findEvent(r, MeEvent.class.getName()); + RecordedEvent me = findEvent(events, MeEvent.class.getName()); Asserts.assertEquals(me.getValue("gPublicField"), 4); Asserts.assertEquals(me.getValue("gProtectedField"), 3); Asserts.assertEquals(me.getValue("gDefaultField"), 1); @@ -162,8 +164,8 @@ public static void main(String[] args) throws Exception { Asserts.assertEquals(me.getValue("hiddenField"), "Hidden"); } - private static RecordedEvent findEvent(Recording r, String name) throws Exception { - for (RecordedEvent re : Events.fromRecording(r)) { + private static RecordedEvent findEvent(List events, String name) throws Exception { + for (RecordedEvent re : events) { if (re.getEventType().getName().equals(name)) { return re; } diff --git a/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java b/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java index 0df2b5802cfe3..9c571a514e669 100644 --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerPhase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,7 +78,7 @@ public static void main(String[] args) throws Exception { System.out.println("Event:" + event); Events.assertField(event, "phase").notEmpty(); Events.assertField(event, "compileId").atLeast(0); - Events.assertField(event, "phaseLevel").atLeast((short)0).atMost((short)4); + Events.assertField(event, "phaseLevel").atLeast((short)0).atMost((short)5); Events.assertEventThread(event); } } diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java b/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java index 3d378712c422e..1e64a0bb4e44e 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java @@ -125,7 +125,7 @@ public static void main(String[] args) throws IOException { // since we can not reliably guarantee that they occur (or not). Set optPhases = of( // The following phases only occur on evacuation failure. - "RestoreRetainedRegions", + "RestoreEvacuationFailedRegions", "RemoveSelfForwards", "RestorePreservedMarks", "ProcessEvacuationFailedRegions", diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java index 5ec810b11c861..bd3a7f63a8a99 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1ConcurrentMark.java @@ -40,7 +40,7 @@ public static void main(String[] args) throws Exception { String testID = "G1ConcurrentMark"; String[] vmFlags = {"-XX:+UseG1GC", "-XX:+ExplicitGCInvokesConcurrent"}; String[] gcNames = {GCHelper.gcG1New, GCHelper.gcG1Old, GCHelper.gcG1Full}; - String[] gcCauses = {"Metadata GC Threshold", "GCLocker Initiated GC", "G1 Evacuation Pause", "G1 Preventive Collection", + String[] gcCauses = {"Metadata GC Threshold", "G1 Evacuation Pause", "G1 Preventive Collection", "G1 Compaction Pause", "System.gc()"}; GCGarbageCollectionUtil.test(testID, vmFlags, gcNames, gcCauses); } diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java index a83e0ba6d6f70..072c3905baf59 100644 --- a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java +++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithG1FullCollection.java @@ -40,7 +40,7 @@ public static void main(String[] args) throws Exception { String testID = "G1FullCollection"; String[] vmFlags = {"-XX:+UseG1GC"}; String[] gcNames = {GCHelper.gcG1New, GCHelper.gcG1Old, GCHelper.gcG1Full}; - String[] gcCauses = {"Metadata GC Threshold", "GCLocker Initiated GC", "G1 Evacuation Pause", "G1 Preventive Collection", + String[] gcCauses = {"Metadata GC Threshold", "G1 Evacuation Pause", "G1 Preventive Collection", "G1 Compaction Pause", "System.gc()"}; GCGarbageCollectionUtil.test(testID, vmFlags, gcNames, gcCauses); } diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationFailedEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationFailedEvent.java index fb34249c1dc93..584900620d4ec 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationFailedEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestEvacuationFailedEvent.java @@ -47,8 +47,8 @@ * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI - * -Xmx32m -Xms32m -XX:+UnlockExperimentalVMOptions -XX:+G1EvacuationFailureALot - * -XX:G1EvacuationFailureALotCount=100 -XX:G1EvacuationFailureALotInterval=1 + * -Xmx32m -Xms32m -XX:+UnlockExperimentalVMOptions -XX:+G1GCAllocationFailureALot + * -XX:G1GCAllocationFailureALotCount=100 -XX:G1GCAllocationFailureALotInterval=1 * -Xlog:gc=debug -XX:+UseG1GC jdk.jfr.event.gc.detailed.TestEvacuationFailedEvent */ diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestGCLockerEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestGCLockerEvent.java index f0d9fa3f35a69..596af47de39bc 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestGCLockerEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestGCLockerEvent.java @@ -26,11 +26,12 @@ * @test TestGCLockerEvent * @key jfr * @requires vm.hasJFR - * @requires vm.gc.G1 + * @requires vm.gc.Serial | vm.gc.Parallel + * @requires vm.gc != null * @library /test/lib * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx32m -Xms32m -Xmn12m -XX:+UseG1GC jdk.jfr.event.gc.detailed.TestGCLockerEvent + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xmx32m -Xms32m -Xmn12m jdk.jfr.event.gc.detailed.TestGCLockerEvent */ package jdk.jfr.event.gc.detailed; diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java index 2306d33b65107..7e0cc11173370 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZAllocationStallEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ public static void main(String[] args) throws Exception { List events = Events.fromRecording(recording); System.out.println("Events: " + events.size()); Events.hasEvents(events); - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { Events.assertField(event, "size").atLeast(2L * 1024 * 1024); } } diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java index 910fdd80eb43d..182f7b3d509f3 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZPageAllocationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,7 +65,7 @@ public static void main(String[] args) throws Exception { List events = Events.fromRecording(recording); System.out.println("Events: " + events.size()); Events.hasEvents(events); - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { Events.assertField(event, "size").atLeast(2L * 1024 * 1024); } } diff --git a/test/jdk/jdk/jfr/event/gc/heapsummary/HeapSummaryEventAllGcs.java b/test/jdk/jdk/jfr/event/gc/heapsummary/HeapSummaryEventAllGcs.java index 8946df90f814e..674270b044911 100644 --- a/test/jdk/jdk/jfr/event/gc/heapsummary/HeapSummaryEventAllGcs.java +++ b/test/jdk/jdk/jfr/event/gc/heapsummary/HeapSummaryEventAllGcs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,10 +48,11 @@ public static void test(String expectedYoungCollector, String expectedOldCollect GCHelper.callSystemGc(5, true); recording.stop(); - if (!checkCollectors(recording, expectedYoungCollector, expectedOldCollector)) { + List allEvents = Events.fromRecording(recording); + if (!checkCollectors(allEvents, expectedYoungCollector, expectedOldCollector)) { return; } - List events = GCHelper.removeFirstAndLastGC(Events.fromRecording(recording)); + List events = GCHelper.removeFirstAndLastGC(allEvents); for (RecordedEvent event : events) { System.out.println("Event:" + event); } @@ -190,8 +191,8 @@ private static void checkSpace(RecordedEvent event, String structName) { Asserts.assertEquals(size, end - start, "Size mismatch"); } - private static boolean checkCollectors(Recording recording, String expectedYoung, String expectedOld) throws Exception { - for (RecordedEvent event : Events.fromRecording(recording)) { + private static boolean checkCollectors(List events, String expectedYoung, String expectedOld) throws Exception { + for (RecordedEvent event : events) { if (Events.isEventType(event, EventNames.GCConfiguration)) { final String young = Events.assertField(event, "youngCollector").notEmpty().getValue(); final String old = Events.assertField(event, "oldCollector").notEmpty().getValue(); diff --git a/test/jdk/jdk/jfr/event/gc/objectcount/ObjectCountAfterGCEvent.java b/test/jdk/jdk/jfr/event/gc/objectcount/ObjectCountAfterGCEvent.java index 4646992f4643e..f5ee4b73a5e6e 100644 --- a/test/jdk/jdk/jfr/event/gc/objectcount/ObjectCountAfterGCEvent.java +++ b/test/jdk/jdk/jfr/event/gc/objectcount/ObjectCountAfterGCEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,11 +53,11 @@ public static void test(String gcName) throws Exception { recording.stop(); System.out.println("gcName=" + gcName); - for (RecordedEvent event : Events.fromRecording(recording)) { + List events = Events.fromRecording(recording); + for (RecordedEvent event : events) { System.out.println("Event: " + event); } - List events= Events.fromRecording(recording); Optional gcEvent = events.stream() .filter(e -> isMySystemGc(e, gcName)) .findFirst(); diff --git a/test/jdk/jdk/jfr/event/gc/stacktrace/AllocationStackTrace.java b/test/jdk/jdk/jfr/event/gc/stacktrace/AllocationStackTrace.java index 5e3b56d2c8602..c5dbcd2b42ecd 100644 --- a/test/jdk/jdk/jfr/event/gc/stacktrace/AllocationStackTrace.java +++ b/test/jdk/jdk/jfr/event/gc/stacktrace/AllocationStackTrace.java @@ -79,7 +79,7 @@ public void allocate() { class OldGenMemoryAllocator extends MemoryAllocator { private List list = new ArrayList(); - private int counter = 6000; + private int counter = 5000; @Override public void allocate() { @@ -87,7 +87,7 @@ public void allocate() { list.add(new byte[10 * KB]); } else { list = new ArrayList(); - counter = 6000; + counter = 5000; } garbage = list; diff --git a/test/jdk/jdk/jfr/event/oldobject/TestListenerLeak.java b/test/jdk/jdk/jfr/event/oldobject/TestListenerLeak.java index 67ef11b27408c..92610283525a6 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestListenerLeak.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestListenerLeak.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,15 +71,17 @@ public void onListen() { public static void main(String[] args) throws Exception { WhiteBox.setWriteAllObjectSamples(true); - - try (Recording r = new Recording()) { - r.enable(EventNames.OldObjectSample).withStackTrace().with("cutoff", "infinity"); - r.start(); - listenerLeak(); - r.stop(); - List events = Events.fromRecording(r); - if (OldObjects.countMatchingEvents(events, Stuff[].class, null, null, -1, "listenerLeak") == 0) { - throw new Exception("Could not find leak with " + Stuff[].class); + while (true) { + try (Recording r = new Recording()) { + r.enable(EventNames.OldObjectSample).withStackTrace().with("cutoff", "infinity"); + r.start(); + listenerLeak(); + r.stop(); + List events = Events.fromRecording(r); + if (OldObjects.countMatchingEvents(events, Stuff[].class, null, null, -1, "listenerLeak") != 0) { + return; // Success + } + System.out.println("Could not find leak with " + Stuff[].class + ". Retrying."); } } } diff --git a/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java b/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java index 82d324f5b55e2..b84160a0ac5a4 100644 --- a/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java +++ b/test/jdk/jdk/jfr/event/oldobject/TestMetadataRetention.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,10 +100,10 @@ public static void main(String[] args) throws Throwable { RecordedEvent chunkRotation = findChunkRotationEvent(events); try { // Sanity check that class was unloaded - Events.hasEvent(recording, EventNames.ClassUnload); + Events.hasEvent(events, EventNames.ClassUnload); validateClassUnloadEvent(events); // Validate that metadata for old object event has survived chunk rotation - Events.hasEvent(recording, EventNames.OldObjectSample); + Events.hasEvent(events, EventNames.OldObjectSample); validateOldObjectEvent(events, chunkRotation.getStartTime()); } catch (Throwable t) { t.printStackTrace(); diff --git a/test/jdk/jdk/jfr/event/runtime/TestDeprecatedEvent.java b/test/jdk/jdk/jfr/event/runtime/TestDeprecatedEvent.java new file mode 100644 index 0000000000000..183d82bc5e201 --- /dev/null +++ b/test/jdk/jdk/jfr/event/runtime/TestDeprecatedEvent.java @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jfr.event.runtime; + +import java.util.List; +import java.util.ArrayList; + +import jdk.jfr.consumer.RecordedMethod; +import jdk.jfr.consumer.RecordedEvent; +import jdk.jfr.consumer.RecordedStackTrace; +import jdk.jfr.consumer.RecordedFrame; +import jdk.jfr.internal.test.DeprecatedMethods; +import jdk.jfr.internal.test.DeprecatedThing; +import jdk.jfr.Recording; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.Events; +import static jdk.test.lib.Asserts.assertTrue; +import static jdk.test.lib.Asserts.assertNull; +import static jdk.test.lib.Asserts.assertNotNull; + +/** + * @test + * @key jfr + * @requires vm.hasJFR + * @modules jdk.jfr/jdk.jfr.internal.test + * @library /test/lib + * + * @run main/othervm/timeout=300 -XX:StartFlightRecording:settings=none,+jdk.DeprecatedInvocation#enabled=true + * jdk.jfr.event.runtime.TestDeprecatedEvent Default + + * @run main/othervm/timeout=300 -Xint -XX:+UseInterpreter -XX:StartFlightRecording:settings=none,+jdk.DeprecatedInvocation#enabled=true + * jdk.jfr.event.runtime.TestDeprecatedEvent Interpreter + * + * @run main/othervm/timeout=300 -Xcomp -XX:-UseInterpreter -XX:StartFlightRecording:settings=none,+jdk.DeprecatedInvocation#enabled=true + * jdk.jfr.event.runtime.TestDeprecatedEvent Compiler + * + * @run main/othervm/timeout=300 -Xcomp -XX:TieredStopAtLevel=1 -XX:-UseInterpreter -XX:StartFlightRecording:settings=none,+jdk.DeprecatedInvocation#enabled=true + * jdk.jfr.event.runtime.TestDeprecatedEvent C1 + * + * @run main/othervm/timeout=300 -Xcomp -XX:TieredStopAtLevel=4 -XX:-TieredCompilation -XX:-UseInterpreter -XX:StartFlightRecording:settings=none,+jdk.DeprecatedInvocation#enabled=true + * jdk.jfr.event.runtime.TestDeprecatedEvent C2 + * + */ +public class TestDeprecatedEvent { +/* + * + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * jdk.jfr.event.runtime.TestDeprecatedEvent JVMCI + * + */ + public static String EVENT_NAME = EventNames.DeprecatedInvocation; + private static String mode; + public static int counter; + + public static void main(String... args) throws Exception { + mode = args[0]; + testDeprecatedLevelAll(); + testDeprecatedLevelAllRetained(); + testReflectionAll(); + testDeprecatedLevelForRemovalRetained(); + } + + private static void testDeprecatedLevelAll() throws Exception { + try (Recording r = new Recording()) { + r.enable(EVENT_NAME).with("level", "all"); + r.start(); + testLevelAll(); + r.stop(); + validateLevelAll(r); + } + } + + @Deprecated(forRemoval = true) + public static void userDeprecatedForRemoval() { + counter++; + } + + private static void testLevelAll() throws Exception { + // Methods individually decorated. + DeprecatedMethods.deprecated(); + DeprecatedMethods.deprecatedSince(); + DeprecatedMethods.deprecatedForRemoval(); + DeprecatedMethods.deprecatedSinceForRemoval(); + // Class level @deprecated annotation + // @Deprecated(since = "0") + DeprecatedThing t = new DeprecatedThing(); + t.instanceDeprecatedForRemoval(); + t.instanceDeprecatedSinceForRemoval(); + t.foo(); + t.zoo(); + // Invoke a deprecated method in the users code + // to verify the negative case, i.e. that this + // invocation is not reported. + userDeprecatedForRemoval(); + } + + private static void validateLevelAll(Recording r) throws Exception { + List events = Events.fromRecording(r); + printInvocations(events, "all"); + assertMethod(events, "testLevelAll", "deprecated"); + assertMethod(events, "testLevelAll", "deprecatedSince"); + assertMethod(events, "testLevelAll", "deprecatedForRemoval"); + assertMethod(events, "testLevelAll", "deprecatedSinceForRemoval"); + assertMethod(events, "testLevelAll", "instanceDeprecatedForRemoval"); + assertMethod(events, "testLevelAll", "instanceDeprecatedSinceForRemoval"); + assertMethod(events, "testLevelAll", "foo"); + assertMethod(events, "testLevelAll", "zoo"); + // Negative case + try { + assertMethod(events, "testLevelAll", "userDeprecatedForRemoval"); + throw new RuntimeException("Invocation of a deprecated method in user code should not be reported"); + } catch (Exception e) { + // Expected + } + } + + // Does not invoke any deprecated methods. We only verify + // that all previously invoked methods are still retained + // when starting and stopping a subsequent recording. + private static void testDeprecatedLevelAllRetained() throws Exception { + try (Recording r = new Recording()) { + r.enable(EVENT_NAME).with("level", "all"); + r.start(); + r.stop(); + validateLevelAll(r); + } + } + + private static void testReflectionAll() throws Exception { + try (Recording r = new Recording()) { + r.enable(EVENT_NAME).with("level", "all"); + r.start(); + DeprecatedMethods.class.getMethod("reflectionDeprecated").invoke(null); + DeprecatedMethods.class.getMethod("reflectionDeprecatedSince").invoke(null); + DeprecatedMethods.class.getMethod("reflectionDeprecatedForRemoval").invoke(null); + DeprecatedMethods.class.getMethod("reflectionDeprecatedSinceForRemoval").invoke(null); + r.stop(); + validateReflectionLevelAll(r); + } + } + + private static void validateReflectionLevelAll(Recording r) throws Exception { + List events = Events.fromRecording(r); + printInvocations(events, "reflectionAll"); + assertMethod(events, "testReflectionAll", "reflectionDeprecated"); + assertMethod(events, "testReflectionAll", "reflectionDeprecatedSince"); + assertMethod(events, "testReflectionAll", "reflectionDeprecatedForRemoval"); + assertMethod(events, "testReflectionAll", "reflectionDeprecatedSinceForRemoval"); + } + + // Does not invoke any deprecated methods. We only verify + // that all previously invoked methods are still retained + // when starting and stopping a subsequent recording. + private static void testDeprecatedLevelForRemovalRetained() throws Exception { + try (Recording r = new Recording()) { + r.enable(EVENT_NAME).with("level", "forRemoval"); + r.start(); + r.stop(); + validateLevelForRemoval(r); + } + } + + private static void validateLevelForRemoval(Recording r) throws Exception { + List events = Events.fromRecording(r); + printInvocations(events, "forRemoval"); + assertMethod(events, "testLevelAll", "deprecatedForRemoval"); + assertMethod(events, "testLevelAll", "deprecatedSinceForRemoval"); + assertMethod(events, "testLevelAll", "instanceDeprecatedForRemoval"); + assertMethod(events, "testLevelAll", "instanceDeprecatedSinceForRemoval"); + assertMethod(events, "testReflectionAll", "reflectionDeprecatedForRemoval"); + assertMethod(events, "testReflectionAll", "reflectionDeprecatedSinceForRemoval"); + } + + private static void assertMethod(List events, String caller, String method) throws Exception { + for (RecordedEvent e : events) { + RecordedMethod deprecatedMethod = e.getValue("method"); + boolean forRemoval = e.getValue("forRemoval"); + RecordedStackTrace stacktrace = e.getStackTrace(); + assertNotNull(stacktrace, "should have a stacktrace"); + assertTrue(stacktrace.isTruncated(), "invariant"); + List frames = stacktrace.getFrames(); + assertTrue(frames.size() == 1, "invariant"); + assertTrue(frames.getFirst().isJavaFrame(), "invariant"); + RecordedFrame frame = frames.getFirst(); + assertTrue(frame.isJavaFrame(), "invariant"); + RecordedMethod callerMethod = frame.getMethod(); + assertNull(e.getThread(), "should not have a thread"); + if (forRemoval) { + assertTrue(deprecatedMethod.getName().endsWith("ForRemoval"), "wrong filtering?"); + } + if (deprecatedMethod.getName().equals(method) && callerMethod.getName().equals(caller)){ + return; + } + } + throw new Exception("Could not find invocation: " + caller + " -> " + method); + } + + + private static void printInvocations(List events, String all) { + System.out.println("*** METHOD INVOCATION *** (" + mode + ") level = " + all + " count: " + events.size() + " ***\n"); + for (RecordedEvent e : events) { + RecordedMethod deprecatedMethod = e.getValue("method"); + boolean forRemoval = e.getValue("forRemoval"); + RecordedStackTrace stacktrace = e.getStackTrace(); + assertNotNull(stacktrace, "should have a stacktrace"); + assertTrue(stacktrace.isTruncated(), "invariant"); + List frames = stacktrace.getFrames(); + assertTrue(frames.size() == 1, "invariant"); + RecordedFrame frame = frames.getFirst(); + assertTrue(frame.isJavaFrame(), "invariant"); + RecordedMethod callerMethod = frame.getMethod(); + int bci = frame.getBytecodeIndex(); + int lineNumber = frame.getLineNumber(); + assertNull(e.getThread(), "should not have a thread"); + System.out.println(callerMethod.getName() + " at bci: " + bci + " line: " + lineNumber + " -> " + deprecatedMethod.getName()); + System.out.println(e); + } + System.out.println(); + } +} diff --git a/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java b/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java index f590ebed8987c..285592bce1699 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java +++ b/test/jdk/jdk/jfr/event/runtime/TestSafepointEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,9 +68,10 @@ public static void main(String[] args) throws Exception { try { // Verify that each event type was seen at least once + List events = Events.fromRecording(recording); for (String name : EVENT_NAMES) { boolean found = false; - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { found = event.getEventType().getName().equals(name); if (found) { break; @@ -81,7 +82,7 @@ public static void main(String[] args) throws Exception { // Collect all events grouped by safepoint id SortedMap> safepointIds = new TreeMap<>(); - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { Long safepointId = event.getValue("safepointId"); if (!safepointIds.containsKey(safepointId)) { safepointIds.put(safepointId, new HashSet<>()); diff --git a/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java b/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java index 36ef4bf29bf19..f20175da37fd9 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestSyncOnValueBasedClassEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,7 @@ public static void main(String[] args) throws Throwable { List classesFound = new ArrayList(); List events = Events.fromRecording(recording); Events.hasEvents(events); - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { String className = Events.assertField(event, "valueBasedClass.name").notEmpty().getValue(); RecordedThread jt = event.getThread(); if (Thread.currentThread().getName().equals(jt.getJavaName())) { diff --git a/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java b/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java index 61ec9677df6a8..ae6f1f27191af 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java +++ b/test/jdk/jdk/jfr/event/runtime/TestVMOperation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ public static void main(String[] args) throws Throwable { List events = Events.fromRecording(recording); Events.hasEvents(events); - for (RecordedEvent event : Events.fromRecording(recording)) { + for (RecordedEvent event : events) { String operation = Events.assertField(event, "operation").notEmpty().getValue(); if (operation.equals(VM_OPERATION)) { Events.assertField(event, "safepoint").equal(true); diff --git a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java index abbd6fb520170..5d469c698c190 100644 --- a/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java +++ b/test/jdk/jdk/jfr/jcmd/TestJcmdDumpPathToGCRoots.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -74,43 +74,50 @@ public static void main(String[] args) throws Exception { } private static void testDump(String pathToGcRoots, Map settings, boolean expectedChains) throws Exception { - try (Recording r = new Recording()) { - Map p = new HashMap<>(settings); - p.put(EventNames.OldObjectSample + "#" + Enabled.NAME, "true"); - r.setName("dodo"); - r.setSettings(p); - r.setToDisk(true); - r.start(); - clearLeak(); - System.out.println("Recording id: " + r.getId()); - System.out.println("Settings: " + settings.toString()); - System.out.println("Command: JFR.dump " + pathToGcRoots); - System.out.println("Chains expected: " + expectedChains); - buildLeak(); - System.gc(); - System.gc(); - File recording = new File("TestJcmdDumpPathToGCRoots" + r.getId() + ".jfr"); - recording.delete(); - JcmdHelper.jcmd("JFR.dump", "name=dodo", pathToGcRoots, "filename=" + recording.getAbsolutePath()); - r.setSettings(Collections.emptyMap()); - List events = RecordingFile.readAllEvents(recording.toPath()); - if (events.isEmpty()) { - throw new Exception("No events found in recoding"); - } - boolean chains = hasChains(events); - if (expectedChains && !chains) { - System.out.println(events); - throw new Exception("Expected chains but found none"); - } - if (!expectedChains && chains) { - System.out.println(events); - throw new Exception("Didn't expect chains but found some"); + while (true) { + try (Recording r = new Recording()) { + Map p = new HashMap<>(settings); + p.put(EventNames.OldObjectSample + "#" + Enabled.NAME, "true"); + r.setName("dodo"); + r.setSettings(p); + r.setToDisk(true); + r.start(); + clearLeak(); + System.out.println("Recording id: " + r.getId()); + System.out.println("Settings: " + settings.toString()); + System.out.println("Command: JFR.dump " + pathToGcRoots); + System.out.println("Chains expected: " + expectedChains); + buildLeak(); + System.gc(); + System.gc(); + File recording = new File("TestJcmdDumpPathToGCRoots" + r.getId() + ".jfr"); + recording.delete(); + JcmdHelper.jcmd("JFR.dump", "name=dodo", pathToGcRoots, "filename=" + recording.getAbsolutePath()); + r.setSettings(Collections.emptyMap()); + List events = RecordingFile.readAllEvents(recording.toPath()); + if (events.isEmpty()) { + System.out.println("No events found in recording. Retrying."); + continue; + } + boolean chains = hasChains(events); + if (expectedChains && !chains) { + System.out.println(events); + System.out.println("Expected chains but found none. Retrying."); + continue; + } + if (!expectedChains && chains) { + System.out.println(events); + System.out.println("Didn't expect chains but found some. Retrying."); + continue; + } + return; // Success } } } private static void clearLeak() { leak.clear(); + System.gc(); } private static boolean hasChains(List events) throws IOException { diff --git a/test/jdk/jdk/jfr/startupargs/TestRetransform.java b/test/jdk/jdk/jfr/startupargs/TestRetransform.java index 6e516afe7ebd6..2e4067ae5441d 100644 --- a/test/jdk/jdk/jfr/startupargs/TestRetransform.java +++ b/test/jdk/jdk/jfr/startupargs/TestRetransform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,11 @@ package jdk.jfr.startupargs; +import java.util.List; import jdk.jfr.Event; import jdk.jfr.EventType; import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; import jdk.test.lib.Asserts; import jdk.test.lib.jfr.Events; import jdk.test.lib.jfr.SimpleEvent; @@ -58,8 +60,9 @@ public static void main(String[] args) throws Exception { if (type.isEnabled()) { Asserts.fail("Expected event to be disabled after recording stopped"); } - Events.hasEvent(r, SimpleEvent.class.getName()); - Events.hasEvent(r, TestEvent.class.getName()); + List events = Events.fromRecording(r); + Events.hasEvent(events, SimpleEvent.class.getName()); + Events.hasEvent(events, TestEvent.class.getName()); } // Classes that are loaded during a recording diff --git a/test/jdk/jdk/jfr/tool/TestView.java b/test/jdk/jdk/jfr/tool/TestView.java index fda82939c373d..89c74133286f9 100644 --- a/test/jdk/jdk/jfr/tool/TestView.java +++ b/test/jdk/jdk/jfr/tool/TestView.java @@ -91,13 +91,13 @@ private static void testTableView(String recording) throws Throwable { private static void testEventType(String recording) throws Throwable { OutputAnalyzer output = ExecuteHelper.jfr( - "view", "--verbose", "--width", "300", "--cell-height", "100", "SystemGC", recording); + "view", "--verbose", "--width", "300", "--cell-height", "100", "ThreadSleep", recording); // Verify title - output.shouldContain("System GC"); + output.shouldContain("Thread Sleep"); // Verify headings - output.shouldContain("Invoked Concurrent"); + output.shouldContain("Sleep Time"); // Verify verbose headings - output.shouldContain("invokedConcurrent"); + output.shouldContain("time"); // Verify thread value output.shouldContain(Thread.currentThread().getName()); // Verify stack frame diff --git a/test/jdk/jdk/lambda/TEST.properties b/test/jdk/jdk/lambda/TEST.properties index bd37b556c82e6..d6687af079f2c 100644 --- a/test/jdk/jdk/lambda/TEST.properties +++ b/test/jdk/jdk/lambda/TEST.properties @@ -3,7 +3,5 @@ TestNG.dirs = . maxOutputSize = 250000 -modules = java.base/jdk.internal.classfile \ - java.base/jdk.internal.classfile.constantpool \ - java.base/jdk.internal.classfile.instruction \ - jdk.compiler jdk.zipfs +modules = jdk.compiler jdk.zipfs +enablePreview = true \ No newline at end of file diff --git a/test/jdk/jdk/lambda/separate/ClassToInterfaceConverter.java b/test/jdk/jdk/lambda/separate/ClassToInterfaceConverter.java index 6b39981bfbde3..44c5c6ab17913 100644 --- a/test/jdk/jdk/lambda/separate/ClassToInterfaceConverter.java +++ b/test/jdk/jdk/lambda/separate/ClassToInterfaceConverter.java @@ -23,10 +23,10 @@ package separate; -import jdk.internal.classfile.*; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.*; +import java.lang.classfile.instruction.InvokeInstruction; import static java.lang.constant.ConstantDescs.INIT_NAME; -import static jdk.internal.classfile.Classfile.*; +import static java.lang.classfile.ClassFile.*; public class ClassToInterfaceConverter implements ClassFilePreprocessor { @@ -50,7 +50,7 @@ private byte[] convertToInterface(ClassModel classModel) { } }; - return Classfile.of().transform(classModel, + return ClassFile.of().transform(classModel, ClassTransform.dropping(ce -> ce instanceof MethodModel mm && mm.methodName().equalsString(INIT_NAME)) .andThen(ClassTransform.transformingMethodBodies(ct)) .andThen(ClassTransform.endHandler(b -> b.withFlags(ACC_INTERFACE | ACC_ABSTRACT | ACC_PUBLIC))) @@ -58,7 +58,7 @@ private byte[] convertToInterface(ClassModel classModel) { } public byte[] preprocess(String classname, byte[] bytes) { - ClassModel classModel = Classfile.of().parse(bytes); + ClassModel classModel = ClassFile.of().parse(bytes); if (classModel.thisClass().asInternalName().equals(whichClass)) { return convertToInterface(classModel); } else { diff --git a/test/jdk/jdk/modules/incubator/ServiceBinding.java b/test/jdk/jdk/modules/incubator/ServiceBinding.java index 521dcb5f158b2..1252b9081781d 100644 --- a/test/jdk/jdk/modules/incubator/ServiceBinding.java +++ b/test/jdk/jdk/modules/incubator/ServiceBinding.java @@ -24,10 +24,8 @@ /** * @test * @bug 8233922 - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.module + * @enablePreview + * @modules java.base/jdk.internal.module * @library /test/lib * @build ServiceBinding TestBootLayer jdk.test.lib.util.ModuleInfoWriter * @run testng ServiceBinding diff --git a/test/jdk/jdk/nio/zipfs/CorruptedZipFilesTest.java b/test/jdk/jdk/nio/zipfs/CorruptedZipFilesTest.java new file mode 100644 index 0000000000000..57287c6d8ee05 --- /dev/null +++ b/test/jdk/jdk/nio/zipfs/CorruptedZipFilesTest.java @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8316141 + * @summary test for correct detection and reporting of corrupted zip files + * @run junit CorruptedZipFilesTest + */ + + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipException; +import java.util.zip.ZipOutputStream; + +import static java.util.zip.ZipFile.*; +import static org.junit.jupiter.api.Assertions.*; + +public class CorruptedZipFilesTest { + + /* + * Byte array holding a valid template ZIP. + * + * The 'good' ZIP file has the following structure: + * + * 0000 LOCAL HEADER #1 04034B50 + * 0004 Extract Zip Spec 14 '2.0' + * 0005 Extract OS 00 'MS-DOS' + * 0006 General Purpose Flag 0808 + * [Bits 1-2] 0 'Normal Compression' + * [Bit 3] 1 'Streamed' + * [Bit 11] 1 'Language Encoding' + * 0008 Compression Method 0008 'Deflated' + * 000A Last Mod Time 567F7D07 'Fri Mar 31 15:40:14 2023' + * 000E CRC 00000000 + * 0012 Compressed Length 00000000 + * 0016 Uncompressed Length 00000000 + * 001A Filename Length 0001 + * 001C Extra Length 0000 + * 001E Filename 'x' + * 001F PAYLOAD ... + * + * 0022 STREAMING DATA HEADER 08074B50 + * 0026 CRC 8CDC1683 + * 002A Compressed Length 00000003 + * 002E Uncompressed Length 00000001 + * + * 0032 CENTRAL HEADER #1 02014B50 + * 0036 Created Zip Spec 14 '2.0' + * 0037 Created OS 00 'MS-DOS' + * 0038 Extract Zip Spec 14 '2.0' + * 0039 Extract OS 00 'MS-DOS' + * 003A General Purpose Flag 0808 + * [Bits 1-2] 0 'Normal Compression' + * [Bit 3] 1 'Streamed' + * [Bit 11] 1 'Language Encoding' + * 003C Compression Method 0008 'Deflated' + * 003E Last Mod Time 567F7D07 'Fri Mar 31 15:40:14 2023' + * 0042 CRC 8CDC1683 + * 0046 Compressed Length 00000003 + * 004A Uncompressed Length 00000001 + * 004E Filename Length 0001 + * 0050 Extra Length 0000 + * 0052 Comment Length 0000 + * 0054 Disk Start 0000 + * 0056 Int File Attributes 0000 + * [Bit 0] 0 'Binary Data' + * 0058 Ext File Attributes 00000000 + * 005C Local Header Offset 00000000 + * 0060 Filename 'x' + * + * 0061 END CENTRAL HEADER 06054B50 + * 0065 Number of this disk 0000 + * 0067 Central Dir Disk no 0000 + * 0069 Entries in this disk 0001 + * 006B Total Entries 0001 + * 006D Size of Central Dir 0000002F + * 0071 Offset to Central Dir 00000032 + * 0075 Comment Length 0000 + * + */ + private static byte[] template; + + // Copy of the template ZIP for modification by each test + private byte[] copy; + + // Litte-endian ByteBuffer for manipulating the ZIP copy + private ByteBuffer buffer; + + // Some well-known locations in the ZIP + private static int endpos, cenpos, locpos; + + // The path used when reading/writing the corrupted ZIP to disk + private Path zip = Path.of("corrupted.zip"); + + /* + * Make a sample ZIP and calculate some known offsets into this ZIP + */ + @BeforeAll + public static void setup() throws IOException { + // Make a ZIP with a single entry + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try (ZipOutputStream zos = new ZipOutputStream(out)) { + ZipEntry e = new ZipEntry("x"); + zos.putNextEntry(e); + zos.write((int)'x'); + } + template = out.toByteArray(); + // ByteBuffer for reading fields from the ZIP + ByteBuffer buffer = ByteBuffer.wrap(template).order(ByteOrder.LITTLE_ENDIAN); + + // Calculate the offset of the End of central directory record + endpos = template.length - ENDHDR; + // Look up the offet of the Central directory header + cenpos = buffer.getShort(endpos + ENDOFF); + // Look up the offset of the corresponding Local file header + locpos = buffer.getShort(cenpos + CENOFF); + + // Run some sanity checks on the valid ZIP: + assertEquals(ENDSIG, buffer.getInt(endpos),"Where's ENDSIG?"); + assertEquals(CENSIG, buffer.getInt(cenpos),"Where's CENSIG?"); + assertEquals(LOCSIG, buffer.getInt(locpos),"Where's LOCSIG?"); + assertEquals(buffer.getShort(cenpos+CENNAM), + buffer.getShort(locpos+LOCNAM), + "Name field length mismatch"); + assertEquals(buffer.getShort(cenpos+CENEXT), + buffer.getShort( locpos+LOCEXT), + "Extra field length mismatch"); + } + + /* + * Make a copy safe to modify by each test + */ + @BeforeEach + public void makeCopy() { + copy = template.clone(); + buffer = ByteBuffer.wrap(copy).order(ByteOrder.LITTLE_ENDIAN); + } + + /* + * Delete the ZIP file produced after each test method + */ + @AfterEach + public void cleanup() throws IOException { + Files.deleteIfExists(zip); + } + + /* + * A ZipException is thrown when the 'End of Central Directory' + * (END) header has a CEN size exceeding past the offset of the END record + */ + @Test + public void excessiveCENSize() throws IOException { + buffer.putInt(endpos+ENDSIZ, 0xff000000); + assertZipException(".*bad central directory size.*"); + } + + /* + * A ZipException is thrown when the 'End of Central Directory' + * (END) header has a CEN offset with an invalid value. + */ + @Test + public void excessiveCENOffset() throws IOException { + buffer.putInt(endpos+ENDOFF, 0xff000000); + assertZipException(".*bad central directory offset.*"); + } + + /* + * A ZipException is thrown when a CEN header has an unexpected signature + */ + @Test + public void invalidCENSignature() throws IOException { + int existingSignature = buffer.getInt(cenpos); + buffer.putInt(cenpos, existingSignature +1); + assertZipException(".*bad signature.*"); + } + + /* + * A ZipException is thrown when a CEN header has the + * 'general purpose bit flag 0' ('encrypted') set. + */ + @Test + public void encryptedEntry() throws IOException { + copy[cenpos+CENFLG] |= 1; + assertZipException(".*encrypted entry.*"); + } + + /* + * A ZipException is thrown when a CEN header has a file name + * length which makes the CEN header overflow into the + * 'End of central directory' record. + */ + @Test + public void excessiveFileNameLength() throws IOException { + short existingNameLength = buffer.getShort(cenpos + CENNAM); + buffer.putShort(cenpos+CENNAM, (short) (existingNameLength + 1)); + assertZipException(".*bad header size.*"); + } + + /* + * A ZipException is thrown when a CEN header has a + * file name length which makes the CEN header overflow into the + * 'End of central directory' record. + */ + @Test + public void excessiveFileNameLength2() throws IOException { + buffer.putShort(cenpos + CENNAM, (short) 0xfdfd); + assertZipException(".*bad header size.*"); + } + + /* + * A ZipException is thrown if a CEN header has an + * extra field length which makes the CEN header overflow into the + * End of central directory record. + */ + @Test + public void excessiveExtraFieldLength() throws IOException { + buffer.put(cenpos+CENEXT, (byte) 0xff); + buffer.put(cenpos+CENEXT+1, (byte) 0xff); + assertZipException(".*bad header size.*"); + } + + /* + * A ZipException is thrown by Zip FS if a CEN header has an + * extra field length which makes the CEN header overflow into the + * End of central directory record. + */ + @Test + public void excessiveExtraFieldLength2() throws IOException { + buffer.putShort(cenpos+CENEXT, (short) 0xfdfd); + assertZipException(".*bad header size.*"); + } + + /* + * A ZipException is thrown when a CEN header has a comment length + * which overflows into the 'End of central directory' record + */ + @Test + public void excessiveCommentLength() throws IOException { + short existingCommentLength = buffer.getShort(cenpos + CENCOM); + buffer.putShort(cenpos+CENCOM, (short) (existingCommentLength + 1)); + assertZipException(".*bad header size.*"); + } + + /* + * A ZipException is thrown when a CEN header has a + * compression method field which is unsupported by the implementation + */ + @Test + public void unsupportedCompressionMethod() throws IOException { + copy[cenpos+CENHOW] = 2; + assertZipException(".*unsupported compression method.*"); + } + + /* + * Assert that opening a ZIP file and consuming the entry's + * InputStream using the ZipFile API fails with a ZipException + * with a message matching the given pattern. + * + * The ZIP file opened is the contents of the 'copy' byte array. + */ + void assertZipException(String msgPattern) throws IOException { + + Files.write(zip, copy); + + ZipException ex = assertThrows(ZipException.class, () -> { + try (FileSystem fs = FileSystems.newFileSystem(zip, Map.of())) { + Path p = fs.getPath("x"); + try (InputStream is = Files.newInputStream(p)) { + is.transferTo(OutputStream.nullOutputStream()); + } + } + }); + assertTrue(ex.getMessage().matches(msgPattern), + "Unexpected ZipException message: " + ex.getMessage()); + } +} diff --git a/test/jdk/lib/testlibrary/bootlib/java.base/java/util/stream/DefaultMethodStreams.java b/test/jdk/lib/testlibrary/bootlib/java.base/java/util/stream/DefaultMethodStreams.java index d16603e9cf8bb..bc7c3bc471d26 100644 --- a/test/jdk/lib/testlibrary/bootlib/java.base/java/util/stream/DefaultMethodStreams.java +++ b/test/jdk/lib/testlibrary/bootlib/java.base/java/util/stream/DefaultMethodStreams.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java b/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java new file mode 100644 index 0000000000000..333981bd1ff02 --- /dev/null +++ b/test/jdk/sun/jvmstat/monitor/MonitoredVm/ConcurrentGetMonitoredHost.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import sun.jvmstat.monitor.MonitoredHost; +import sun.jvmstat.monitor.VmIdentifier; + +/* + * @test + * @bug 8320687 + * @summary verify that sun.jvmstat.monitor.MonitoredHost.getMonitoredHost() doesn't + * unexpectedly throw an exception when invoked by concurrent threads + * + * @run main/othervm ConcurrentGetMonitoredHost + */ +public class ConcurrentGetMonitoredHost { + + /* + * Launches multiple concurrent threads and invokes MonitoredHost.getMonitoredHost() + * in each of these threads and expects the call to return successfully without any + * exceptions. + */ + public static void main(final String[] args) throws Exception { + final String pidStr = "12345"; + final VmIdentifier vmid = new VmIdentifier(pidStr); + final int numTasks = 100; + final List tasks = new ArrayList<>(); + for (int i = 0; i < numTasks; i++) { + tasks.add(new Task(vmid)); + } + System.out.println("Submitting " + numTasks + " concurrent tasks to" + + " get MonitoredHost for " + vmid); + try (ExecutorService executor = Executors.newCachedThreadPool()) { + // wait for all tasks to complete + final List> results = executor.invokeAll(tasks); + // verify each one successfully completed and each of + // the returned MonitoredHost is not null + for (final Future result : results) { + final MonitoredHost mh = result.get(); + if (mh == null) { + throw new AssertionError("MonitoredHost.getMonitoredHost() returned" + + " null for vmid " + vmid); + } + } + } + System.out.println("All " + numTasks + " completed successfully"); + } + + // a task which just calls MonitoredHost.getMonitoredHost(VmIdentifier) and + // returns the resultant MonitoredHost + private static final class Task implements Callable { + private final VmIdentifier vmid; + + private Task(final VmIdentifier vmid) { + this.vmid = Objects.requireNonNull(vmid); + } + + @Override + public MonitoredHost call() throws Exception { + return MonitoredHost.getMonitoredHost(this.vmid); + } + } +} diff --git a/test/jdk/sun/security/pkcs/pkcs7/NewSigAlg.java b/test/jdk/sun/security/pkcs/pkcs7/NewSigAlg.java index 098dd9caaa42c..926c2c0c65e69 100644 --- a/test/jdk/sun/security/pkcs/pkcs7/NewSigAlg.java +++ b/test/jdk/sun/security/pkcs/pkcs7/NewSigAlg.java @@ -46,6 +46,6 @@ public static void main(String[] args) throws Exception { static void test(String d, String e, String s) throws Exception { Asserts.assertEQ(s, SignerInfo.makeSigAlg( - AlgorithmId.get(d), AlgorithmId.get(s), false)); + AlgorithmId.get(d), AlgorithmId.get(s))); } } diff --git a/test/jdk/sun/security/pkcs/pkcs7/TwoHash.java b/test/jdk/sun/security/pkcs/pkcs7/TwoHash.java index 6aaf7825c26d2..4ebedd21928c4 100644 --- a/test/jdk/sun/security/pkcs/pkcs7/TwoHash.java +++ b/test/jdk/sun/security/pkcs/pkcs7/TwoHash.java @@ -45,7 +45,7 @@ public static void main(String[] args) throws Exception { CertAndKeyGen cak = new CertAndKeyGen("EC", "SHA512withECDSA"); cak.generate("secp256r1"); - byte[] signature = PKCS7.generateNewSignedData( + byte[] signature = PKCS7.generateSignedData( "SHA256withECDSA", null, cak.getPrivateKey(), diff --git a/test/jdk/sun/security/rsa/WithoutNULL.java b/test/jdk/sun/security/rsa/WithoutNULL.java new file mode 100644 index 0000000000000..64cf831099d2a --- /dev/null +++ b/test/jdk/sun/security/rsa/WithoutNULL.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8320597 + * @summary Verify RSA signature with omitted digest params (should be encoded as NULL) + * for backward compatibility + */ +import java.security.KeyFactory; +import java.security.Signature; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +public class WithoutNULL { + public static void main(String[] args) throws Exception { + + // A 1024-bit RSA public key + byte[] key = Base64.getMimeDecoder().decode(""" + MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrfTrEm4KvdFSpGAM7InrFEzALTKdphT9fK6Gu + eVjHtKsuCSEaULCdjhJvPpFK40ONr1JEC1Ywp1UYrfBBdKunnbDZqNZL1cFv+IzF4Yj6JO6pOeHi + 1Zpur1GaQRRlYTvzmyWY/AATQDh8JfKObNnDVwXeezFODUG8h5+XL1ZXZQIDAQAB"""); + + // A SHA1withRSA signature on an empty input where the digestAlgorithm + // inside DigestInfo does not have a parameters field. + byte[] sig = Base64.getMimeDecoder().decode(""" + D1FpiT44WEXlDfYK880bdorLO+e9qJVXZWiBgqs9dfK7lYQwyEt9dL23mbUAKm5TVEj2ZxtHkEvk + b8oaWkxk069jDTM1RhllPJZkAjeQRbw4gkg4N6wKZz9B/jdSRMNJg/b9QdRYZOHOBxsEHMbUREPV + DoCOLaxB8eIXX0EWkiE="""); + + Signature s = Signature.getInstance("SHA1withRSA", "SunRsaSign"); + s.initVerify(KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(key))); + if (!s.verify(sig)) { + throw new RuntimeException("Does not verify"); + } + } +} diff --git a/test/jdk/sun/security/tools/keytool/LineEndings.java b/test/jdk/sun/security/tools/keytool/LineEndings.java new file mode 100644 index 0000000000000..621102ae73caf --- /dev/null +++ b/test/jdk/sun/security/tools/keytool/LineEndings.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.Asserts; +import jdk.test.lib.SecurityTools; +import jdk.test.lib.process.OutputAnalyzer; + +import java.io.ByteArrayOutputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * @test + * @bug 8202598 + * @summary PEM outputs should have consistent line endings + * @library /test/lib + */ + +public class LineEndings { + + public static void main(String[] args) throws Exception { + keytool("-genkeypair -dname CN=A -keyalg ec"); + + keytool("-certreq -file a.csr -rfc"); + checkFile("a.csr"); + + keytool("-exportcert -file a.crt -rfc"); + checkFile("a.crt"); + + keytool("-gencrl -id 1 -rfc -file a.crl"); + checkFile("a.crl"); + + // `keytool -printcrl` shows "Verified by ..." at the end. Remove it. + String print = keytool("-printcrl -file a.crl -rfc").getStdout(); + print = print.substring(0, print.indexOf("Verified by")); + Files.writeString(Path.of("print"), print); + checkFile("print"); + } + + private static OutputAnalyzer keytool(String cmd) throws Exception { + return SecurityTools.keytool( + "-keystore ks -storepass changeit -alias a " + cmd) + .shouldHaveExitValue(0); + } + + // Make sure only CRLF is used inside the file. + private static void checkFile(String name) throws Exception { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + for (byte b : Files.readAllBytes(Path.of(name))) { + // Collect all non-printable bytes in an array + if (b < 32) bout.write(b); + } + // There should only be a series of CRLFs left + byte[] endings = bout.toByteArray(); + Asserts.assertTrue(endings.length > 4, "Too empty"); + Asserts.assertTrue(endings.length % 2 == 0, + "Length is " + endings.length); + for (int i = 0; i < endings.length; i += 2) { + Asserts.assertEquals(endings[i], (byte)'\r', + "Byte at " + i + " is not CR"); + Asserts.assertEquals(endings[i + 1], (byte)'\n', + "Byte at " + (i + 1) + " is not LF"); + } + } +} diff --git a/test/jdk/sun/security/tools/keytool/PKCS12Passwd.java b/test/jdk/sun/security/tools/keytool/PKCS12Passwd.java index e5a60b5c06cd8..9f381cf49bf0a 100644 --- a/test/jdk/sun/security/tools/keytool/PKCS12Passwd.java +++ b/test/jdk/sun/security/tools/keytool/PKCS12Passwd.java @@ -108,7 +108,7 @@ public static void main(String[] args) throws Exception { check("p12", "newpass", "newpass"); - // Conversely, a JKS keystore can be laoded as a PKCS12, and it follows + // Conversely, a JKS keystore can be loaded as a PKCS12, and it follows // PKCS12 rules that both passwords are changed at the same time and // some commands are rejected. diff --git a/test/jdk/sun/tools/jcmd/TestGcCounters.java b/test/jdk/sun/tools/jcmd/TestGcCounters.java new file mode 100644 index 0000000000000..3beb476c60820 --- /dev/null +++ b/test/jdk/sun/tools/jcmd/TestGcCounters.java @@ -0,0 +1,65 @@ +/* + * Copyright 2023 Alphabet LLC. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8315149 + * @summary Unit test to ensure CPU hsperf counters are published. + * @requires vm.gc.G1 + * + * @library /test/lib + * + * @run main/othervm -XX:+UsePerfData -XX:+UseStringDeduplication TestGcCounters + */ + +import static jdk.test.lib.Asserts.*; + +import jdk.test.lib.process.OutputAnalyzer; + +public class TestGcCounters { + + private static final String SUN_THREADS = "sun.threads"; + private static final String SUN_THREADS_CPUTIME = "sun.threads.cpu_time"; + + public static void main(String[] args) throws Exception { + testGcCpuCountersExist(); + } + + + /** + * jcmd -J-XX:+UsePerfData pid PerfCounter.print + */ + private static void testGcCpuCountersExist() throws Exception { + OutputAnalyzer output = JcmdBase.jcmd(new String[] {"PerfCounter.print"}); + + output.shouldHaveExitValue(0); + output.shouldContain(SUN_THREADS + ".total_gc_cpu_time"); + output.shouldContain(SUN_THREADS_CPUTIME + ".gc_conc_mark"); + output.shouldContain(SUN_THREADS_CPUTIME + ".gc_conc_refine"); + output.shouldContain(SUN_THREADS_CPUTIME + ".gc_service"); + output.shouldContain(SUN_THREADS_CPUTIME + ".gc_parallel_workers"); + output.shouldContain(SUN_THREADS_CPUTIME + ".vm"); + output.shouldContain(SUN_THREADS_CPUTIME + ".conc_dedup"); + } +} + diff --git a/test/jdk/sun/tools/jcmd/TestProcessHelper.java b/test/jdk/sun/tools/jcmd/TestProcessHelper.java index 139f21e2d9d35..73f04563cc9fb 100644 --- a/test/jdk/sun/tools/jcmd/TestProcessHelper.java +++ b/test/jdk/sun/tools/jcmd/TestProcessHelper.java @@ -54,10 +54,8 @@ * * @requires vm.flagless * @requires os.family == "linux" + * @enablePreview * @modules jdk.jcmd/sun.tools.common:+open - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool * java.base/jdk.internal.module * @library /test/lib * @build test.TestProcess diff --git a/test/jdk/tools/jimage/JImageNonAsciiNameTest.java b/test/jdk/tools/jimage/JImageNonAsciiNameTest.java index 5e478f15bec7c..c50a10539fc2e 100644 --- a/test/jdk/tools/jimage/JImageNonAsciiNameTest.java +++ b/test/jdk/tools/jimage/JImageNonAsciiNameTest.java @@ -37,12 +37,8 @@ * @summary Test non-ASCII path in custom JRE * @library ../lib * /test/lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jimage * @build tests.* * @run main/othervm JImageNonAsciiNameTest diff --git a/test/jdk/tools/jimage/JImageTest.java b/test/jdk/tools/jimage/JImageTest.java index 8c0c1a48bded6..3342c56602594 100644 --- a/test/jdk/tools/jimage/JImageTest.java +++ b/test/jdk/tools/jimage/JImageTest.java @@ -47,12 +47,8 @@ * @summary Test jimage tool * @bug 8222100 * @library ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage * jdk.jlink/jdk.tools.jlink.internal diff --git a/test/jdk/tools/jlink/DefaultProviderTest.java b/test/jdk/tools/jlink/DefaultProviderTest.java index 62cca19e937c4..3177b37666a72 100644 --- a/test/jdk/tools/jlink/DefaultProviderTest.java +++ b/test/jdk/tools/jlink/DefaultProviderTest.java @@ -42,12 +42,8 @@ * @author Jean-Francois Denise * @requires vm.compMode != "Xcomp" * @library ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.plugin * jdk.jlink/jdk.tools.jmod diff --git a/test/jdk/tools/jlink/ExplodedModuleNameTest.java b/test/jdk/tools/jlink/ExplodedModuleNameTest.java index 7cbdc93bf0e2e..69a564c7538ab 100644 --- a/test/jdk/tools/jlink/ExplodedModuleNameTest.java +++ b/test/jdk/tools/jlink/ExplodedModuleNameTest.java @@ -38,12 +38,8 @@ * @bug 8192986 * @summary Inconsistent handling of exploded modules in jlink * @library ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage diff --git a/test/jdk/tools/jlink/IntegrationTest.java b/test/jdk/tools/jlink/IntegrationTest.java index 9d92c2042ef75..e85d8f0d98443 100644 --- a/test/jdk/tools/jlink/IntegrationTest.java +++ b/test/jdk/tools/jlink/IntegrationTest.java @@ -60,12 +60,8 @@ * @summary Test integration API * @author Jean-Francois Denise * @library ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.builder * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.internal.plugins diff --git a/test/jdk/tools/jlink/JLink100Modules.java b/test/jdk/tools/jlink/JLink100Modules.java index bbcba94b51fe6..bb4f18cb4e878 100644 --- a/test/jdk/tools/jlink/JLink100Modules.java +++ b/test/jdk/tools/jlink/JLink100Modules.java @@ -35,12 +35,8 @@ * @summary Make sure that 100 modules can be linked using jlink. * @bug 8240567 * @library ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.plugin * jdk.jlink/jdk.tools.jmod diff --git a/test/jdk/tools/jlink/JLink2Test.java b/test/jdk/tools/jlink/JLink2Test.java index 47cc9bafc4f3b..1e0fe69348982 100644 --- a/test/jdk/tools/jlink/JLink2Test.java +++ b/test/jdk/tools/jlink/JLink2Test.java @@ -26,12 +26,8 @@ * @summary Test image creation * @author Jean-Francois Denise * @library ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.plugin * jdk.jlink/jdk.tools.jmod diff --git a/test/jdk/tools/jlink/JLinkDedupTestBatchSizeOne.java b/test/jdk/tools/jlink/JLinkDedupTestBatchSizeOne.java index 45ab9bf41f258..8b2dee1b45ad7 100644 --- a/test/jdk/tools/jlink/JLinkDedupTestBatchSizeOne.java +++ b/test/jdk/tools/jlink/JLinkDedupTestBatchSizeOne.java @@ -36,12 +36,8 @@ * @bug 8311591 * @library /test/lib * ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.plugin * jdk.jlink/jdk.tools.jmod diff --git a/test/jdk/tools/jlink/JLinkNegativeTest.java b/test/jdk/tools/jlink/JLinkNegativeTest.java index 493d7a370ddf1..6f88c02b0c8a1 100644 --- a/test/jdk/tools/jlink/JLinkNegativeTest.java +++ b/test/jdk/tools/jlink/JLinkNegativeTest.java @@ -28,16 +28,9 @@ * @bug 8174718 * @bug 8189671 * @author Andrei Eremeev - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.jimage + * @enablePreview + * @modules java.base/jdk.internal.jimage * java.base/jdk.internal.module - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage diff --git a/test/jdk/tools/jlink/JLinkOptionsTest.java b/test/jdk/tools/jlink/JLinkOptionsTest.java index e1f84c0872a09..95b4268069d96 100644 --- a/test/jdk/tools/jlink/JLinkOptionsTest.java +++ b/test/jdk/tools/jlink/JLinkOptionsTest.java @@ -36,12 +36,8 @@ * @summary Test jlink options * @author Jean-Francois Denise * @library ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.plugin * jdk.jlink/jdk.tools.jmod diff --git a/test/jdk/tools/jlink/JLinkPluginsTest.java b/test/jdk/tools/jlink/JLinkPluginsTest.java index b90f9d4db26fa..cd524db747a08 100644 --- a/test/jdk/tools/jlink/JLinkPluginsTest.java +++ b/test/jdk/tools/jlink/JLinkPluginsTest.java @@ -35,12 +35,8 @@ * @author Jean-Francois Denise * @requires (vm.compMode != "Xcomp" & os.maxMemory >= 2g) * @library ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage diff --git a/test/jdk/tools/jlink/JLinkTest.java b/test/jdk/tools/jlink/JLinkTest.java index 0226caf47ccae..e897badad133c 100644 --- a/test/jdk/tools/jlink/JLinkTest.java +++ b/test/jdk/tools/jlink/JLinkTest.java @@ -51,12 +51,8 @@ * @author Jean-Francois Denise * @requires (vm.compMode != "Xcomp" & os.maxMemory >= 2g) * @library ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.plugin * jdk.jlink/jdk.tools.jimage diff --git a/test/jdk/tools/jlink/ModuleNamesOrderTest.java b/test/jdk/tools/jlink/ModuleNamesOrderTest.java index a2c6f0cfe3e7d..d8fda1387d7fa 100644 --- a/test/jdk/tools/jlink/ModuleNamesOrderTest.java +++ b/test/jdk/tools/jlink/ModuleNamesOrderTest.java @@ -41,12 +41,8 @@ * @bug 8168925 * @summary MODULES property should be topologically ordered and space-separated list * @library ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage diff --git a/test/jdk/tools/jlink/NativeTest.java b/test/jdk/tools/jlink/NativeTest.java index 38bc87faabbe5..8fba7b8f699ec 100644 --- a/test/jdk/tools/jlink/NativeTest.java +++ b/test/jdk/tools/jlink/NativeTest.java @@ -26,12 +26,8 @@ * @summary Test config, cmd and lib directories of jmod. * @author Andrei Eremeev * @library ../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage diff --git a/test/jdk/tools/jlink/plugins/AddOptionsPluginTest.java b/test/jdk/tools/jlink/plugins/AddOptionsPluginTest.java index 0979edd1af4ca..acb2e65fd382f 100644 --- a/test/jdk/tools/jlink/plugins/AddOptionsPluginTest.java +++ b/test/jdk/tools/jlink/plugins/AddOptionsPluginTest.java @@ -30,12 +30,8 @@ * @summary Test the --add-options plugin * @library ../../lib * @library /test/lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage diff --git a/test/jdk/tools/jlink/plugins/CDSPluginTest.java b/test/jdk/tools/jlink/plugins/CDSPluginTest.java index d96c2eb8b7ecf..d50b1c88a2163 100644 --- a/test/jdk/tools/jlink/plugins/CDSPluginTest.java +++ b/test/jdk/tools/jlink/plugins/CDSPluginTest.java @@ -37,12 +37,8 @@ * @requires vm.cds * @library ../../lib * @library /test/lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage diff --git a/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java b/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java index 2a8ea451865a3..275043ed8d8db 100644 --- a/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java +++ b/test/jdk/tools/jlink/plugins/GenerateJLIClassesPluginTest.java @@ -42,12 +42,8 @@ * @bug 8252919 * @library ../../lib * @summary Test --generate-jli-classes plugin + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.internal.plugins * jdk.jlink/jdk.tools.jmod diff --git a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java index a487b08b5f64c..0e485bd75dd57 100644 --- a/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java +++ b/test/jdk/tools/jlink/plugins/IncludeLocalesPluginTest.java @@ -47,12 +47,8 @@ * @author Naoto Sato * @requires (vm.compMode != "Xcomp" & os.maxMemory >= 2g) * @library ../../lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.internal.plugins * jdk.jlink/jdk.tools.jlink.plugin diff --git a/test/jdk/tools/jlink/plugins/SaveJlinkArgfilesPluginTest.java b/test/jdk/tools/jlink/plugins/SaveJlinkArgfilesPluginTest.java index fe26f7e6bbbe1..207290d6cf71f 100644 --- a/test/jdk/tools/jlink/plugins/SaveJlinkArgfilesPluginTest.java +++ b/test/jdk/tools/jlink/plugins/SaveJlinkArgfilesPluginTest.java @@ -27,12 +27,8 @@ * @requires vm.jvmci * @library ../../lib * @library /test/lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage diff --git a/test/jdk/tools/jlink/plugins/StringSharingPluginTest.java b/test/jdk/tools/jlink/plugins/StringSharingPluginTest.java index 306974781306f..3979c7e833bab 100644 --- a/test/jdk/tools/jlink/plugins/StringSharingPluginTest.java +++ b/test/jdk/tools/jlink/plugins/StringSharingPluginTest.java @@ -26,6 +26,7 @@ * @summary Test StringSharingPluginTest * @author Jean-Francois Denise * @library ../../lib + * @enablePreview * @modules java.base/jdk.internal.jimage * java.base/jdk.internal.jimage.decompressor * jdk.jlink/jdk.tools.jlink.internal @@ -33,11 +34,6 @@ * jdk.jlink/jdk.tools.jlink.plugin * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.compiler * @run build tests.* * @run main StringSharingPluginTest diff --git a/test/jdk/tools/jlink/plugins/StripJavaDebugAttributesPluginTest.java b/test/jdk/tools/jlink/plugins/StripJavaDebugAttributesPluginTest.java index 5c66ccedbbab4..79a52f5728810 100644 --- a/test/jdk/tools/jlink/plugins/StripJavaDebugAttributesPluginTest.java +++ b/test/jdk/tools/jlink/plugins/StripJavaDebugAttributesPluginTest.java @@ -27,17 +27,13 @@ * @author Jean-Francois Denise * @library ../../lib * @build tests.* + * @enablePreview * @modules java.base/jdk.internal.jimage * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.internal.plugins * jdk.jlink/jdk.tools.jlink.plugin * jdk.jlink/jdk.tools.jimage * jdk.jlink/jdk.tools.jmod - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.compiler * @run main StripJavaDebugAttributesPluginTest */ @@ -49,8 +45,8 @@ import java.util.*; import java.util.stream.Stream; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; import jdk.tools.jlink.internal.ResourcePoolManager; import jdk.tools.jlink.internal.plugins.StripJavaDebugAttributesPlugin; import jdk.tools.jlink.plugin.Plugin; @@ -138,7 +134,7 @@ private ResourcePoolEntry stripDebug(Plugin debug, ResourcePoolEntry classResour } private > void checkDebugAttributes(byte[] strippedClassFile) { - ClassModel classFile = Classfile.of().parse(strippedClassFile); + ClassModel classFile = ClassFile.of().parse(strippedClassFile); for (MethodModel method : classFile.methods()) { String methodName = method.methodName().stringValue(); CodeAttribute code = method.findAttribute(Attributes.CODE).orElseThrow(); diff --git a/test/jdk/tools/jlink/plugins/VendorInfoPluginsTest.java b/test/jdk/tools/jlink/plugins/VendorInfoPluginsTest.java index 73bc3fab7e4c7..2f2c52a6c1783 100644 --- a/test/jdk/tools/jlink/plugins/VendorInfoPluginsTest.java +++ b/test/jdk/tools/jlink/plugins/VendorInfoPluginsTest.java @@ -30,12 +30,8 @@ * @summary Test the --vendor-version --vendor-url-bug plugins * @library ../../lib * @library /test/lib + * @enablePreview * @modules java.base/jdk.internal.jimage - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jmod * jdk.jlink/jdk.tools.jimage diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index 30a4c6f8cd8e5..fd62d6c7d8820 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -423,6 +423,14 @@ public Path outputBundle() { return outputDir().resolve(bundleName); } + Optional nullableOutputBundle() { + try { + return Optional.ofNullable(outputBundle()); + } catch (Exception ex) { + return Optional.empty(); + } + } + /** * Returns application layout. * @@ -749,11 +757,15 @@ public Executor.Result execute(int expectedExitCode) { if (hasArgument("--dest")) { if (isImagePackageType()) { TKit.deleteDirectoryContentsRecursive(outputDir()); - } else if (ThrowingSupplier.toSupplier(() -> TKit.deleteIfExists( - outputBundle())).get()) { - TKit.trace( - String.format("Deleted [%s] file before running jpackage", - outputBundle())); + } else { + nullableOutputBundle().ifPresent(path -> { + if (ThrowingSupplier.toSupplier(() -> TKit.deleteIfExists( + path)).get()) { + TKit.trace(String.format( + "Deleted [%s] file before running jpackage", + path)); + } + }); } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java index 834948b830ae8..d597c62d83f17 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -582,7 +582,9 @@ public void accept(Action action, JPackageCommand cmd) { if (expectedJPackageExitCode == 0) { TKit.assertFileExists(cmd.outputBundle()); } else { - TKit.assertPathExists(cmd.outputBundle(), false); + cmd.nullableOutputBundle().ifPresent(outputBundle -> { + TKit.assertPathExists(outputBundle, false); + }); } verifyPackageBundle(cmd, result); break; diff --git a/test/jdk/tools/jpackage/macosx/MacAppStoreJlinkOptionsTest.java b/test/jdk/tools/jpackage/macosx/MacAppStoreJlinkOptionsTest.java index b3cefa7d38fe2..8b1cec04ab9c7 100644 --- a/test/jdk/tools/jpackage/macosx/MacAppStoreJlinkOptionsTest.java +++ b/test/jdk/tools/jpackage/macosx/MacAppStoreJlinkOptionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ * @build MacAppStoreJLinkOptionsTest * @modules jdk.jpackage/jdk.jpackage.internal * @requires (os.family == "mac") - * @run main/othervm -Xmx512m jdk.jpackage.test.Main + * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=MacAppStoreJLinkOptionsTest */ public class MacAppStoreJLinkOptionsTest { diff --git a/test/jdk/tools/jpackage/share/AppImagePackageTest.java b/test/jdk/tools/jpackage/share/AppImagePackageTest.java index 4f229e5c93459..949e68faae2ee 100644 --- a/test/jdk/tools/jpackage/share/AppImagePackageTest.java +++ b/test/jdk/tools/jpackage/share/AppImagePackageTest.java @@ -25,6 +25,7 @@ import java.nio.file.Files; import java.io.IOException; import java.util.List; +import jdk.jpackage.internal.AppImageFile; import jdk.jpackage.test.Annotations.Parameter; import jdk.jpackage.test.TKit; import jdk.jpackage.test.JPackageCommand; @@ -102,6 +103,55 @@ public static void testEmpty(boolean withIcon) throws IOException { // default: {CREATE, UNPACK, VERIFY}, but we can't verify foreign image } + @Test + public static void testBadAppImage() throws IOException { + Path appImageDir = TKit.createTempDirectory("appimage"); + Files.createFile(appImageDir.resolve("foo")); + configureAppImageWithoutJPackageXMLFile(appImageDir).addInitializer( + cmd -> { + cmd.removeArgumentWithValue("--name"); + }).run(Action.CREATE); + } + + @Test + public static void testBadAppImage2() throws IOException { + Path appImageDir = TKit.createTempDirectory("appimage"); + Files.createFile(appImageDir.resolve("foo")); + configureAppImageWithoutJPackageXMLFile(appImageDir).run(Action.CREATE); + } + + @Test + public static void testBadAppImage3() throws IOException { + Path appImageDir = TKit.createTempDirectory("appimage"); + + JPackageCommand appImageCmd = JPackageCommand.helloAppImage(). + setFakeRuntime().setArgumentValue("--dest", appImageDir); + + configureAppImageWithoutJPackageXMLFile(appImageCmd.outputBundle()). + addRunOnceInitializer(() -> { + appImageCmd.execute(); + Files.delete(AppImageFile.getPathInAppImage(appImageCmd. + outputBundle())); + }).run(Action.CREATE); + } + + private static PackageTest configureAppImageWithoutJPackageXMLFile( + Path appImageDir) { + return new PackageTest() + .addInitializer(cmd -> { + cmd.saveConsoleOutput(true); + cmd.addArguments("--app-image", appImageDir); + cmd.removeArgumentWithValue("--input"); + cmd.ignoreDefaultVerbose(true); // no "--verbose" option + }) + .addBundleVerifier((cmd, result) -> { + TKit.assertTextStream( + "Error: Missing .jpackage.xml file in app-image dir").apply( + result.getOutput().stream()); + }) + .setExpectedExitCode(1); + } + private static Path iconPath(String name) { return TKit.TEST_SRC_ROOT.resolve(Path.of("resources", name + TKit.ICON_SUFFIX)); diff --git a/test/jdk/tools/launcher/Arrrghs.java b/test/jdk/tools/launcher/Arrrghs.java index 11a6ab0a52024..efc9505284257 100644 --- a/test/jdk/tools/launcher/Arrrghs.java +++ b/test/jdk/tools/launcher/Arrrghs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -541,12 +541,12 @@ void testMainMethod() throws FileNotFoundException { createJar(new File("some.jar"), new File("Foo"), "public static int main(String[] args){return 1;}"); tr = doExec(javaCmd, "-jar", "some.jar"); - tr.contains("Error: Main method must return a value of type void in class Foo"); + tr.contains("Error: Main method not found in class Foo"); if (!tr.testStatus) System.out.println(tr); // use classpath to check tr = doExec(javaCmd, "-cp", "some.jar", "Foo"); - tr.contains("Error: Main method must return a value of type void in class Foo"); + tr.contains("Error: Main method not found in class Foo"); if (!tr.testStatus) System.out.println(tr); @@ -567,12 +567,12 @@ void testMainMethod() throws FileNotFoundException { createJar(new File("some.jar"), new File("Foo"), "public void main(String[] args){}"); tr = doExec(javaCmd, "-jar", "some.jar"); - tr.contains("Error: Main method is not static in class Foo"); + tr.contains("Error: Main method not found in class Foo"); if (!tr.testStatus) System.out.println(tr); // use classpath to check tr = doExec(javaCmd, "-cp", "some.jar", "Foo"); - tr.contains("Error: Main method is not static in class Foo"); + tr.contains("Error: Main method not found in class Foo"); if (!tr.testStatus) System.out.println(tr); diff --git a/test/jdk/tools/launcher/InstanceMainTest.java b/test/jdk/tools/launcher/InstanceMainTest.java index 05973557fc35f..08b5cb48dbbec 100644 --- a/test/jdk/tools/launcher/InstanceMainTest.java +++ b/test/jdk/tools/launcher/InstanceMainTest.java @@ -42,13 +42,13 @@ static void main(String[] args) { } """, - // static dominating instance + // instance dominating static """ class MainClass { void main(String[] args) { - throw new AssertionError(); } static void main() { + throw new AssertionError(); } } """, @@ -81,12 +81,12 @@ static void main(String[] args) { } """, - // unnamed class static dominating instance + // main with args dominating main without args """ void main(String[] args) { - throw new AssertionError(); } static void main() { + throw new AssertionError(); } """, @@ -105,15 +105,15 @@ void main() { } """, - // instance main dominating super static + // instance main with args dominating super """ class MainClass extends SuperClass { void main() { + throw new AssertionError(); } } class SuperClass { void main(String[] args) { - throw new AssertionError(); } } """, diff --git a/test/jdk/tools/launcher/modules/basic/LauncherErrors.java b/test/jdk/tools/launcher/modules/basic/LauncherErrors.java index b79238218b379..dd5157fa6127e 100644 --- a/test/jdk/tools/launcher/modules/basic/LauncherErrors.java +++ b/test/jdk/tools/launcher/modules/basic/LauncherErrors.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,9 +92,10 @@ public void testErrorMessage() throws Exception { ProcessTools.executeTestJava("-Djava.security.manager", "--module-path", dir, "--module", mid) .outputTo(System.out) .errorTo(System.out) - .shouldContain("Error: Unable to initialize main class " + MAIN_CLASS + " in module " + TEST_MODULE) - .shouldContain("Caused by: java.security.AccessControlException: access denied") + .shouldContain("Error: Unable to load main class " + MAIN_CLASS + " in module " + TEST_MODULE) + .shouldContain("Caused by: java.security.AccessControlException") .shouldNotHaveExitValue(0); + } } diff --git a/test/jdk/tools/lib/tests/JImageValidator.java b/test/jdk/tools/lib/tests/JImageValidator.java index 81b543f590752..125afb9d24cf1 100644 --- a/test/jdk/tools/lib/tests/JImageValidator.java +++ b/test/jdk/tools/lib/tests/JImageValidator.java @@ -30,9 +30,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Properties; -import jdk.internal.classfile.ClassHierarchyResolver; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassHierarchyResolver; -import jdk.internal.classfile.Classfile; import jdk.internal.jimage.BasicImageReader; import jdk.internal.jimage.ImageLocation; @@ -223,10 +223,10 @@ public long getModuleLauncherExecutionTime() { } public static void readClass(byte[] clazz) throws IOException{ - var errors = Classfile.of().parse(clazz).verify( + var errors = ClassFile.of( //resolution of all classes as interfaces cancels assignability verification - cls -> ClassHierarchyResolver.ClassHierarchyInfo.ofInterface(), - null); + ClassFile.ClassHierarchyResolverOption.of(cls -> ClassHierarchyResolver.ClassHierarchyInfo.ofInterface())) + .verify(clazz); if (!errors.isEmpty()) { var itr = errors.iterator(); var thrown = itr.next(); diff --git a/test/langtools/jdk/javadoc/doclet/testDocletExample/TestDocletExample.java b/test/langtools/jdk/javadoc/doclet/testDocletExample/TestDocletExample.java index 0f03248d7335f..f210b940b6060 100644 --- a/test/langtools/jdk/javadoc/doclet/testDocletExample/TestDocletExample.java +++ b/test/langtools/jdk/javadoc/doclet/testDocletExample/TestDocletExample.java @@ -50,8 +50,12 @@ public class TestDocletExample extends TestRunner { public static void main(String... args) throws Exception { - var t = new TestDocletExample(); - t.runTests(m -> new Object[] { Path.of(m.getName()) }); + try { + var t = new TestDocletExample(); + t.runTests(m -> new Object[] { Path.of(m.getName()) }); + } catch (SnippetUtils.ConfigurationException e) { + System.err.println("NOTE: " + e.getMessage() + "; test skipped"); + } } SnippetUtils snippets; diff --git a/test/langtools/jdk/javadoc/doclet/testImplicitlyDeclaredClasses/TestImplicitlyDeclaredClasses.java b/test/langtools/jdk/javadoc/doclet/testImplicitlyDeclaredClasses/TestImplicitlyDeclaredClasses.java new file mode 100644 index 0000000000000..80b2a0685ff47 --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testImplicitlyDeclaredClasses/TestImplicitlyDeclaredClasses.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8308715 + * @library /tools/lib ../../lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.javadoc/jdk.javadoc.internal.tool + * @build javadoc.tester.* toolbox.ToolBox toolbox.ModuleBuilder builder.ClassBuilder + * @run main/othervm TestImplicitlyDeclaredClasses + */ + +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javadoc.tester.JavadocTester; +import toolbox.ToolBox; + +public class TestImplicitlyDeclaredClasses extends JavadocTester { + + private final ToolBox tb = new ToolBox(); + + public static void main(String... args) throws Exception { + new TestImplicitlyDeclaredClasses().runTests(); + } + + @Test + public void test(Path base) throws IOException { + int i = 0; + for (Method main : mainMethods()) + for (Method otherMethod : otherMethods()) { + var methods = List.of(main, otherMethod); + var index = String.valueOf(i++); + var src = base.resolve(Path.of("src-" + index, "MyClass.java")); + tb.writeFile(src, methods.stream() + .map(Object::toString) + .collect(Collectors.joining("\n"))); + // TODO: remove preview-related options once "Implicitly Declared + // Classes and Instance Main Methods" has been standardized + javadoc("--enable-preview", "--source=" + Runtime.version().feature(), + "-d", base.resolve("out-" + index).toString(), + src.toString()); + + checkExit(Exit.OK); + // there must be no warning on undocumented (default) constructor + checkOutput(Output.OUT, false, """ + warning: use of default constructor, which does not provide a comment"""); + // the (default) constructor must neither be linked nor mentioned + checkOutput("MyClass.html", false, "%3Cinit%3E"); + checkOutput("MyClass.html", false, "Constructor"); + // a method that is public, protected or declared with package + // access must either be documented or, if it doesn't have a + // comment, must be warned about + int nWarnedMethods = 0; + for (var m : methods) { + if (m.accessModifier.compareTo(Access.PACKAGE) >= 0) { + if (m.comment.isEmpty()) { + checkOutput(Output.OUT, true, "warning: no comment\n" + m); + nWarnedMethods++; + } else { + checkOutput("MyClass.html", true, + """ + %s""" + .formatted(m.returnValue), + """ + %s""" + .formatted(m.name)); + } + } + } + // there must be no warning on uncommented implicitly declared class + // + // Here's a non-obvious part. A warning message for an uncommented + // class is the same as that of a method. Moreover, since the class + // is implicit, its AST position is that of the first method. + // + // Put differently, if the class is uncommented, the warning about + // it is indistinguishable from that of the first method, if that + // method is uncommented. + // + // Here's how this check works: if an undocumented class warning + // is present, then the total count of undocumented element warnings + // is one greater than that of undocumented methods. + // + // Of course, it's possible, although seemingly unlikely, that + // this check passes, when it should fail: the warning for class + // is generated, but the warning for the first method is not. + // Numbers are equal, test passes. + checking("uncommented class warning"); + long all = Pattern.compile("warning: no comment") + .matcher(getOutput(Output.OUT)) + .results() + .count(); + if (all != nWarnedMethods) { + failed("%d/%d".formatted(all, nWarnedMethods)); + } else { + passed(""); + } + } + } + + private Iterable mainMethods() { + return generate( + List.of("/** main comment */", ""), + // adding PRIVATE will increase test output size and run time + EnumSet.of(Access.PUBLIC, Access.PROTECTED, Access.PACKAGE), + // adding final will increase test output size and run time + List.of("static", ""), + List.of("void"), + "main", + List.of("String[] args", "") + ); + } + + private Iterable otherMethods() { + return generate( + List.of("/** other comment */", ""), + // adding PROTECTED or PUBLIC will increase test output size and run time + EnumSet.of(Access.PACKAGE, Access.PRIVATE), + // adding final or static will increase test output size and run time + List.of(""), + List.of("void"), + "other", + List.of("")); + } + + private Iterable generate(Iterable comments, + Iterable accessModifiers, + Iterable otherModifiers, + Iterable returnValues, + String name, + Iterable args) { + var methods = new ArrayList(); + for (var comment : comments) + for (var accessModifier : accessModifiers) + for (var otherModifier : otherModifiers) + for (var returnValue : returnValues) + for (var arg : args) + methods.add(new Method(comment, accessModifier, + otherModifier, returnValue, name, arg)); + return methods; + } + + enum Access {PRIVATE, PACKAGE, PROTECTED, PUBLIC} + + record Method(String comment, + Access accessModifier, + String otherModifier, + String returnValue, + String name, + String arg) { + + @Override + public String toString() { + return Stream.of(comment, access(accessModifier), otherModifier, + returnValue, name + "(" + arg + ") { }") + .map(Object::toString) + .filter(s -> !s.isEmpty()) + .collect(Collectors.joining(" ")); + } + } + + private static String access(Access accessModifier) { + return switch (accessModifier) { + case PRIVATE -> "private"; + case PACKAGE -> ""; + case PROTECTED -> "protected"; + case PUBLIC -> "public"; + }; + } +} \ No newline at end of file diff --git a/test/langtools/jdk/javadoc/doclet/testLegalNotices/TestLegalNotices.java b/test/langtools/jdk/javadoc/doclet/testLegalNotices/TestLegalNotices.java index 148accdbfd4af..29da4d989720a 100644 --- a/test/langtools/jdk/javadoc/doclet/testLegalNotices/TestLegalNotices.java +++ b/test/langtools/jdk/javadoc/doclet/testLegalNotices/TestLegalNotices.java @@ -111,6 +111,8 @@ void test(Path base, Path src, Path legal, OptionKind optionKind, IndexKind inde super.out.println(" Found: " + foundFiles); if (foundFiles.equals(expectFiles)) { passed("Found all expected files"); + } else { + failed("Did not find all expected files"); } // See JDK-8306980 @@ -168,4 +170,4 @@ Set listFiles(Path dir, Predicate filter) throws IOException { return files; } } -} \ No newline at end of file +} diff --git a/test/langtools/jdk/javadoc/doclet/testUnnamed/TestUnnamed.java b/test/langtools/jdk/javadoc/doclet/testUnnamed/TestImplicit.java similarity index 91% rename from test/langtools/jdk/javadoc/doclet/testUnnamed/TestUnnamed.java rename to test/langtools/jdk/javadoc/doclet/testUnnamed/TestImplicit.java index e9658cd4071b9..fa9a535902f87 100644 --- a/test/langtools/jdk/javadoc/doclet/testUnnamed/TestUnnamed.java +++ b/test/langtools/jdk/javadoc/doclet/testUnnamed/TestImplicit.java @@ -24,11 +24,11 @@ /* * @test * @bug 8309595 - * @summary Allow javadoc to process unnamed classes + * @summary Allow javadoc to process implicit classes * @library /tools/lib ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool * @build toolbox.ToolBox javadoc.tester.* - * @run main TestUnnamed + * @run main TestImplicit */ import java.io.File; @@ -39,18 +39,18 @@ import javadoc.tester.JavadocTester; import toolbox.ToolBox; -public class TestUnnamed extends JavadocTester { +public class TestImplicit extends JavadocTester { private static final String thisVersion = System.getProperty("java.specification.version"); private static final ToolBox tb = new ToolBox(); public static void main(String... args) throws Exception { - new TestUnnamed().runTests(); + new TestImplicit().runTests(); } @Test - public void testUnnamed(Path base) throws IOException { + public void testImplicit(Path base) throws IOException { String className = "Sample"; Files.createDirectories(base); Path out = base.resolve("out"); diff --git a/test/langtools/jdk/jshell/JdiStarterTest.java b/test/langtools/jdk/jshell/JdiStarterTest.java new file mode 100644 index 0000000000000..0beee9ceda164 --- /dev/null +++ b/test/langtools/jdk/jshell/JdiStarterTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8319311 + * @summary Tests JdiStarter + * @modules jdk.jshell/jdk.jshell jdk.jshell/jdk.jshell.spi jdk.jshell/jdk.jshell.execution + * @run testng JdiStarterTest + */ + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.testng.annotations.Test; +import jdk.jshell.JShell; +import jdk.jshell.SnippetEvent; +import jdk.jshell.execution.JdiDefaultExecutionControl.JdiStarter; +import jdk.jshell.execution.JdiDefaultExecutionControl.JdiStarter.TargetDescription; +import jdk.jshell.execution.JdiExecutionControlProvider; +import jdk.jshell.execution.JdiInitiator; +import static org.testng.Assert.assertEquals; + +@Test +public class JdiStarterTest { + + public void jdiStarter() { + // turn on logging of launch failures + Logger.getLogger("jdk.jshell.execution").setLevel(Level.ALL); + JdiStarter starter = (env, parameters, port) -> { + assertEquals(parameters.get(JdiExecutionControlProvider.PARAM_HOST_NAME), ""); + assertEquals(parameters.get(JdiExecutionControlProvider.PARAM_LAUNCH), "false"); + assertEquals(parameters.get(JdiExecutionControlProvider.PARAM_REMOTE_AGENT), "jdk.jshell.execution.RemoteExecutionControl"); + assertEquals(parameters.get(JdiExecutionControlProvider.PARAM_TIMEOUT), "5000"); + JdiInitiator jdii = + new JdiInitiator(port, + env.extraRemoteVMOptions(), + "jdk.jshell.execution.RemoteExecutionControl", + false, + null, + 5000, + Collections.emptyMap()); + return new TargetDescription(jdii.vm(), jdii.process()); + }; + JShell jshell = + JShell.builder() + .executionEngine(new JdiExecutionControlProvider(starter), Map.of()) + .build(); + List evts = jshell.eval("1 + 2"); + assertEquals(1, evts.size()); + assertEquals("3", evts.get(0).value()); + } +} diff --git a/test/langtools/jdk/jshell/LocalExecutionClassPathTest.java b/test/langtools/jdk/jshell/LocalExecutionClassPathTest.java new file mode 100644 index 0000000000000..6511c9a17fb0a --- /dev/null +++ b/test/langtools/jdk/jshell/LocalExecutionClassPathTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8314327 + * @summary Verify the "--class-path" flag works properly in local execution mode + * @library /tools/lib + * @modules + * jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * @build toolbox.ToolBox toolbox.JavacTask LocalExecutionTestSupport + * @run testng/othervm LocalExecutionClassPathTest + */ + +import java.util.Locale; +import org.testng.annotations.Test; + +public class LocalExecutionClassPathTest extends LocalExecutionTestSupport { + + @Override + public void test(Locale locale, boolean defaultStartUp, String[] args, String startMsg, ReplTest... tests) { + + // Set local execution with context class loader + args = this.prependArgs(args, + "--execution", "local", + "--class-path", this.classesDir.toString()); + + // Verify MyClass can be found by both the compiler and the execution engine + super.test(locale, defaultStartUp, args, startMsg, tests); + } + + @Test + public void verifyMyClassFoundOnClassPath() { + test(new String[] { "--no-startup" }, + a -> assertCommand(a, "test.MyClass.class", "$1 ==> class test.MyClass") + ); + } +} diff --git a/test/langtools/jdk/jshell/LocalExecutionContextLoaderParentTest.java b/test/langtools/jdk/jshell/LocalExecutionContextLoaderParentTest.java new file mode 100644 index 0000000000000..e01ee879a8c82 --- /dev/null +++ b/test/langtools/jdk/jshell/LocalExecutionContextLoaderParentTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8314327 + * @summary Verify function of LocalExecutionControlProvider createExecutionControl() method override + * @library /tools/lib + * @modules + * jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * @build toolbox.ToolBox toolbox.JavacTask LocalExecutionTestSupport + * @run testng/othervm LocalExecutionContextLoaderParentTest + */ + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Locale; +import java.util.Map; +import java.nio.file.Files; + +import jdk.jshell.execution.LocalExecutionControl; +import jdk.jshell.execution.LocalExecutionControlProvider; +import jdk.jshell.spi.ExecutionControl; +import jdk.jshell.spi.ExecutionControlProvider; +import jdk.jshell.spi.ExecutionEnv; + +import org.testng.annotations.Test; +import org.testng.annotations.BeforeTest; + +public class LocalExecutionContextLoaderParentTest extends LocalExecutionTestSupport { + + @BeforeTest + public void installParentTestProvider() throws IOException { + Path dir = createSubdir(classesDir, "META-INF/services"); + Files.write(dir.resolve(ExecutionControlProvider.class.getName()), + Arrays.asList(ParentTestExecutionControlProvider.class.getName())); + } + + @Override + public void test(Locale locale, boolean defaultStartUp, String[] args, String startMsg, ReplTest... tests) { + + // Make test.MyClass visible to the context class loader + final URL classesDirURL; + try { + classesDirURL = this.classesDir.toUri().toURL(); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + Thread.currentThread().setContextClassLoader(new URLClassLoader(new URL[] { classesDirURL })); + + // Set local execution with context class loader as parent loader + args = this.prependArgs(args, "--execution", "parentTest"); + + // Verify the execution engine can find MyClass (we don't care whether the compiler can find it in this test) + super.test(locale, defaultStartUp, args, startMsg, tests); + } + + @Test + public void verifyMyClassFoundByExecutionEngine() { + test(new String[] { "--no-startup" }, + a -> assertCommand(a, "Class.forName(\"test.MyClass\").getField(\"FOO\").get(null)", "$1 ==> \"bar\"") + ); + } + +// ParentTestExecutionControlProvider + + public static class ParentTestExecutionControlProvider extends LocalExecutionControlProvider { + + @Override + public String name() { + return "parentTest"; + } + + @Override + public ExecutionControl createExecutionControl(ExecutionEnv env, Map parameters) { + return new LocalExecutionControl(Thread.currentThread().getContextClassLoader()); + } + } +} diff --git a/test/langtools/jdk/jshell/LocalExecutionTestSupport.java b/test/langtools/jdk/jshell/LocalExecutionTestSupport.java new file mode 100644 index 0000000000000..6c6e122dfa916 --- /dev/null +++ b/test/langtools/jdk/jshell/LocalExecutionTestSupport.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.testng.annotations.BeforeTest; + +import toolbox.JavacTask; +import toolbox.TestRunner; +import toolbox.ToolBox; + +/* + * This class installs a class in a temporary diretory so we can test + * finding classes that are not visible to the system class loader. + */ +public class LocalExecutionTestSupport extends ReplToolTesting { + + public static final String MY_CLASS_SOURCE = """ + package test; + public class MyClass { + public static final String FOO = "bar"; + }"""; + + protected final ToolBox tb = new ToolBox(); + + protected Path baseDir; // base working directory + protected Path sourcesDir; // sources directory + protected Path classesDir; // classes directory + + // Install file "test/MyClass.class" in some temporary directory somewhere + @BeforeTest + public void installMyClass() throws IOException { + + // Create directories + baseDir = Files.createTempDirectory(getClass().getSimpleName()).toAbsolutePath(); + sourcesDir = createWorkSubdir("sources"); + classesDir = createWorkSubdir("classes"); + + // Create source file + tb.writeJavaFiles(sourcesDir, MY_CLASS_SOURCE); + + // Compile source file + new JavacTask(tb) + .outdir(classesDir) + .files(sourcesDir.resolve("test/MyClass.java")) + .run(); + } + + protected Path createWorkSubdir(String name) throws IOException { + return createSubdir(baseDir, name); + } + + protected Path createSubdir(Path base, String name) throws IOException { + Path dir = base.resolve(name); + Files.createDirectories(dir); + return dir; + } + + protected String[] prependArgs(String[] args, String... prepends) { + String[] newArgs = new String[prepends.length + args.length]; + System.arraycopy(prepends, 0, newArgs, 0, prepends.length); + System.arraycopy(args, 0, newArgs, prepends.length, args.length); + return newArgs; + } +} diff --git a/test/langtools/lib/annotations/annotations/classfile/ClassfileInspector.java b/test/langtools/lib/annotations/annotations/classfile/ClassfileInspector.java index 8707d48e3114a..d6219dbff119f 100644 --- a/test/langtools/lib/annotations/annotations/classfile/ClassfileInspector.java +++ b/test/langtools/lib/annotations/annotations/classfile/ClassfileInspector.java @@ -28,8 +28,8 @@ import java.util.ArrayList; import java.util.List; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; /** * A class providing utilities for writing tests that inspect class @@ -1173,7 +1173,7 @@ public static ClassModel getClassFile(String name, final URL url = host.getResource(name); assert url != null; try (InputStream in = url.openStream()) { - return Classfile.of().parse(in.readAllBytes()); + return ClassFile.of().parse(in.readAllBytes()); } } diff --git a/test/langtools/tools/javac/4241573/T4241573.java b/test/langtools/tools/javac/4241573/T4241573.java index f6b6acb83470b..93164bad57f2d 100644 --- a/test/langtools/tools/javac/4241573/T4241573.java +++ b/test/langtools/tools/javac/4241573/T4241573.java @@ -25,17 +25,13 @@ * @test * @bug 4241573 * @summary SourceFile attribute includes full path - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.Attributes; +import java.lang.classfile.attribute.*; import java.io.*; import java.util.*; import java.util.jar.*; @@ -112,7 +108,7 @@ else if (expect.containsAll(found)) void verifySourceFileAttribute(File f) { System.err.println("verify: " + f); try { - ClassModel cf = Classfile.of().parse(f.toPath()); + ClassModel cf = ClassFile.of().parse(f.toPath()); SourceFileAttribute sfa = cf.findAttribute(Attributes.SOURCE_FILE).orElseThrow(); String found = sfa.sourceFile().stringValue(); String expect = f.getName().replaceAll("([$.].*)?\\.class", ".java"); diff --git a/test/langtools/tools/javac/6341866/T6341866.java b/test/langtools/tools/javac/6341866/T6341866.java index c04653ed58d0c..33df081c6ba76 100644 --- a/test/langtools/tools/javac/6341866/T6341866.java +++ b/test/langtools/tools/javac/6341866/T6341866.java @@ -67,6 +67,7 @@ enum ImplicitType { enum AnnoType { NONE, // no annotation processing + SERVICE, // implicit annotation processing, via ServiceLoader SPECIFY // explicit annotation processing }; @@ -98,14 +99,14 @@ static boolean test(ImplicitType implicitType, AnnoType annoType) throws IOExcep processorServices.delete(); List opts = new ArrayList(); - opts.addAll(Arrays.asList("-d", ".", - "-sourcepath", testSrc, - "-classpath", testClasses, - "-proc:full")); + opts.addAll(Arrays.asList("-d", ".", "-sourcepath", testSrc, "-classpath", testClasses, "-Xlint:-options")); if (implicitType.opt != null) opts.add(implicitType.opt); switch (annoType) { + case SERVICE: + createProcessorServices(Anno.class.getName()); + break; case SPECIFY: opts.addAll(Arrays.asList("-processor", Anno.class.getName())); break; @@ -144,6 +145,9 @@ static boolean test(ImplicitType implicitType, AnnoType annoType) throws IOExcep String expectKey = null; if (implicitType == ImplicitType.OPT_UNSET) { switch (annoType) { + case SERVICE: + expectKey = "compiler.warn.proc.use.proc.or.implicit"; + break; case SPECIFY: expectKey = "compiler.warn.proc.use.implicit"; break; diff --git a/test/langtools/tools/javac/7003595/T7003595.java b/test/langtools/tools/javac/7003595/T7003595.java index 517b106457153..94fb0c4b09c6c 100644 --- a/test/langtools/tools/javac/7003595/T7003595.java +++ b/test/langtools/tools/javac/7003595/T7003595.java @@ -25,19 +25,15 @@ * @test * @bug 7003595 * @summary IncompatibleClassChangeError with unreferenced local class with subclass - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.file */ import com.sun.source.util.JavacTask; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import com.sun.tools.javac.api.JavacTool; import java.io.File; @@ -162,7 +158,7 @@ void verifyBytecode(JavaSource source) { String filename = cks[i].getClassfileName(cnames, cks, i); File compiledTest = new File(filename + ".class"); try { - ClassModel cf = Classfile.of().parse(compiledTest.toPath()); + ClassModel cf = ClassFile.of().parse(compiledTest.toPath()); if (cf == null) { throw new Error("Classfile not found: " + filename); } diff --git a/test/langtools/tools/javac/7153958/CPoolRefClassContainingInlinedCts.java b/test/langtools/tools/javac/7153958/CPoolRefClassContainingInlinedCts.java index ed3d095be2faf..cff6e774a2f3d 100644 --- a/test/langtools/tools/javac/7153958/CPoolRefClassContainingInlinedCts.java +++ b/test/langtools/tools/javac/7153958/CPoolRefClassContainingInlinedCts.java @@ -25,19 +25,15 @@ * @test * @bug 7153958 8073372 * @summary add constant pool reference to class containing inlined constants - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile pkg/ClassToBeStaticallyImportedA.java pkg/ClassToBeStaticallyImportedB.java CPoolRefClassContainingInlinedCts.java * @run main CPoolRefClassContainingInlinedCts */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.ClassEntry; -import jdk.internal.classfile.constantpool.PoolEntry; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.ClassEntry; +import java.lang.classfile.constantpool.PoolEntry; import java.io.File; import java.io.IOException; @@ -74,7 +70,7 @@ void checkReferences() throws IOException { File testClasses = new File(System.getProperty("test.classes")); File file = new File(testClasses, CPoolRefClassContainingInlinedCts.class.getName() + ".class"); - ClassModel classFile = Classfile.of().parse(file.toPath()); + ClassModel classFile = ClassFile.of().parse(file.toPath()); for (PoolEntry cpInfo : classFile.constantPool()) { if (cpInfo instanceof ClassEntry classEntry) { checkClassName(classEntry.asInternalName()); diff --git a/test/langtools/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java b/test/langtools/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java index b5d3c8b55b55f..e81db00e5df04 100644 --- a/test/langtools/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java +++ b/test/langtools/tools/javac/7166455/CheckACC_STRICTFlagOnclinitTest.java @@ -25,12 +25,7 @@ * @test * @bug 7166455 * @summary javac doesn't set ACC_STRICT bit on for strictfp class - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @modules jdk.jdeps/com.sun.tools.classfile * @compile -source 16 -target 16 CheckACC_STRICTFlagOnclinitTest.java * @run main CheckACC_STRICTFlagOnclinitTest */ @@ -39,7 +34,13 @@ import java.util.List; import java.io.File; import java.io.IOException; -import jdk.internal.classfile.*; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.Descriptor; +import com.sun.tools.classfile.Descriptor.InvalidDescriptor; +import com.sun.tools.classfile.Method; + +import static com.sun.tools.classfile.AccessFlags.ACC_STRICT; public strictfp class CheckACC_STRICTFlagOnclinitTest { private static final String AssertionErrorMessage = @@ -64,11 +65,13 @@ void m21() {} private List errors = new ArrayList<>(); - public static void main(String[] args) throws IOException { + public static void main(String[] args) + throws IOException, ConstantPoolException, InvalidDescriptor { new CheckACC_STRICTFlagOnclinitTest().run(); } - private void run() throws IOException { + private void run() + throws IOException, ConstantPoolException, InvalidDescriptor { String testClasses = System.getProperty("test.classes"); check(testClasses, "CheckACC_STRICTFlagOnclinitTest.class", @@ -83,18 +86,37 @@ private void run() throws IOException { } } - void check(String dir, String... fileNames) throws IOException{ + void check(String dir, String... fileNames) + throws + IOException, + ConstantPoolException, + Descriptor.InvalidDescriptor { for (String fileName : fileNames) { - ClassModel classFileToCheck = Classfile.of().parse(new File(dir, fileName).toPath()); + ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName)); - for (MethodModel method : classFileToCheck.methods()) { - if ((method.flags().flagsMask() & Classfile.ACC_STRICT) == 0) { + for (Method method : classFileToCheck.methods) { + if ((method.access_flags.flags & ACC_STRICT) == 0) { errors.add(String.format(offendingMethodErrorMessage, - method.methodName().stringValue(), - classFileToCheck.thisClass().asInternalName())); + method.getName(classFileToCheck.constant_pool), + classFileToCheck.getName())); } } } } +// this version of the code can be used when ClassFile API in not in a preview +// void check(String dir, String... fileNames) throws IOException{ +// for (String fileName : fileNames) { +// ClassModel classFileToCheck = ClassFile.of().parse(new File(dir, fileName).toPath()); +// +// for (MethodModel method : classFileToCheck.methods()) { +// if ((method.flags().flagsMask() & ClassFile.ACC_STRICT) == 0) { +// errors.add(String.format(offendingMethodErrorMessage, +// method.methodName().stringValue(), +// classFileToCheck.thisClass().asInternalName())); +// } +// } +// } +// } + } diff --git a/test/langtools/tools/javac/8000518/DuplicateConstantPoolEntry.java b/test/langtools/tools/javac/8000518/DuplicateConstantPoolEntry.java index cd640524d62bd..eee423e48a86e 100644 --- a/test/langtools/tools/javac/8000518/DuplicateConstantPoolEntry.java +++ b/test/langtools/tools/javac/8000518/DuplicateConstantPoolEntry.java @@ -26,18 +26,15 @@ * @bug 8000518 * @summary Javac generates duplicate name_and_type constant pool entry for * class BinaryOpValueExp.java - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @run main DuplicateConstantPoolEntry */ import com.sun.source.util.JavacTask; -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.ConstantPool; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.ConstantPool; +import java.lang.classfile.constantpool.PoolEntry; import java.io.File; import java.io.IOException; import java.net.URI; @@ -47,7 +44,6 @@ import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; import javax.tools.ToolProvider; -import jdk.internal.classfile.constantpool.PoolEntry; /* * This bug was reproduced having two classes B and C referenced from a class A @@ -95,7 +91,7 @@ void generateFilesNeeded() throws Exception { void checkReference() throws IOException { File file = new File("A.class"); - ClassModel classFile = Classfile.of().parse(file.toPath()); + ClassModel classFile = ClassFile.of().parse(file.toPath()); ConstantPool constantPool = classFile.constantPool(); for (PoolEntry pe1 : constantPool) { for (PoolEntry pe2 : constantPool) { diff --git a/test/langtools/tools/javac/8005931/CheckACC_STRICTFlagOnPkgAccessClassTest.java b/test/langtools/tools/javac/8005931/CheckACC_STRICTFlagOnPkgAccessClassTest.java index 5bd67b2b87e25..de8cdbc5af3a9 100644 --- a/test/langtools/tools/javac/8005931/CheckACC_STRICTFlagOnPkgAccessClassTest.java +++ b/test/langtools/tools/javac/8005931/CheckACC_STRICTFlagOnPkgAccessClassTest.java @@ -25,12 +25,8 @@ * @test * @bug 8005931 * @summary javac doesn't set ACC_STRICT for classes with package access - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @run main CheckACC_STRICTFlagOnPkgAccessClassTest */ @@ -45,7 +41,7 @@ import javax.tools.SimpleJavaFileObject; import javax.tools.ToolProvider; import com.sun.source.util.JavacTask; -import jdk.internal.classfile.*; +import java.lang.classfile.*; public class CheckACC_STRICTFlagOnPkgAccessClassTest { @@ -93,10 +89,10 @@ private void compile(JavaCompiler comp) { } void check() throws IOException { - ClassModel classFileToCheck = Classfile.of().parse(new File("Test.class").toPath()); + ClassModel classFileToCheck = ClassFile.of().parse(new File("Test.class").toPath()); for (MethodModel method : classFileToCheck.methods()) { - if ((method.flags().flagsMask() & Classfile.ACC_STRICT) == 0) { + if ((method.flags().flagsMask() & ClassFile.ACC_STRICT) == 0) { errors.add(String.format(offendingMethodErrorMessage, method.methodName().stringValue(), classFileToCheck.thisClass().asInternalName())); diff --git a/test/langtools/tools/javac/8009170/RedundantByteCodeInArrayTest.java b/test/langtools/tools/javac/8009170/RedundantByteCodeInArrayTest.java index 1d672785fceee..a9821e75ac0f2 100644 --- a/test/langtools/tools/javac/8009170/RedundantByteCodeInArrayTest.java +++ b/test/langtools/tools/javac/8009170/RedundantByteCodeInArrayTest.java @@ -26,17 +26,13 @@ * @bug 8009170 * @summary Regression: javac generates redundant bytecode in assignop involving * arrays - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run main RedundantByteCodeInArrayTest */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.ConstantPool; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.ConstantPool; import java.io.File; import java.io.IOException; @@ -54,7 +50,7 @@ void arrMethod(int[] array, int p, int inc) { void checkClassFile(File file) throws IOException { - ClassModel classFile = Classfile.of().parse(file.toPath()); + ClassModel classFile = ClassFile.of().parse(file.toPath()); ConstantPool constantPool = classFile.constantPool(); //lets get all the methods in the class file. diff --git a/test/langtools/tools/javac/AnonymousClass/AnonymousClassFlags.java b/test/langtools/tools/javac/AnonymousClass/AnonymousClassFlags.java index 12df490a6f68d..7769b1caf3226 100644 --- a/test/langtools/tools/javac/AnonymousClass/AnonymousClassFlags.java +++ b/test/langtools/tools/javac/AnonymousClass/AnonymousClassFlags.java @@ -25,12 +25,8 @@ * @test * @bug 8161013 * @summary Verify that anonymous class binaries have the correct flags set - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @run main AnonymousClassFlags */ @@ -38,9 +34,9 @@ import java.nio.file.Path; import java.nio.file.Paths; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.InnerClassInfo; -import jdk.internal.classfile.attribute.InnerClassesAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.InnerClassInfo; +import java.lang.classfile.attribute.InnerClassesAttribute; public class AnonymousClassFlags { public static void main(String[] args) throws Exception { @@ -95,10 +91,10 @@ void test(String classesDir) throws Exception { instanceMethod(); Path outerFile = Paths.get(classesDir, getClass().getName() + ".class"); - ClassModel outerClass = Classfile.of().parse(outerFile); + ClassModel outerClass = ClassFile.of().parse(outerFile); for (Map.Entry entry : anonClasses.entrySet()) { Path innerFile = Paths.get(classesDir, entry.getKey() + ".class"); - ClassModel innerClass = Classfile.of().parse(innerFile); + ClassModel innerClass = ClassFile.of().parse(innerFile); String name = entry.getKey(); int expected = entry.getValue(); assertInnerFlags(outerClass, name, expected); @@ -108,9 +104,9 @@ void test(String classesDir) throws Exception { } static void assertClassFlags(ClassModel classFile, String name, int expected) { - int mask = Classfile.ACC_PUBLIC | Classfile.ACC_FINAL | Classfile.ACC_INTERFACE | Classfile.ACC_ABSTRACT | - Classfile.ACC_SYNTHETIC | Classfile.ACC_ANNOTATION | Classfile.ACC_ENUM; - int classExpected = (expected & mask) | Classfile.ACC_SUPER; + int mask = ClassFile.ACC_PUBLIC | ClassFile.ACC_FINAL | ClassFile.ACC_INTERFACE | ClassFile.ACC_ABSTRACT | + ClassFile.ACC_SYNTHETIC | ClassFile.ACC_ANNOTATION | ClassFile.ACC_ENUM; + int classExpected = (expected & mask) | ClassFile.ACC_SUPER; int classActual = classFile.flags().flagsMask(); if (classActual != classExpected) { throw new AssertionError("Incorrect access_flags for class " + name + diff --git a/test/jdk/java/lang/Class/UnnamedClass/Unnamed.java b/test/langtools/tools/javac/ImplicitClass/Implicit.java similarity index 95% rename from test/jdk/java/lang/Class/UnnamedClass/Unnamed.java rename to test/langtools/tools/javac/ImplicitClass/Implicit.java index 9545a90f0deaa..10e1fad007ba2 100644 --- a/test/jdk/java/lang/Class/UnnamedClass/Unnamed.java +++ b/test/langtools/tools/javac/ImplicitClass/Implicit.java @@ -23,8 +23,8 @@ /** - * Exemplar unnamed class. + * Exemplar implicit class. */ -public void main() { +void main() { System.out.println("Hello, world."); } diff --git a/test/langtools/tools/javac/unnamed/UnnamedClassRecovery.java b/test/langtools/tools/javac/ImplicitClass/ImplicitClassRecovery.java similarity index 53% rename from test/langtools/tools/javac/unnamed/UnnamedClassRecovery.java rename to test/langtools/tools/javac/ImplicitClass/ImplicitClassRecovery.java index 2c1d533ab6c9d..0057d779f8c73 100644 --- a/test/langtools/tools/javac/unnamed/UnnamedClassRecovery.java +++ b/test/langtools/tools/javac/ImplicitClass/ImplicitClassRecovery.java @@ -1,6 +1,6 @@ /** * @test /nodynamiccopyright/ - * @compile/fail/ref=UnnamedClassRecovery.out -XDrawDiagnostics --enable-preview --source ${jdk.version} UnnamedClassRecovery.java + * @compile/fail/ref=ImplicitClassRecovery.out -XDrawDiagnostics --enable-preview --source ${jdk.version} ImplicitClassRecovery.java */ public void main() { //the following is intentionally missing a semicolon: diff --git a/test/langtools/tools/javac/ImplicitClass/ImplicitClassRecovery.out b/test/langtools/tools/javac/ImplicitClass/ImplicitClassRecovery.out new file mode 100644 index 0000000000000..7de6ac6b3ee1b --- /dev/null +++ b/test/langtools/tools/javac/ImplicitClass/ImplicitClassRecovery.out @@ -0,0 +1,4 @@ +ImplicitClassRecovery.java:7:33: compiler.err.expected: ';' +- compiler.note.preview.filename: ImplicitClassRecovery.java, DEFAULT +- compiler.note.preview.recompile +1 error diff --git a/test/langtools/tools/javac/ImplicitClass/NestedClasses.java b/test/langtools/tools/javac/ImplicitClass/NestedClasses.java new file mode 100644 index 0000000000000..19f070c4d485c --- /dev/null +++ b/test/langtools/tools/javac/ImplicitClass/NestedClasses.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8315458 + * @enablePreview + * @summary Make sure nesting classes don't create symbol conflicts with implicit name. + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * @build toolbox.ToolBox toolbox.JavacTask + * @run main NestedClasses + */ + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import toolbox.ToolBox; +import toolbox.JavaTask; +import toolbox.JavacTask; +import toolbox.Task; + +public class NestedClasses { + private static ToolBox TOOLBOX = new ToolBox(); + private static final String JAVA_VERSION = System.getProperty("java.specification.version"); + + public static void main(String... arg) throws IOException { + compPass("A.java", """ + void main() {} + class A {} // okay + """); + + compPass("A.java", """ + void main() {} + class B { + class A { } // okay + } + """); + + compFail("A.java", """ + void main() {} + class B { + class B { } //error + } + """); + } + + /* + * Test source for successful compile. + */ + static void compPass(String fileName, String code) throws IOException { + Path path = Path.of(fileName); + Files.writeString(path, code); + String output = new JavacTask(TOOLBOX) + .files(List.of(path)) + .classpath(".") + .options("-encoding", "utf8", "--enable-preview", "-source", JAVA_VERSION) + .run() + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (output.contains("compiler.err")) { + throw new RuntimeException("Error detected"); + } + } + + /* + * Test source for unsuccessful compile and specific error. + */ + static void compFail(String fileName, String code) throws IOException { + Path path = Path.of(fileName); + Files.writeString(path, code); + String output = new JavacTask(TOOLBOX) + .files(List.of(path)) + .classpath(".") + .options("-XDrawDiagnostics", "-encoding", "utf8", "--enable-preview", "-source", JAVA_VERSION) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + if (!output.contains("compiler.err")) { + throw new RuntimeException("No error detected"); + } + } + + } diff --git a/test/langtools/tools/javac/unnamedclass/NestedEnum.java b/test/langtools/tools/javac/ImplicitClass/NestedEnum.java similarity index 100% rename from test/langtools/tools/javac/unnamedclass/NestedEnum.java rename to test/langtools/tools/javac/ImplicitClass/NestedEnum.java diff --git a/test/langtools/tools/javac/unnamedclass/SourceLevelErrorPosition.java b/test/langtools/tools/javac/ImplicitClass/SourceLevelErrorPosition.java similarity index 74% rename from test/langtools/tools/javac/unnamedclass/SourceLevelErrorPosition.java rename to test/langtools/tools/javac/ImplicitClass/SourceLevelErrorPosition.java index 54beb45d90bcc..786c228f11ec1 100644 --- a/test/langtools/tools/javac/unnamedclass/SourceLevelErrorPosition.java +++ b/test/langtools/tools/javac/ImplicitClass/SourceLevelErrorPosition.java @@ -1,7 +1,7 @@ /** * @test /nodynamiccopyright/ * @bug 8310314 - * @summary Ensure proper error position for the "unnamed classes not supported" error + * @summary Ensure proper error position for the "implicit classes not supported" error * @compile/fail/ref=SourceLevelErrorPosition.out -XDrawDiagnostics SourceLevelErrorPosition.java */ class Nested {} diff --git a/test/langtools/tools/javac/unnamedclass/SourceLevelErrorPosition.out b/test/langtools/tools/javac/ImplicitClass/SourceLevelErrorPosition.out similarity index 55% rename from test/langtools/tools/javac/unnamedclass/SourceLevelErrorPosition.out rename to test/langtools/tools/javac/ImplicitClass/SourceLevelErrorPosition.out index 518350810a07e..1376183d9c610 100644 --- a/test/langtools/tools/javac/unnamedclass/SourceLevelErrorPosition.out +++ b/test/langtools/tools/javac/ImplicitClass/SourceLevelErrorPosition.out @@ -1,2 +1,2 @@ -SourceLevelErrorPosition.java:8:1: compiler.err.preview.feature.disabled.plural: (compiler.misc.feature.unnamed.classes) +SourceLevelErrorPosition.java:8:1: compiler.err.preview.feature.disabled.plural: (compiler.misc.feature.implicit.classes) 1 error diff --git a/test/langtools/tools/javac/ImplicitClass/TestImplicitClass.java b/test/langtools/tools/javac/ImplicitClass/TestImplicitClass.java new file mode 100644 index 0000000000000..673c31b621500 --- /dev/null +++ b/test/langtools/tools/javac/ImplicitClass/TestImplicitClass.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8315458 + * @enablePreview + * @build Implicit TestImplicitClass + * @run main TestImplicitClass + * @summary Basic checks of java.lang.Class support for implicit classes + */ + +import java.lang.reflect.Modifier; + +public class TestImplicitClass { + public static void main(String... args) throws Exception { + Class implicitClass = Class.forName("Implicit"); + + /* + * From JEP 463 JLS changes: + * + * "An implicit class compilation unit implicitly declares a class that satisfies the following + * properties: + * It is always a top level class. + * It is never abstract (8.1.1.1). + * It is never synthetic (13.1.11) + * It is always final (8.1.1.2). + * It is always a member of unnamed package (7.4.2) and has package access. + * Its direct superclass type is always Object (8.1.4). + * It never has any direct superinterface types (8.1.5). + */ + + check(!(implicitClass.isInterface() || + implicitClass.isEnum() || + implicitClass.isRecord() || + implicitClass.isHidden()), + "Implicit class was not a normal class"); + + check(!(implicitClass.isLocalClass() || + implicitClass.isMemberClass() || + implicitClass.isPrimitive() || + implicitClass.isArray()), + "Implicit class was not top-level"); + + check("Implicit".equals(implicitClass.getName()), "Unexpected Class.getName result"); + check("Implicit".equals(implicitClass.getTypeName()), "Unexpected Class.getTypeName result"); + check("Implicit".equals(implicitClass.getSimpleName()), "Unexpected Class.getSimpleName result"); + check("Implicit".equals(implicitClass.getCanonicalName()), "Unexpected Class.getCanonicalName result"); + + int modifiers = implicitClass.getModifiers(); + check((modifiers & Modifier.ABSTRACT) == 0, "Implicit class was abstract"); + check((modifiers & Modifier.FINAL) != 0, "Implicit class was not final"); + check((modifiers & (Modifier.PUBLIC | + Modifier.PRIVATE | + Modifier.PROTECTED)) == 0, "Implicit class was not package access"); + + check(!implicitClass.isSynthetic(), "Implicit class was synthetic"); + + check("".equals(implicitClass.getPackage().getName()), "Implicit class not in an implicit package"); + + check(implicitClass.getSuperclass() == Object.class, "Superclass was not java.lang.Object"); + + check(implicitClass.getInterfaces().length == 0, "Implicit class had super interfaces"); + } + + private static void check(boolean predicate, String message) { + if (!predicate) { + throw new RuntimeException(message); + } + } +} diff --git a/test/langtools/tools/javac/MethodParameters/AnnotationTest.java b/test/langtools/tools/javac/MethodParameters/AnnotationTest.java index 25f99a00888ea..e30f83f8af35d 100644 --- a/test/langtools/tools/javac/MethodParameters/AnnotationTest.java +++ b/test/langtools/tools/javac/MethodParameters/AnnotationTest.java @@ -25,12 +25,8 @@ * @test * @bug 8006582 * @summary javac should generate method parameters correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build MethodParametersTester ClassFileVisitor ReflectionVisitor * @compile -parameters AnnotationTest.java * @run main MethodParametersTester AnnotationTest AnnotationTest.out diff --git a/test/langtools/tools/javac/MethodParameters/AnonymousClass.java b/test/langtools/tools/javac/MethodParameters/AnonymousClass.java index 11c31a4a3845d..3926d9623a3c8 100644 --- a/test/langtools/tools/javac/MethodParameters/AnonymousClass.java +++ b/test/langtools/tools/javac/MethodParameters/AnonymousClass.java @@ -25,12 +25,8 @@ * @test * @bug 8006582 * @summary javac should generate method parameters correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build MethodParametersTester ClassFileVisitor ReflectionVisitor * @compile -parameters AnonymousClass.java * @run main MethodParametersTester AnonymousClass AnonymousClass.out diff --git a/test/langtools/tools/javac/MethodParameters/ClassFileVisitor.java b/test/langtools/tools/javac/MethodParameters/ClassFileVisitor.java index 644261d46fa79..610256064142a 100644 --- a/test/langtools/tools/javac/MethodParameters/ClassFileVisitor.java +++ b/test/langtools/tools/javac/MethodParameters/ClassFileVisitor.java @@ -21,9 +21,9 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.Utf8Entry; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.Utf8Entry; import java.io.*; import java.lang.constant.MethodTypeDesc; @@ -87,10 +87,10 @@ public void warn(String msg) { */ void visitClass(final String cname, final File cfile, final StringBuilder sb) throws Exception { this.cname = cname; - classFile = Classfile.of().parse(cfile.toPath()); - isEnum = (classFile.flags().flagsMask() & Classfile.ACC_ENUM) != 0; - isInterface = (classFile.flags().flagsMask() & Classfile.ACC_INTERFACE) != 0; - isPublic = (classFile.flags().flagsMask() & Classfile.ACC_PUBLIC) != 0; + classFile = ClassFile.of().parse(cfile.toPath()); + isEnum = (classFile.flags().flagsMask() & ClassFile.ACC_ENUM) != 0; + isInterface = (classFile.flags().flagsMask() & ClassFile.ACC_INTERFACE) != 0; + isPublic = (classFile.flags().flagsMask() & ClassFile.ACC_PUBLIC) != 0; isInner = false; isStatic = false; isAnon = false; @@ -127,7 +127,7 @@ void visitInnerClasses(InnerClassesAttribute iattr) { if (!cname.equals(in)) continue; isInner = true; isAnon = null == info.innerName().orElse(null); - isStatic = (info.flagsMask() & Classfile.ACC_STATIC) != 0; + isStatic = (info.flagsMask() & ClassFile.ACC_STATIC) != 0; break; } } catch(Exception e) { @@ -159,11 +159,11 @@ void visitMethod(MethodModel method, StringBuilder sb) { mParams = mDesc.parameterCount(); mAttrs = method.attributes().size(); mNumParams = -1; // no MethodParameters attribute found - mSynthetic = (method.flags().flagsMask() & Classfile.ACC_SYNTHETIC) != 0; + mSynthetic = (method.flags().flagsMask() & ClassFile.ACC_SYNTHETIC) != 0; mIsConstructor = mName.equals(""); mIsClinit = mName.equals(""); prefix = cname + "." + mName + "() - "; - mIsBridge = (method.flags().flagsMask() & Classfile.ACC_BRIDGE) != 0; + mIsBridge = (method.flags().flagsMask() & ClassFile.ACC_BRIDGE) != 0; if (mIsClinit) { sb = new StringBuilder(); // Discard output @@ -232,7 +232,7 @@ public void visitMethodParameters(MethodParametersAttribute mp, String sep = ""; String userParam = null; for (int x = 0; x < mNumParams; x++) { - isFinal = (mp.parameters().get(x).flagsMask() & Classfile.ACC_FINAL) != 0; + isFinal = (mp.parameters().get(x).flagsMask() & ClassFile.ACC_FINAL) != 0; // IMPL: Assume all parameters are named, something. Utf8Entry paramEntry = mp.parameters().get(x).name().orElse(null); if (paramEntry == null) { @@ -293,9 +293,9 @@ int checkParam(MethodParametersAttribute mp, String param, int index, StringBuilder sb, boolean isFinal) { boolean synthetic = (mp.parameters().get(index).flagsMask() - & Classfile.ACC_SYNTHETIC) != 0; + & ClassFile.ACC_SYNTHETIC) != 0; boolean mandated = (mp.parameters().get(index).flagsMask() - & Classfile.ACC_MANDATED) != 0; + & ClassFile.ACC_MANDATED) != 0; // Setup expectations for flags and special names String expect = null; diff --git a/test/langtools/tools/javac/MethodParameters/Constructors.java b/test/langtools/tools/javac/MethodParameters/Constructors.java index 0624f88f11b51..a797b40db5e81 100644 --- a/test/langtools/tools/javac/MethodParameters/Constructors.java +++ b/test/langtools/tools/javac/MethodParameters/Constructors.java @@ -25,12 +25,8 @@ * @test * @bug 8006582 * @summary javac should generate method parameters correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build MethodParametersTester ClassFileVisitor ReflectionVisitor * @compile -parameters Constructors.java * @run main MethodParametersTester Constructors Constructors.out diff --git a/test/langtools/tools/javac/MethodParameters/EnumTest.java b/test/langtools/tools/javac/MethodParameters/EnumTest.java index b2df35aa75703..0f706e7e02d49 100644 --- a/test/langtools/tools/javac/MethodParameters/EnumTest.java +++ b/test/langtools/tools/javac/MethodParameters/EnumTest.java @@ -25,12 +25,8 @@ * @test * @bug 8006582 8008658 * @summary javac should generate method parameters correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build MethodParametersTester ClassFileVisitor ReflectionVisitor * @compile -parameters EnumTest.java * @run main MethodParametersTester EnumTest EnumTest.out diff --git a/test/langtools/tools/javac/MethodParameters/InstanceMethods.java b/test/langtools/tools/javac/MethodParameters/InstanceMethods.java index 019d84c387321..e84f12245c777 100644 --- a/test/langtools/tools/javac/MethodParameters/InstanceMethods.java +++ b/test/langtools/tools/javac/MethodParameters/InstanceMethods.java @@ -25,12 +25,8 @@ * @test * @bug 8006582 * @summary javac should generate method parameters correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build MethodParametersTester ClassFileVisitor ReflectionVisitor * @compile -parameters InstanceMethods.java * @run main MethodParametersTester InstanceMethods InstanceMethods.out diff --git a/test/langtools/tools/javac/MethodParameters/LambdaTest.java b/test/langtools/tools/javac/MethodParameters/LambdaTest.java index 693096947912a..252c9487ce4cb 100644 --- a/test/langtools/tools/javac/MethodParameters/LambdaTest.java +++ b/test/langtools/tools/javac/MethodParameters/LambdaTest.java @@ -25,12 +25,8 @@ * @test * @bug 8006582 8037546 8138729 * @summary javac should generate method parameters correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build MethodParametersTester ClassFileVisitor ReflectionVisitor * @compile -parameters LambdaTest.java * @run main MethodParametersTester LambdaTest LambdaTest.out diff --git a/test/langtools/tools/javac/MethodParameters/LegacyOutputTest/LegacyOutputTest.java b/test/langtools/tools/javac/MethodParameters/LegacyOutputTest/LegacyOutputTest.java index 3a9d3d155c965..117beccfe59ea 100644 --- a/test/langtools/tools/javac/MethodParameters/LegacyOutputTest/LegacyOutputTest.java +++ b/test/langtools/tools/javac/MethodParameters/LegacyOutputTest/LegacyOutputTest.java @@ -25,19 +25,15 @@ * @test * @bug 8190452 * @summary javac should not add MethodParameters attributes to v51 and earlier class files - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build LegacyOutputTest * @run main LegacyOutputTest */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.MethodParameterInfo; -import jdk.internal.classfile.attribute.MethodParametersAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.MethodParameterInfo; +import java.lang.classfile.attribute.MethodParametersAttribute; import java.io.IOException; import java.net.URI; import java.nio.file.Paths; @@ -95,7 +91,7 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) if (!task.call()) { throw new AssertionError("compilation failed"); } - ClassModel classFile = Classfile.of().parse(Paths.get("Test.class")); + ClassModel classFile = ClassFile.of().parse(Paths.get("Test.class")); MethodModel method = getMethod(classFile, "f"); MethodParametersAttribute attribute = method.findAttribute(Attributes.METHOD_PARAMETERS).orElse(null); if (attribute == null) { diff --git a/test/langtools/tools/javac/MethodParameters/LocalClassTest.java b/test/langtools/tools/javac/MethodParameters/LocalClassTest.java index 27020e31fdf40..061e2213a4c48 100644 --- a/test/langtools/tools/javac/MethodParameters/LocalClassTest.java +++ b/test/langtools/tools/javac/MethodParameters/LocalClassTest.java @@ -25,12 +25,8 @@ * @test * @bug 8006582 8008658 * @summary javac should generate method parameters correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build MethodParametersTester ClassFileVisitor ReflectionVisitor * @compile -parameters LocalClassTest.java * @run main MethodParametersTester LocalClassTest LocalClassTest.out diff --git a/test/langtools/tools/javac/MethodParameters/MemberClassTest.java b/test/langtools/tools/javac/MethodParameters/MemberClassTest.java index 39fd09027ed38..940d30da40c9a 100644 --- a/test/langtools/tools/javac/MethodParameters/MemberClassTest.java +++ b/test/langtools/tools/javac/MethodParameters/MemberClassTest.java @@ -25,12 +25,8 @@ * @test * @bug 8006582 8008658 * @summary javac should generate method parameters correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build MethodParametersTester ClassFileVisitor ReflectionVisitor * @compile -parameters MemberClassTest.java * @run main MethodParametersTester MemberClassTest MemberClassTest.out diff --git a/test/langtools/tools/javac/MethodParameters/StaticMethods.java b/test/langtools/tools/javac/MethodParameters/StaticMethods.java index 4373e328acc1e..a6c0d8aa5d09a 100644 --- a/test/langtools/tools/javac/MethodParameters/StaticMethods.java +++ b/test/langtools/tools/javac/MethodParameters/StaticMethods.java @@ -25,12 +25,8 @@ * @test * @bug 8006582 * @summary javac should generate method parameters correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build MethodParametersTester ClassFileVisitor ReflectionVisitor * @compile -parameters StaticMethods.java * @run main MethodParametersTester StaticMethods StaticMethods.out diff --git a/test/langtools/tools/javac/MethodParameters/UncommonParamNames.java b/test/langtools/tools/javac/MethodParameters/UncommonParamNames.java index 8bfe8215ae111..ae17d90150d85 100644 --- a/test/langtools/tools/javac/MethodParameters/UncommonParamNames.java +++ b/test/langtools/tools/javac/MethodParameters/UncommonParamNames.java @@ -25,12 +25,8 @@ * @test * @bug 8006582 * @summary javac should generate method parameters correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build MethodParametersTester ClassFileVisitor ReflectionVisitor * @compile -parameters UncommonParamNames.java * @run main MethodParametersTester UncommonParamNames UncommonParamNames.out diff --git a/test/langtools/tools/javac/MethodParametersTest.java b/test/langtools/tools/javac/MethodParametersTest.java index 4f4ad15bd6b49..5c7a891cdb07a 100644 --- a/test/langtools/tools/javac/MethodParametersTest.java +++ b/test/langtools/tools/javac/MethodParametersTest.java @@ -25,12 +25,8 @@ * @test * @bug 8004727 * @summary javac should generate method parameters correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.comp * jdk.compiler/com.sun.tools.javac.file @@ -39,8 +35,8 @@ * jdk.compiler/com.sun.tools.javac.util */ // key: opt.arg.parameters -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.main.Main; @@ -171,7 +167,7 @@ void inspectBaz() throws Exception { void modifyBaz(boolean flip) throws Exception { final File Baz_class = new File(classesdir, Baz_name + ".class"); - final ClassModel baz = Classfile.of().parse(Baz_class.toPath()); + final ClassModel baz = ClassFile.of().parse(Baz_class.toPath()); // Find MethodParameters and the Code attributes if (baz.methods().size() != 1) @@ -188,7 +184,7 @@ void modifyBaz(boolean flip) throws Exception { // Alter the MethodParameters attribute, changing the name of // the parameter from i to baz. - byte[] bazBytes = Classfile.of().transform(baz, ClassTransform.transformingMethods((methodBuilder, methodElement) -> { + byte[] bazBytes = ClassFile.of().transform(baz, ClassTransform.transformingMethods((methodBuilder, methodElement) -> { if (methodElement instanceof MethodParametersAttribute a) { List newParameterInfos = new ArrayList<>(); for (MethodParameterInfo info : a.parameters()) { @@ -204,7 +200,7 @@ void modifyBaz(boolean flip) throws Exception { // Flip the code and method attributes(). This is for checking // that order doesn't matter. if (flip) { - bazBytes = Classfile.of().transform(baz, ClassTransform.transformingMethods((methodBuilder, methodElement) -> { + bazBytes = ClassFile.of().transform(baz, ClassTransform.transformingMethods((methodBuilder, methodElement) -> { if (methodElement instanceof MethodParametersAttribute) { methodBuilder.with(cattr); } else if (methodElement instanceof CodeAttribute){ @@ -220,7 +216,7 @@ void modifyBaz(boolean flip) throws Exception { // Run a bunch of structural tests on foo to make sure it looks right. void checkFoo() throws Exception { final File Foo_class = new File(classesdir, Foo_name + ".class"); - final ClassModel foo = Classfile.of().parse(Foo_class.toPath()); + final ClassModel foo = ClassFile.of().parse(Foo_class.toPath()); for (int i = 0; i < foo.methods().size(); i++) { System.err.println("Examine method Foo." + foo.methods().get(i).methodName()); if (foo.methods().get(i).methodName().equalsString("foo2")) { @@ -261,7 +257,7 @@ else if (foo.methods().get(i).methodName().equalsString("foo0")) { // Run a bunch of structural tests on Bar to make sure it looks right. void checkBar() throws Exception { final File Bar_class = new File(classesdir, Bar_name + ".class"); - final ClassModel bar = Classfile.of().parse(Bar_class.toPath()); + final ClassModel bar = ClassFile.of().parse(Bar_class.toPath()); for (int i = 0; i < bar.methods().size(); i++) { System.err.println("Examine method Bar." + bar.methods().get(i).methodName()); if (bar.methods().get(i).methodName().equalsString("")) { diff --git a/test/langtools/tools/javac/NoStringToLower.java b/test/langtools/tools/javac/NoStringToLower.java index 450a05ac70733..64e68aad1de52 100644 --- a/test/langtools/tools/javac/NoStringToLower.java +++ b/test/langtools/tools/javac/NoStringToLower.java @@ -25,19 +25,15 @@ * @test * @bug 8029800 * @summary String.toLowerCase()/toUpperCase is generally dangerous, check it is not used in langtools - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ import java.io.*; import java.util.*; import javax.tools.*; -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.*; public class NoStringToLower { public static void main(String... args) throws Exception { @@ -108,7 +104,7 @@ JavaFileManager.Location findJavacLocation(JavaFileManager fm) { */ void scan(JavaFileObject fo) throws IOException { try (InputStream in = fo.openInputStream()) { - ClassModel cf = Classfile.of().parse(in.readAllBytes()); + ClassModel cf = ClassFile.of().parse(in.readAllBytes()); for (PoolEntry pe : cf.constantPool()) { if (pe instanceof MethodRefEntry ref) { String methodDesc = ref.owner().name().stringValue() + "." + ref.name().stringValue() + ":" + ref.type().stringValue(); diff --git a/test/langtools/tools/javac/RequiredParameterFlags/ImplicitParameters.java b/test/langtools/tools/javac/RequiredParameterFlags/ImplicitParameters.java index 563a65089e177..64db03abdaeb9 100644 --- a/test/langtools/tools/javac/RequiredParameterFlags/ImplicitParameters.java +++ b/test/langtools/tools/javac/RequiredParameterFlags/ImplicitParameters.java @@ -26,21 +26,17 @@ * @bug 8292275 * @summary check that implicit parameter flags are available by default * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.code - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @run main ImplicitParameters */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.MethodParameterInfo; -import jdk.internal.classfile.attribute.MethodParametersAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.MethodParameterInfo; +import java.lang.classfile.attribute.MethodParametersAttribute; import com.sun.tools.javac.code.Flags; import toolbox.Assert; import toolbox.JavacTask; @@ -58,7 +54,7 @@ import java.util.List; public class ImplicitParameters extends TestRunner { - private static final int CHECKED_FLAGS = Classfile.ACC_MANDATED | Classfile.ACC_SYNTHETIC; + private static final int CHECKED_FLAGS = ClassFile.ACC_MANDATED | ClassFile.ACC_SYNTHETIC; private static final int NO_FLAGS = 0; public ImplicitParameters() { @@ -130,7 +126,7 @@ record MyRecord(int a, Object b) { private ClassModel readClassFile(Path classes, Method method) { String className = method.getAnnotation(ClassName.class).value(); try { - return Classfile.of().parse(classes.resolve("Outer$" + className + ".class")); + return ClassFile.of().parse(classes.resolve("Outer$" + className + ".class")); } catch (IOException e) { throw new RuntimeException(e); } @@ -144,7 +140,7 @@ private ClassModel readClassFile(Path classes, Method method) { @Test @ClassName("Inner") public void testInnerClassConstructor(ClassModel classFile) { - checkParameters(classFile.methods().get(0), Classfile.ACC_MANDATED, 0); + checkParameters(classFile.methods().get(0), ClassFile.ACC_MANDATED, 0); } @Test @@ -152,7 +148,7 @@ public void testInnerClassConstructor(ClassModel classFile) { public void testLocalClassConstructor(ClassModel classFile) { for (MethodModel method : classFile.methods()) { if (method.methodName().equalsString(ConstantDescs.INIT_NAME)) { - checkParameters(method, Classfile.ACC_MANDATED, NO_FLAGS, Classfile.ACC_SYNTHETIC); + checkParameters(method, ClassFile.ACC_MANDATED, NO_FLAGS, ClassFile.ACC_SYNTHETIC); break; } } @@ -161,13 +157,13 @@ public void testLocalClassConstructor(ClassModel classFile) { @Test @ClassName("1") public void testAnonymousClassExtendingInnerClassConstructor(ClassModel classFile) { - checkParameters(classFile.methods().get(0), Classfile.ACC_MANDATED, NO_FLAGS, NO_FLAGS); + checkParameters(classFile.methods().get(0), ClassFile.ACC_MANDATED, NO_FLAGS, NO_FLAGS); } @Test @ClassName("2") public void testAnonymousClassConstructor(ClassModel classFile) { - checkParameters(classFile.methods().get(0), Classfile.ACC_MANDATED); + checkParameters(classFile.methods().get(0), ClassFile.ACC_MANDATED); } @Test @@ -175,7 +171,7 @@ public void testAnonymousClassConstructor(ClassModel classFile) { public void testValueOfInEnum(ClassModel classFile) { for (MethodModel method : classFile.methods()) { if (method.methodName().equalsString("valueOf")) { - checkParameters(method, Classfile.ACC_MANDATED); + checkParameters(method, ClassFile.ACC_MANDATED); break; } } @@ -186,7 +182,7 @@ public void testValueOfInEnum(ClassModel classFile) { public void testEnumClassConstructor(ClassModel classFile) { for (MethodModel method : classFile.methods()) { if (method.methodName().equalsString(ConstantDescs.INIT_NAME)) { - checkParameters(method, Classfile.ACC_SYNTHETIC, Classfile.ACC_SYNTHETIC, NO_FLAGS, NO_FLAGS); + checkParameters(method, ClassFile.ACC_SYNTHETIC, ClassFile.ACC_SYNTHETIC, NO_FLAGS, NO_FLAGS); break; } } @@ -195,7 +191,7 @@ public void testEnumClassConstructor(ClassModel classFile) { @Test @ClassName("MyRecord") public void testCompactConstructor(ClassModel classFile) { - checkParameters(classFile.methods().get(0), Classfile.ACC_MANDATED, Classfile.ACC_MANDATED); + checkParameters(classFile.methods().get(0), ClassFile.ACC_MANDATED, ClassFile.ACC_MANDATED); } private void checkParameters(MethodModel method, int... parametersFlags) { @@ -213,6 +209,6 @@ private void checkParameters(MethodModel method, int... parametersFlags) { } private static String convertFlags(int flags) { - return ((flags & Classfile.ACC_MANDATED) == Classfile.ACC_MANDATED) + " and " + ((flags & Classfile.ACC_SYNTHETIC) == Classfile.ACC_SYNTHETIC); + return ((flags & ClassFile.ACC_MANDATED) == ClassFile.ACC_MANDATED) + " and " + ((flags & ClassFile.ACC_SYNTHETIC) == ClassFile.ACC_SYNTHETIC); } } diff --git a/test/langtools/tools/javac/StringConcat/TestIndyStringConcat.java b/test/langtools/tools/javac/StringConcat/TestIndyStringConcat.java index 32aa103f52a69..39b9cd52998f2 100644 --- a/test/langtools/tools/javac/StringConcat/TestIndyStringConcat.java +++ b/test/langtools/tools/javac/StringConcat/TestIndyStringConcat.java @@ -21,11 +21,10 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.InvokeDynamicEntry; -import jdk.internal.classfile.constantpool.MethodHandleEntry; -import jdk.internal.classfile.instruction.InvokeDynamicInstruction; +import com.sun.tools.classfile.*; +import com.sun.tools.classfile.BootstrapMethods_attribute.BootstrapMethodSpecifier; +import com.sun.tools.classfile.ConstantPool.CONSTANT_InvokeDynamic_info; +import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodHandle_info; import java.io.File; @@ -33,12 +32,7 @@ * @test * @bug 8148483 8151516 8151223 * @summary Test that StringConcat is working for JDK >= 9 - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @modules jdk.jdeps/com.sun.tools.classfile * * @clean * * @compile -source 8 -target 8 TestIndyStringConcat.java @@ -65,7 +59,7 @@ public static String test() { } public static void main(String[] args) throws Exception { - boolean expected = Boolean.parseBoolean(args[0]); + boolean expected = Boolean.valueOf(args[0]); boolean actual = hasStringConcatFactoryCall("test"); if (expected != actual) { throw new AssertionError("expected = " + expected + ", actual = " + actual); @@ -73,18 +67,30 @@ public static void main(String[] args) throws Exception { } public static boolean hasStringConcatFactoryCall(String methodName) throws Exception { - ClassModel classFile = Classfile.of().parse(new File(System.getProperty("test.classes", "."), - TestIndyStringConcat.class.getName() + ".class").toPath()); + ClassFile classFile = ClassFile.read(new File(System.getProperty("test.classes", "."), + TestIndyStringConcat.class.getName() + ".class")); + ConstantPool constantPool = classFile.constant_pool; - for (MethodModel method : classFile.methods()) { - if (method.methodName().equalsString(methodName)) { - CodeAttribute code = method.findAttribute(Attributes.CODE).orElseThrow(); - for (CodeElement i : code.elementList()) { - if (i instanceof InvokeDynamicInstruction) { - InvokeDynamicInstruction indy = (InvokeDynamicInstruction) i; - BootstrapMethodEntry bsmSpec = indy.invokedynamic().bootstrap(); - MethodHandleEntry bsmInfo = bsmSpec.bootstrapMethod(); - if (bsmInfo.reference().owner().asInternalName().equals("java/lang/invoke/StringConcatFactory")) { + BootstrapMethods_attribute bsm_attr = + (BootstrapMethods_attribute)classFile + .getAttribute(Attribute.BootstrapMethods); + + for (Method method : classFile.methods) { + if (method.getName(constantPool).equals(methodName)) { + Code_attribute code = (Code_attribute) method.attributes + .get(Attribute.Code); + for (Instruction i : code.getInstructions()) { + if (i.getOpcode() == Opcode.INVOKEDYNAMIC) { + CONSTANT_InvokeDynamic_info indyInfo = + (CONSTANT_InvokeDynamic_info) constantPool.get(i.getUnsignedShort(1)); + + BootstrapMethodSpecifier bsmSpec = + bsm_attr.bootstrap_method_specifiers[indyInfo.bootstrap_method_attr_index]; + + CONSTANT_MethodHandle_info bsmInfo = + (CONSTANT_MethodHandle_info) constantPool.get(bsmSpec.bootstrap_method_ref); + + if (bsmInfo.getCPRefInfo().getClassName().equals("java/lang/invoke/StringConcatFactory")) { return true; } } @@ -94,4 +100,27 @@ public static boolean hasStringConcatFactoryCall(String methodName) throws Excep return false; } +// this version of the code can be used when ClassFile API in not in a preview +// public static boolean hasStringConcatFactoryCall(String methodName) throws Exception { +// ClassModel classFile = ClassFile.of().parse(new File(System.getProperty("test.classes", "."), +// TestIndyStringConcat.class.getName() + ".class").toPath()); +// +// for (MethodModel method : classFile.methods()) { +// if (method.methodName().equalsString(methodName)) { +// CodeAttribute code = method.findAttribute(Attributes.CODE).orElseThrow(); +// for (CodeElement i : code.elementList()) { +// if (i instanceof InvokeDynamicInstruction) { +// InvokeDynamicInstruction indy = (InvokeDynamicInstruction) i; +// BootstrapMethodEntry bsmSpec = indy.invokedynamic().bootstrap(); +// MethodHandleEntry bsmInfo = bsmSpec.bootstrapMethod(); +// if (bsmInfo.reference().owner().asInternalName().equals("java/lang/invoke/StringConcatFactory")) { +// return true; +// } +// } +// } +// } +// } +// return false; +// } + } diff --git a/test/langtools/tools/javac/StringConcat/WellKnownTypeSignatures.java b/test/langtools/tools/javac/StringConcat/WellKnownTypeSignatures.java index 7e14ae361c980..60d54944168dc 100644 --- a/test/langtools/tools/javac/StringConcat/WellKnownTypeSignatures.java +++ b/test/langtools/tools/javac/StringConcat/WellKnownTypeSignatures.java @@ -21,10 +21,10 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.NameAndTypeEntry; -import jdk.internal.classfile.instruction.InvokeDynamicInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.NameAndTypeEntry; +import java.lang.classfile.instruction.InvokeDynamicInstruction; import java.io.File; import java.util.ArrayList; @@ -34,12 +34,8 @@ * @test * @bug 8273914 * @summary Indy string concat changes order of operations - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * * @clean * * @compile -XDstringConcat=indy WellKnownTypeSignatures.java @@ -101,7 +97,7 @@ public static void test(String actual, int index, String expectedType) { public static void readIndyTypes() throws Exception { actualTypes = new ArrayList(); - ClassModel classFile = Classfile.of().parse( + ClassModel classFile = ClassFile.of().parse( new File( System.getProperty("test.classes", "."), WellKnownTypeSignatures.class.getName() + ".class").toPath()); diff --git a/test/langtools/tools/javac/StringConcat/WellKnownTypes.java b/test/langtools/tools/javac/StringConcat/WellKnownTypes.java index 2da4dd705643e..470182bc04e38 100644 --- a/test/langtools/tools/javac/StringConcat/WellKnownTypes.java +++ b/test/langtools/tools/javac/StringConcat/WellKnownTypes.java @@ -25,11 +25,7 @@ * @test * @bug 8273914 * @summary Indy string concat changes order of operations - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * * @compile -XDstringConcat=indy WellKnownTypes.java * @run main WellKnownTypes diff --git a/test/langtools/tools/javac/StringConcat/access/Test.java b/test/langtools/tools/javac/StringConcat/access/Test.java index 51313092e789b..93ee3ec7c3f1f 100644 --- a/test/langtools/tools/javac/StringConcat/access/Test.java +++ b/test/langtools/tools/javac/StringConcat/access/Test.java @@ -21,10 +21,10 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.*; -import jdk.internal.classfile.instruction.InvokeDynamicInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.*; +import java.lang.classfile.instruction.InvokeDynamicInstruction; import java.io.File; import java.util.ArrayList; @@ -34,11 +34,7 @@ * @test * @bug 8151223 * @summary String concatenation fails with implicit toString() on package-private class - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * * @clean * * @compile -XDstringConcat=indy Holder.java PublicClass.java PublicInterface.java Public_PublicClass.java Public_PublicInterface.java Public_PrivateInterface1.java Public_PrivateInterface2.java Test.java @@ -181,7 +177,7 @@ public static void test(String actual, int index, String expectedType) { public static void readIndyTypes() throws Exception { actualTypes = new ArrayList(); - ClassModel classFile = Classfile.of().parse(new File(System.getProperty("test.classes", "."), + ClassModel classFile = ClassFile.of().parse(new File(System.getProperty("test.classes", "."), Test.class.getName() + ".class").toPath()); for (MethodModel method : classFile.methods()) { diff --git a/test/langtools/tools/javac/T6695379/AnnotationsAreNotCopiedToBridgeMethodsTest.java b/test/langtools/tools/javac/T6695379/AnnotationsAreNotCopiedToBridgeMethodsTest.java index 16fef1b824229..53adfe17d18ad 100644 --- a/test/langtools/tools/javac/T6695379/AnnotationsAreNotCopiedToBridgeMethodsTest.java +++ b/test/langtools/tools/javac/T6695379/AnnotationsAreNotCopiedToBridgeMethodsTest.java @@ -26,12 +26,8 @@ * @bug 6695379 * @summary Copy method annotations and parameter annotations to synthetic * bridge methods - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.util * @run main AnnotationsAreNotCopiedToBridgeMethodsTest */ @@ -45,8 +41,8 @@ import java.nio.file.Path; import java.nio.file.Paths; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import com.sun.tools.javac.util.Assert; public class AnnotationsAreNotCopiedToBridgeMethodsTest { @@ -64,9 +60,9 @@ void run() throws Exception { } > void checkClassFile(final Path cfilePath) throws Exception { - ClassModel classFile = Classfile.of().parse(cfilePath); + ClassModel classFile = ClassFile.of().parse(cfilePath); for (MethodModel method : classFile.methods()) { - if ((method.flags().flagsMask() & Classfile.ACC_BRIDGE) != 0) { + if ((method.flags().flagsMask() & ClassFile.ACC_BRIDGE) != 0) { Assert.checkNonNull(method.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS), "Annotations hasn't been copied to bridge method"); Assert.checkNonNull(method.findAttribute(Attributes.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS), diff --git a/test/langtools/tools/javac/T6970173/DebugPointerAtBadPositionTest.java b/test/langtools/tools/javac/T6970173/DebugPointerAtBadPositionTest.java index 2ef4c45d7ec1c..350d03c8c3bb0 100644 --- a/test/langtools/tools/javac/T6970173/DebugPointerAtBadPositionTest.java +++ b/test/langtools/tools/javac/T6970173/DebugPointerAtBadPositionTest.java @@ -26,12 +26,8 @@ * @bug 6970173 * @summary Debug pointer at bad position * @library /tools/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util @@ -43,8 +39,8 @@ import java.io.File; import java.nio.file.Paths; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import com.sun.tools.javac.util.Assert; import toolbox.JavacTask; @@ -93,7 +89,7 @@ void compileTestClass() throws Exception { } void checkClassFile(final File cfile, String methodToFind) throws Exception { - ClassModel classFile = Classfile.of().parse(cfile.toPath()); + ClassModel classFile = ClassFile.of().parse(cfile.toPath()); boolean methodFound = false; for (MethodModel m : classFile.methods()) { if (m.methodName().equalsString(methodToFind)) { diff --git a/test/langtools/tools/javac/T7008643/InlinedFinallyConfuseDebuggersTest.java b/test/langtools/tools/javac/T7008643/InlinedFinallyConfuseDebuggersTest.java index 99e370ecb3bec..5f76442471397 100644 --- a/test/langtools/tools/javac/T7008643/InlinedFinallyConfuseDebuggersTest.java +++ b/test/langtools/tools/javac/T7008643/InlinedFinallyConfuseDebuggersTest.java @@ -26,12 +26,8 @@ * @bug 7008643 * @summary inlined finally clauses confuse debuggers * @library /tools/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util @@ -43,8 +39,8 @@ import java.io.File; import java.nio.file.Paths; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import com.sun.tools.javac.util.Assert; import toolbox.JavacTask; @@ -100,7 +96,7 @@ void compileTestClass() throws Exception { } void checkClassFile(final File cfile, String methodToFind) throws Exception { - ClassModel classFile = Classfile.of().parse(cfile.toPath()); + ClassModel classFile = ClassFile.of().parse(cfile.toPath()); boolean methodFound = false; for (MethodModel m : classFile.methods()) { if (m.methodName().equalsString(methodToFind)) { diff --git a/test/langtools/tools/javac/T7053059/DoubleCastTest.java b/test/langtools/tools/javac/T7053059/DoubleCastTest.java index 2cf472d3ce915..84c39a6cb1670 100644 --- a/test/langtools/tools/javac/T7053059/DoubleCastTest.java +++ b/test/langtools/tools/javac/T7053059/DoubleCastTest.java @@ -25,12 +25,8 @@ * @test * @bug 8015499 * @summary javac, Gen is generating extra checkcast instructions in some corner cases - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.util * @run main DoubleCastTest */ @@ -38,10 +34,10 @@ import java.util.List; import java.util.ArrayList; import java.util.Objects; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.ClassEntry; -import jdk.internal.classfile.instruction.TypeCheckInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.ClassEntry; +import java.lang.classfile.instruction.TypeCheckInstruction; import com.sun.tools.javac.util.Assert; public class DoubleCastTest { @@ -64,7 +60,7 @@ void m2() { public static void main(String... cmdline) throws Exception { - ClassModel cls = Classfile.of().parse(Objects.requireNonNull(DoubleCastTest.class.getResourceAsStream("DoubleCastTest$C.class")).readAllBytes()); + ClassModel cls = ClassFile.of().parse(Objects.requireNonNull(DoubleCastTest.class.getResourceAsStream("DoubleCastTest$C.class")).readAllBytes()); for (MethodModel m: cls.methods()) check(m); } diff --git a/test/langtools/tools/javac/T7093325.java b/test/langtools/tools/javac/T7093325.java index bd7434f6119e0..948d775c578e7 100644 --- a/test/langtools/tools/javac/T7093325.java +++ b/test/langtools/tools/javac/T7093325.java @@ -27,12 +27,8 @@ * @summary Redundant entry in bytecode exception table * temporarily workaround combo tests are causing time out in several platforms * @library /tools/javac/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.util @@ -43,9 +39,9 @@ import java.io.IOException; import java.io.InputStream; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.ClassEntry; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.ClassEntry; import javax.tools.JavaFileObject; @@ -152,9 +148,9 @@ void verifyBytecode(Result> result) { } try (InputStream is = result.get().iterator().next().openInputStream()) { - ClassModel cf = Classfile.of().parse(is.readAllBytes()); + ClassModel cf = ClassFile.of().parse(is.readAllBytes()); if (cf == null) { - fail("Classfile not found: " + result.compilationInfo()); + fail("ClassFile not found: " + result.compilationInfo()); return; } diff --git a/test/langtools/tools/javac/T7165659/InnerClassAttrMustNotHaveStrictFPFlagTest.java b/test/langtools/tools/javac/T7165659/InnerClassAttrMustNotHaveStrictFPFlagTest.java index 061d1a1d441e6..fc4aae5a0ae46 100644 --- a/test/langtools/tools/javac/T7165659/InnerClassAttrMustNotHaveStrictFPFlagTest.java +++ b/test/langtools/tools/javac/T7165659/InnerClassAttrMustNotHaveStrictFPFlagTest.java @@ -25,18 +25,14 @@ * @test * @bug 7165659 * @summary javac incorrectly sets strictfp access flag on inner-classes - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * jdk.compiler/com.sun.tools.javac.util + * @enablePreview + * @modules jdk.compiler/com.sun.tools.javac.util */ import java.io.File; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import com.sun.tools.javac.util.Assert; public class InnerClassAttrMustNotHaveStrictFPFlagTest { @@ -51,11 +47,11 @@ private void run() throws Exception { } void analyzeClassFile(File path) throws Exception { - ClassModel classFile = Classfile.of().parse(path.toPath()); + ClassModel classFile = ClassFile.of().parse(path.toPath()); InnerClassesAttribute innerClasses = classFile.findAttribute(Attributes.INNER_CLASSES).orElse(null); assert innerClasses != null; for (InnerClassInfo classInfo : innerClasses.classes()) { - Assert.check(classInfo.flagsMask() != Classfile.ACC_STRICT, + Assert.check(classInfo.flagsMask() != ClassFile.ACC_STRICT, "Inner classes attribute must not have the ACC_STRICT flag set"); } } diff --git a/test/langtools/tools/javac/T8003967/DetectMutableStaticFields.java b/test/langtools/tools/javac/T8003967/DetectMutableStaticFields.java index af4d3f9903571..2f10e510b0ceb 100644 --- a/test/langtools/tools/javac/T8003967/DetectMutableStaticFields.java +++ b/test/langtools/tools/javac/T8003967/DetectMutableStaticFields.java @@ -25,17 +25,13 @@ * @test * @bug 8003967 * @summary detect and remove all mutable implicit static enum fields in langtools - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.util * @run main DetectMutableStaticFields */ -import jdk.internal.classfile.*; +import java.lang.classfile.*; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -174,7 +170,7 @@ void analyzeModule(StandardJavaFileManager fm, String moduleName) throws IOExcep if (shouldAnalyzePackage(pckName)) { ClassModel classFile; try (InputStream input = file.openInputStream()) { - classFile = Classfile.of().parse(input.readAllBytes()); + classFile = ClassFile.of().parse(input.readAllBytes()); } analyzeClassFile(classFile); } @@ -196,7 +192,7 @@ boolean ignoreField(String field) { void analyzeClassFile(ClassModel classFileToCheck) { boolean enumClass = - (classFileToCheck.flags().flagsMask() & Classfile.ACC_ENUM) != 0; + (classFileToCheck.flags().flagsMask() & ClassFile.ACC_ENUM) != 0; boolean nonFinalStaticEnumField; boolean nonFinalStaticField; @@ -208,10 +204,10 @@ void analyzeClassFile(ClassModel classFileToCheck) { continue; } nonFinalStaticEnumField = - (field.flags().flagsMask() & (Classfile.ACC_ENUM | Classfile.ACC_FINAL)) == 0; + (field.flags().flagsMask() & (ClassFile.ACC_ENUM | ClassFile.ACC_FINAL)) == 0; nonFinalStaticField = - (field.flags().flagsMask() & Classfile.ACC_STATIC) != 0 && - (field.flags().flagsMask() & Classfile.ACC_FINAL) == 0; + (field.flags().flagsMask() & ClassFile.ACC_STATIC) != 0 && + (field.flags().flagsMask() & ClassFile.ACC_FINAL) == 0; if (enumClass ? nonFinalStaticEnumField : nonFinalStaticField) { errors.add("There is a mutable field named " + field.fieldName().stringValue() + diff --git a/test/langtools/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java b/test/langtools/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java index e435cf82b00d8..81879a5f2a056 100644 --- a/test/langtools/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java +++ b/test/langtools/tools/javac/T8010737/ParameterNamesAreNotCopiedToAnonymousInitTest.java @@ -26,12 +26,8 @@ * @bug 8010737 * @summary javac, known parameter's names should be copied to automatically * generated constructors for inner classes - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.tree @@ -66,7 +62,7 @@ import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Names; -import jdk.internal.classfile.*; +import java.lang.classfile.*; public class ParameterNamesAreNotCopiedToAnonymousInitTest { @@ -116,7 +112,7 @@ void run(String[] args) throws Exception { } void checkClassFile(final File cfile, int numberOfParams) throws Exception { - ClassModel classFile = Classfile.of().parse(cfile.toPath()); + ClassModel classFile = ClassFile.of().parse(cfile.toPath()); boolean methodFound = false; for (MethodModel method : classFile.methods()) { if (method.methodName().equalsString("")) { @@ -147,11 +143,8 @@ void checkInitSymbol( Arrays.asList(new File(System.getProperty("test.src"), this.getClass().getName() + ".java"))); java.util.List options = Arrays.asList( - "--add-exports", "java.base/jdk.internal.classfile=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.attribute=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.instruction=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.components=ALL-UNNAMED", + "--enable-preview", + "--source", String.valueOf(Runtime.version().feature()), "--add-exports", "java.base/jdk.internal.classfile.impl=ALL-UNNAMED", "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", "--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", diff --git a/test/langtools/tools/javac/T8011181/EmptyUTF8ForInnerClassNameTest.java b/test/langtools/tools/javac/T8011181/EmptyUTF8ForInnerClassNameTest.java index 430ec1bfe6149..2957bdd20e736 100644 --- a/test/langtools/tools/javac/T8011181/EmptyUTF8ForInnerClassNameTest.java +++ b/test/langtools/tools/javac/T8011181/EmptyUTF8ForInnerClassNameTest.java @@ -25,12 +25,8 @@ * @test * @bug 8011181 * @summary javac, empty UTF8 entry generated for inner class - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * jdk.compiler/com.sun.tools.javac.util + * @enablePreview + * @modules jdk.compiler/com.sun.tools.javac.util */ import java.io.BufferedInputStream; @@ -39,8 +35,8 @@ import java.nio.file.Paths; import com.sun.tools.javac.util.Assert; -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.*; public class EmptyUTF8ForInnerClassNameTest { @@ -56,7 +52,7 @@ void run() throws Exception { } void checkClassFile(final Path path) throws Exception { - ClassModel classFile = Classfile.of().parse( + ClassModel classFile = ClassFile.of().parse( new BufferedInputStream(Files.newInputStream(path)).readAllBytes()); for (PoolEntry pe : classFile.constantPool()) { if (pe instanceof Utf8Entry utf8Info) { diff --git a/test/langtools/tools/javac/T8019486/WrongLNTForLambdaTest.java b/test/langtools/tools/javac/T8019486/WrongLNTForLambdaTest.java index b6ba6333b82d3..7c334d35f7c92 100644 --- a/test/langtools/tools/javac/T8019486/WrongLNTForLambdaTest.java +++ b/test/langtools/tools/javac/T8019486/WrongLNTForLambdaTest.java @@ -26,14 +26,10 @@ * @bug 8019486 8026861 8027142 * @summary javac, generates erroneous LVT for a test case with lambda code * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main WrongLNTForLambdaTest @@ -44,8 +40,8 @@ import com.sun.tools.javac.util.Assert; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import toolbox.JavacTask; import toolbox.ToolBox; @@ -162,7 +158,7 @@ void compileTestClass() throws Exception { } void checkClassFile(final File cfile, String methodToFind, int[][] expectedLNT) throws Exception { - ClassModel classFile = Classfile.of().parse(cfile.toPath()); + ClassModel classFile = ClassFile.of().parse(cfile.toPath()); boolean methodFound = false; for (MethodModel method : classFile.methods()) { if (method.methodName().equalsString(methodToFind)) { diff --git a/test/langtools/tools/javac/T8022186/DeadCodeGeneratedForEmptyTryTest.java b/test/langtools/tools/javac/T8022186/DeadCodeGeneratedForEmptyTryTest.java index ff60d7b15c505..d3b6851f87bac 100644 --- a/test/langtools/tools/javac/T8022186/DeadCodeGeneratedForEmptyTryTest.java +++ b/test/langtools/tools/javac/T8022186/DeadCodeGeneratedForEmptyTryTest.java @@ -25,19 +25,15 @@ * @test * @bug 8022186 8271254 * @summary javac generates dead code if a try with an empty body has a finalizer - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.util */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.*; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.*; +import java.lang.classfile.instruction.InvokeInstruction; import com.sun.tools.javac.util.Assert; import java.io.BufferedInputStream; import java.nio.file.Files; @@ -63,7 +59,7 @@ void run() throws Exception { void checkClassFile(final Path path) throws Exception { numberOfRefToStr = 0; - ClassModel classFile = Classfile.of().parse( + ClassModel classFile = ClassFile.of().parse( new BufferedInputStream(Files.newInputStream(path)).readAllBytes()); constantPool = classFile.constantPool(); for (MethodModel method: classFile.methods()) { diff --git a/test/langtools/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java b/test/langtools/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java index 15cd4ea8d70cd..27d01bbf27b49 100644 --- a/test/langtools/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java +++ b/test/langtools/tools/javac/T8024039/NoDeadCodeGenerationOnTrySmtTest.java @@ -26,14 +26,10 @@ * @bug 8024039 * @summary javac, previous solution for JDK-8022186 was incorrect * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main NoDeadCodeGenerationOnTrySmtTest @@ -44,9 +40,9 @@ import com.sun.tools.javac.util.Assert; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.instruction.ExceptionCatch; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.instruction.ExceptionCatch; import toolbox.JavacTask; import toolbox.ToolBox; @@ -104,7 +100,7 @@ void compileTestClass() throws Exception { } void checkClassFile(final File cfile, String[] methodsToFind) throws Exception { - ClassModel classFile = Classfile.of().parse(cfile.toPath()); + ClassModel classFile = ClassFile.of().parse(cfile.toPath()); int numberOfmethodsFound = 0; for (String methodToFind : methodsToFind) { for (MethodModel m : classFile.methods()) { diff --git a/test/langtools/tools/javac/T8028504/DontGenerateLVTForGNoneOpTest.java b/test/langtools/tools/javac/T8028504/DontGenerateLVTForGNoneOpTest.java index 0320e3ba5e535..90352ba6702b3 100644 --- a/test/langtools/tools/javac/T8028504/DontGenerateLVTForGNoneOpTest.java +++ b/test/langtools/tools/javac/T8028504/DontGenerateLVTForGNoneOpTest.java @@ -25,11 +25,7 @@ * @test * @bug 8028504 * @summary javac generates LocalVariableTable even with -g:none - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @compile -g:none DontGenerateLVTForGNoneOpTest.java * @run main DontGenerateLVTForGNoneOpTest */ @@ -39,8 +35,8 @@ import java.lang.annotation.Target; import java.nio.file.Paths; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; public class DontGenerateLVTForGNoneOpTest { @@ -54,7 +50,7 @@ void run() throws Exception { } void checkClassFile(final File cfile) throws Exception { - ClassModel classFile = Classfile.of().parse(cfile.toPath()); + ClassModel classFile = ClassFile.of().parse(cfile.toPath()); for (MethodModel method : classFile.methods()) { CodeAttribute code = method.findAttribute(Attributes.CODE).orElse(null); if (code != null) { diff --git a/test/langtools/tools/javac/T8180141/MissingLNTEntryForBreakContinueTest.java b/test/langtools/tools/javac/T8180141/MissingLNTEntryForBreakContinueTest.java index 645ed32de7aa6..5ca65bf9ad871 100644 --- a/test/langtools/tools/javac/T8180141/MissingLNTEntryForBreakContinueTest.java +++ b/test/langtools/tools/javac/T8180141/MissingLNTEntryForBreakContinueTest.java @@ -25,12 +25,8 @@ * @test * @bug 8180141 * @summary Missing entry in LineNumberTable for break statement that jumps out of try-finally - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.comp * jdk.compiler/com.sun.tools.javac.file @@ -56,8 +52,8 @@ import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import static com.sun.tools.javac.util.List.of; import static com.sun.tools.javac.tree.JCTree.Tag.*; @@ -93,7 +89,7 @@ void testFor(String id, String statement) throws Throwable { } File testClasses = new File("."); File file = new File(testClasses, "Test" + id + ".class"); - ClassModel classFile = Classfile.of().parse(file.toPath()); + ClassModel classFile = ClassFile.of().parse(file.toPath()); for (MethodModel m : classFile.methods()) { if (m.methodName().equalsString("foo")) { CodeAttribute code = m.findAttribute(Attributes.CODE).orElseThrow(); diff --git a/test/langtools/tools/javac/T8180660/MissingLNTEntryForFinalizerTest.java b/test/langtools/tools/javac/T8180660/MissingLNTEntryForFinalizerTest.java index dfbba1e23a7e1..504057ed7be7a 100644 --- a/test/langtools/tools/javac/T8180660/MissingLNTEntryForFinalizerTest.java +++ b/test/langtools/tools/javac/T8180660/MissingLNTEntryForFinalizerTest.java @@ -25,12 +25,8 @@ * @test * @bug 8180141 * @summary Missing entry in LineNumberTable for break statement that jumps out of try-finally - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.comp * jdk.compiler/com.sun.tools.javac.file @@ -57,8 +53,8 @@ import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import static com.sun.tools.javac.util.List.of; import static com.sun.tools.javac.tree.JCTree.Tag.*; @@ -89,7 +85,7 @@ void test() throws Throwable { } File testClasses = new File("."); File file = new File(testClasses, "Test1.class"); - ClassModel classFile = Classfile.of().parse(file.toPath()); + ClassModel classFile = ClassFile.of().parse(file.toPath()); for (MethodModel m : classFile.methods()) { if (m.methodName().equalsString("foo")) { CodeAttribute code = m.findAttribute(Attributes.CODE).orElseThrow(); diff --git a/test/langtools/tools/javac/T8187805/BogusRTTAForUnusedVarTest.java b/test/langtools/tools/javac/T8187805/BogusRTTAForUnusedVarTest.java index 4bf259c609b43..aebc8a570d5f6 100644 --- a/test/langtools/tools/javac/T8187805/BogusRTTAForUnusedVarTest.java +++ b/test/langtools/tools/javac/T8187805/BogusRTTAForUnusedVarTest.java @@ -24,12 +24,8 @@ /* * @test 8187805 * @summary bogus RuntimeVisibleTypeAnnotations for unused local in a block - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.util * @run main BogusRTTAForUnusedVarTest */ @@ -40,9 +36,9 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute; import com.sun.tools.javac.util.Assert; public class BogusRTTAForUnusedVarTest { @@ -71,7 +67,7 @@ void checkRTTA() throws Throwable { File testClasses = new File(System.getProperty("test.classes")); File file = new File(testClasses, BogusRTTAForUnusedVarTest.class.getName() + "$Foo.class"); - ClassModel classFile = Classfile.of().parse(file.toPath()); + ClassModel classFile = ClassFile.of().parse(file.toPath()); for (MethodModel m : classFile.methods()) { if (m.methodName().equalsString("something")) { for (Attribute a : m.attributes()) { diff --git a/test/langtools/tools/javac/T8203892/CheckTargetIsNotAddedAsMarkerInterfaceTest.java b/test/langtools/tools/javac/T8203892/CheckTargetIsNotAddedAsMarkerInterfaceTest.java index bcfde0766fa73..f123399c8f53d 100644 --- a/test/langtools/tools/javac/T8203892/CheckTargetIsNotAddedAsMarkerInterfaceTest.java +++ b/test/langtools/tools/javac/T8203892/CheckTargetIsNotAddedAsMarkerInterfaceTest.java @@ -25,12 +25,8 @@ * @test 8203892 * @summary Target interface added as marker interface in calls to altMetafactory * @library /tools/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util @@ -42,9 +38,9 @@ import java.io.File; import java.nio.file.Paths; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.*; import com.sun.tools.javac.util.Assert; import toolbox.JavacTask; @@ -83,7 +79,7 @@ void compileTestClass() throws Exception { } void checkClassFile(final File cfile) throws Exception { - ClassModel classFile = Classfile.of().parse(cfile.toPath()); + ClassModel classFile = ClassFile.of().parse(cfile.toPath()); for (Attribute attr : classFile.attributes()) { if (attr instanceof BootstrapMethodsAttribute bsmAttr) { BootstrapMethodEntry bsmSpecifier = bsmAttr.bootstrapMethods().getFirst(); diff --git a/test/langtools/tools/javac/T8209173/CodeCompletionExceptTest.java b/test/langtools/tools/javac/T8209173/CodeCompletionExceptTest.java index 3106c765a4467..e18761fe5d143 100644 --- a/test/langtools/tools/javac/T8209173/CodeCompletionExceptTest.java +++ b/test/langtools/tools/javac/T8209173/CodeCompletionExceptTest.java @@ -26,12 +26,8 @@ * @bug 8209173 * @summary javac fails with completion exception while reporting an error * @library /tools/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util diff --git a/test/langtools/tools/javac/T8210435/NoLocalsMustBeReservedForDCEedVarsTest.java b/test/langtools/tools/javac/T8210435/NoLocalsMustBeReservedForDCEedVarsTest.java index 7850d1ec307de..69819dd845ef3 100644 --- a/test/langtools/tools/javac/T8210435/NoLocalsMustBeReservedForDCEedVarsTest.java +++ b/test/langtools/tools/javac/T8210435/NoLocalsMustBeReservedForDCEedVarsTest.java @@ -25,12 +25,8 @@ * @test * @summary * @library /tools/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * jdk.compiler/com.sun.tools.javac.api + * @enablePreview + * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util * jdk.jdeps/com.sun.tools.javap @@ -41,8 +37,8 @@ import java.io.File; import java.nio.file.Paths; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import com.sun.tools.javac.util.Assert; import toolbox.JavacTask; @@ -69,7 +65,7 @@ void run() throws Exception { .run(); File cfile = new File(Paths.get(System.getProperty("user.dir"), "Test.class").toUri()); - ClassModel classFile = Classfile.of().parse(cfile.toPath()); + ClassModel classFile = ClassFile.of().parse(cfile.toPath()); for (MethodModel method: classFile.methods()) { if (method.methodName().stringValue().equals("foo")) { CodeAttribute codeAttr = method.findAttribute(Attributes.CODE).orElse(null); diff --git a/test/langtools/tools/javac/T8222035/MinContextOpTest_A.out b/test/langtools/tools/javac/T8222035/MinContextOpTest_A.out index 2321b85909ddc..f5b2d806c472d 100644 --- a/test/langtools/tools/javac/T8222035/MinContextOpTest_A.out +++ b/test/langtools/tools/javac/T8222035/MinContextOpTest_A.out @@ -1,4 +1,4 @@ -- compiler.warn.source.no.system.modules.path: 15 +- compiler.warn.source.no.system.modules.path: 15, (compiler.misc.source.no.system.modules.path: 15) MinContextOpTest.java:16:25: compiler.err.mod.not.allowed.here: static MinContextOpTest.java:22:25: compiler.err.mod.not.allowed.here: static MinContextOpTest.java:28:34: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: T,K,V,E, (compiler.misc.inconvertible.types: java.util.function.Function, java.util.function.Function>)) diff --git a/test/langtools/tools/javac/T8222949/TestConstantDynamic.java b/test/langtools/tools/javac/T8222949/TestConstantDynamic.java index c6a1531580dfa..79e1fbb047ff0 100644 --- a/test/langtools/tools/javac/T8222949/TestConstantDynamic.java +++ b/test/langtools/tools/javac/T8222949/TestConstantDynamic.java @@ -26,12 +26,8 @@ * @bug 8222949 * @summary add condy support to javac's pool API * @library /tools/javac/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.file @@ -53,10 +49,10 @@ import com.sun.source.util.TaskListener; import com.sun.source.util.TreeScanner; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.*; -import jdk.internal.classfile.instruction.ConstantInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.*; +import java.lang.classfile.instruction.ConstantInstruction; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.*; @@ -178,7 +174,7 @@ void verifyBytecode(Result> res) { return; } try (InputStream is = res.get().iterator().next().openInputStream()){ - ClassModel cf = Classfile.of().parse(is.readAllBytes()); + ClassModel cf = ClassFile.of().parse(is.readAllBytes()); MethodModel testMethod = null; for (MethodModel m : cf.methods()) { if (m.methodName().equalsString("test")) { diff --git a/test/langtools/tools/javac/T8320144.java b/test/langtools/tools/javac/T8320144.java new file mode 100644 index 0000000000000..6bd3c4ab66dc1 --- /dev/null +++ b/test/langtools/tools/javac/T8320144.java @@ -0,0 +1,19 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8320144 + * @summary Compilation crashes when a custom annotation with invalid default value is used + * @compile/fail/ref=T8320144.out -XDrawDiagnostics T8320144.java + */ +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +public class T8320144 { + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.TYPE}) + public @interface TestAnnotation { + public String[] excludeModules() default new String[0]; + public String[] value() default new String[] { 3 }; + } +} diff --git a/test/langtools/tools/javac/T8320144.out b/test/langtools/tools/javac/T8320144.out new file mode 100644 index 0000000000000..cb09e379cd1aa --- /dev/null +++ b/test/langtools/tools/javac/T8320144.out @@ -0,0 +1,4 @@ +T8320144.java:16:54: compiler.err.new.not.allowed.in.annotation +T8320144.java:17:45: compiler.err.new.not.allowed.in.annotation +T8320144.java:17:56: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.String) +3 errors diff --git a/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java b/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java index d2911d72e3a2f..45e30cd451678 100644 --- a/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java +++ b/test/langtools/tools/javac/TryWithResources/TwrSimpleClose.java @@ -26,12 +26,8 @@ * @bug 8194978 * @summary Verify than an appropriate number of close method invocations is generated. * @library /tools/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox TwrSimpleClose * @run main TwrSimpleClose */ @@ -57,10 +53,10 @@ import javax.tools.ToolProvider; import com.sun.source.util.JavacTask; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.MemberRefEntry; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.MemberRefEntry; +import java.lang.classfile.instruction.InvokeInstruction; import toolbox.ToolBox; @@ -102,7 +98,7 @@ void run(String trySpec, int expectedCloseCount) throws Exception { } byte[] data = fm.classBytes.values().iterator().next(); - ClassModel cf = Classfile.of().parse(new ByteArrayInputStream(data).readAllBytes()); + ClassModel cf = ClassFile.of().parse(new ByteArrayInputStream(data).readAllBytes()); for (MethodModel m : cf.methods()) { CodeAttribute codeAttr = m.findAttribute(Attributes.CODE).orElseThrow(); diff --git a/test/langtools/tools/javac/annotations/ApplicableAnnotationsOnRecords.java b/test/langtools/tools/javac/annotations/ApplicableAnnotationsOnRecords.java index fcca8563ae043..30d8a579b40ce 100644 --- a/test/langtools/tools/javac/annotations/ApplicableAnnotationsOnRecords.java +++ b/test/langtools/tools/javac/annotations/ApplicableAnnotationsOnRecords.java @@ -26,16 +26,12 @@ * @summary test for com.sun.tools.javac.comp.Check::validateAnnotation, com.sun.tools.javac.code.SymbolMetadata::removeDeclarationMetadata and ::removeFromCompoundList * @bug 8241312 8246774 * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @run main ApplicableAnnotationsOnRecords */ -import jdk.internal.classfile.*; +import java.lang.classfile.*; import com.sun.tools.javac.util.Assert; import java.lang.annotation.*; import java.io.InputStream; @@ -60,7 +56,7 @@ public record ApplicableAnnotationsOnRecords(@FieldAnnotation @MethodAnnotation public static void main(String... args) throws Exception { try ( InputStream in = ApplicableAnnotationsOnRecords.class.getResourceAsStream("ApplicableAnnotationsOnRecords.class")) { - ClassModel cm = Classfile.of().parse(Objects.requireNonNull(in).readAllBytes()); + ClassModel cm = ClassFile.of().parse(Objects.requireNonNull(in).readAllBytes()); Assert.check(cm.methods().size() > 5); for (MethodModel mm : cm.methods()) { String methodName = mm.methodName().stringValue(); diff --git a/test/langtools/tools/javac/annotations/ReadingMethodWithTypeAnno.java b/test/langtools/tools/javac/annotations/ReadingMethodWithTypeAnno.java new file mode 100644 index 0000000000000..d743615655418 --- /dev/null +++ b/test/langtools/tools/javac/annotations/ReadingMethodWithTypeAnno.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8321164 + * @summary Indirectly verify that types.erasure does not complete, called from + * ClassReader.isSameBinaryType, which must not complete. + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox + * @run main ReadingMethodWithTypeAnno + */ + +import com.sun.source.util.TaskEvent; +import com.sun.source.util.TaskListener; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import toolbox.JavacTask; +import toolbox.Task.Expect; +import toolbox.Task.OutputKind; +import toolbox.TestRunner; +import toolbox.ToolBox; + +public class ReadingMethodWithTypeAnno extends TestRunner { + public static void main(String... args) throws Exception { + ReadingMethodWithTypeAnno r = new ReadingMethodWithTypeAnno(); + r.runTests(m -> new Object[] { Paths.get(m.getName()) }); + } + + private final ToolBox tb = new ToolBox(); + + public ReadingMethodWithTypeAnno() throws IOException { + super(System.err); + } + + @Test + public void test_DeclNone_UseNone(Path base) throws IOException { + Path libSrc = base.resolve("lib-src"); + Path libClasses = Files.createDirectories(base.resolve("lib-classes")); + + tb.writeJavaFiles(libSrc, + """ + public class Lib { + public void test(java.lang.@Ann String s) { + new Object() {}; + } + } + """, + """ + import java.lang.annotation.ElementType; + import java.lang.annotation.Target; + @Target(ElementType.TYPE_USE) + public @interface Ann {} + """); + + new JavacTask(tb) + .outdir(libClasses) + .files(tb.findJavaFiles(libSrc)) + .run(Expect.SUCCESS) + .writeAll() + .getOutput(OutputKind.DIRECT); + + Path src = base.resolve("src"); + Path classes = Files.createDirectories(base.resolve("classes")); + + tb.writeJavaFiles(src, + """ + public class Test { + } + """); + + new JavacTask(tb) + .outdir(classes) + .classpath(libClasses) + .files(tb.findJavaFiles(src)) + .callback(task -> { + task.addTaskListener(new TaskListener() { + @Override + public void finished(TaskEvent e) { + if (e.getKind() == TaskEvent.Kind.ENTER) { + task.getElements().getTypeElement("Lib"); + task.getElements().getTypeElement("Lib$1"); + } + } + }); + }) + .run(Expect.SUCCESS) + .writeAll() + .getOutput(OutputKind.DIRECT); + } + +} + diff --git a/test/langtools/tools/javac/annotations/SyntheticParameters.java b/test/langtools/tools/javac/annotations/SyntheticParameters.java index 322394369f678..b26232c4989d5 100644 --- a/test/langtools/tools/javac/annotations/SyntheticParameters.java +++ b/test/langtools/tools/javac/annotations/SyntheticParameters.java @@ -26,12 +26,8 @@ * @bug 8065132 * @summary Test generation of annotations on inner class parameters. * @library /lib/annotations/ - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build annotations.classfile.ClassfileInspector SyntheticParameters * @run main SyntheticParameters */ @@ -41,7 +37,7 @@ import java.io.*; import java.lang.annotation.*; -import jdk.internal.classfile.ClassModel; +import java.lang.classfile.ClassModel; public class SyntheticParameters extends ClassfileInspector { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/TypeAnnotationsPositionsOnRecords.java b/test/langtools/tools/javac/annotations/typeAnnotations/TypeAnnotationsPositionsOnRecords.java index a0257ef1e17ee..2f6ac3a47172e 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/TypeAnnotationsPositionsOnRecords.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/TypeAnnotationsPositionsOnRecords.java @@ -26,12 +26,8 @@ * @bug 8246774 * @summary Verify location of type annotations on records * @library /tools/lib + * @enablePreview * @modules - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -50,8 +46,8 @@ import java.lang.annotation.*; import java.util.Arrays; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import com.sun.tools.javac.util.Assert; import toolbox.JavacTask; @@ -115,7 +111,7 @@ void compileTestClass() throws Exception { } void checkClassFile(final File cfile, int... taPositions) throws Exception { - ClassModel classFile = Classfile.of().parse(cfile.toPath()); + ClassModel classFile = ClassFile.of().parse(cfile.toPath()); int accessorPos = 0; int checkedAccessors = 0; for (MethodModel method : classFile.methods()) { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/VariablesDeclaredWithVarTest.java b/test/langtools/tools/javac/annotations/typeAnnotations/VariablesDeclaredWithVarTest.java index f49304de68802..ffd45ddfca41c 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/VariablesDeclaredWithVarTest.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/VariablesDeclaredWithVarTest.java @@ -26,12 +26,8 @@ * @bug 8261205 * @summary check that potentially applicable type annotations are skip if the variable or parameter was declared with var * @library /tools/lib + * @enablePreview * @modules - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -50,8 +46,8 @@ import java.lang.annotation.*; import java.util.Arrays; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import com.sun.tools.javac.util.Assert; import toolbox.JavacTask; @@ -103,7 +99,7 @@ void compileTestClass() throws Exception { } void checkClassFile(final File cfile, int... taPositions) throws Exception { - ClassModel classFile = Classfile.of().parse(cfile.toPath()); + ClassModel classFile = ClassFile.of().parse(cfile.toPath()); List annos = new ArrayList<>(); for (MethodModel method : classFile.methods()) { findAnnotations(classFile, method, annos); diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/AnonymousClassTest.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/AnonymousClassTest.java index 99b910d0c4e84..bf2bfd2a370f5 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/AnonymousClassTest.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/AnonymousClassTest.java @@ -26,13 +26,9 @@ * @bug 8198945 8207018 8207017 * @summary Invalid RuntimeVisibleTypeAnnotations for annotation on anonymous class type parameter * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * jdk.jdeps/com.sun.tools.javap * @build toolbox.ToolBox toolbox.JavapTask @@ -42,9 +38,9 @@ import static java.util.stream.Collectors.toSet; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -102,7 +98,7 @@ public static void main(String args[]) throws Exception { } static void testAnonymousClassDeclaration() throws Exception { - ClassModel cm = Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest$1.class")); + ClassModel cm = ClassFile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest$1.class")); RuntimeVisibleTypeAnnotationsAttribute rvta = cm.findAttribute(Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS).orElse(null); assert rvta != null; @@ -116,7 +112,7 @@ static void testAnonymousClassDeclaration() throws Exception { } static void testTopLevelMethod() throws Exception { - ClassModel cm = Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class")); + ClassModel cm = ClassFile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class")); MethodModel method = findMethod(cm, "f"); Set annotations = getRuntimeVisibleTypeAnnotations(method); CodeAttribute cAttr = method.findAttribute(Attributes.CODE).orElse(null); @@ -127,7 +123,7 @@ static void testTopLevelMethod() throws Exception { static void testInnerClassMethod() throws Exception { ClassModel cm = - Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest$Inner.class")); + ClassFile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest$Inner.class")); MethodModel method = findMethod(cm, "g"); Set annotations = getRuntimeVisibleTypeAnnotations(method); CodeAttribute cAttr = method.findAttribute(Attributes.CODE).orElse(null); @@ -142,7 +138,7 @@ static void testInnerClassMethod() throws Exception { static void testQualifiedSuperType() throws Exception { { ClassModel cm = - Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class")); + ClassFile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class")); MethodModel method = findMethod(cm, "g"); Set annotations = getRuntimeVisibleTypeAnnotations(method); CodeAttribute cAttr = method.findAttribute(Attributes.CODE).orElse(null); @@ -154,7 +150,7 @@ static void testQualifiedSuperType() throws Exception { { ClassModel cm = - Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest$2.class")); + ClassFile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest$2.class")); RuntimeVisibleTypeAnnotationsAttribute rvta = cm.findAttribute(Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS).orElse(null); assert rvta != null; @@ -169,7 +165,7 @@ static void testQualifiedSuperType() throws Exception { } static void testInstanceAndClassInit() throws Exception { - ClassModel cm = Classfile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class")); + ClassModel cm = ClassFile.of().parse(Paths.get(ToolBox.testClasses, "AnonymousClassTest.class")); MethodModel method = findMethod(cm, ""); Set annotations = getRuntimeVisibleTypeAnnotations(method); CodeAttribute cAttr1 = method.findAttribute(Attributes.CODE).orElse(null); diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java index 856ce1fb6e20c..4926e15b25845 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/ClassfileTestHelper.java @@ -25,8 +25,8 @@ import java.net.URL; import java.util.List; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.util.ArrayList; public class ClassfileTestHelper { @@ -63,13 +63,13 @@ ClassModel getClassFile(String name) throws IOException { URL url = getClass().getResource(name); assert url != null; try (InputStream in = url.openStream()) { - return Classfile.of().parse(in.readAllBytes()); + return ClassFile.of().parse(in.readAllBytes()); } } ClassModel getClassFile(URL url) throws IOException { try (InputStream in = url.openStream()) { - return Classfile.of().parse(in.readAllBytes()); + return ClassFile.of().parse(in.readAllBytes()); } } diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java index 0f855d7d426ec..dfe116580b529 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest1.java @@ -25,15 +25,11 @@ * @test * @bug 8005085 8005877 8004829 8005681 8006734 8006775 * @summary Combinations of Target ElementTypes on (repeated)type annotations. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ -import jdk.internal.classfile.*; +import java.lang.classfile.*; import java.io.File; public class CombinationsTargetTest1 extends ClassfileTestHelper { @@ -147,7 +143,7 @@ public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats, classFile=new File(sb.insert(sb.lastIndexOf(".class"), innerClassname).toString()); } - ClassModel cm = Classfile.of().parse(classFile.toPath()); + ClassModel cm = ClassFile.of().parse(classFile.toPath()); //Test class,fields and method counts. test(cm); diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java index 3ce48df24ba4e..46f5717103a9e 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest2.java @@ -25,15 +25,11 @@ * @test * @bug 8005085 8005877 8004829 8005681 8006734 8006775 8006507 * @summary Combinations of Target ElementTypes on (repeated)type annotations. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ -import jdk.internal.classfile.*; +import java.lang.classfile.*; import java.io.File; import java.util.List; @@ -166,7 +162,7 @@ public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats, classFile=new File(sb.insert(sb.lastIndexOf(".class"),innerClassname).toString()); println("classfile: " + classFile.getAbsolutePath()); } - ClassModel cm = Classfile.of().parse(classFile.toPath()); + ClassModel cm = ClassFile.of().parse(classFile.toPath()); //Test class,fields and method counts. test(cm); diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest3.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest3.java index 6b026f162952d..d0a4deef80b89 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest3.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/CombinationsTargetTest3.java @@ -25,12 +25,8 @@ * @test * @bug 8005085 8005681 8008769 8010015 * @summary Check (repeating)type annotations on lambda usage. + * @enablePreview * @modules jdk.jdeps/com.sun.tools.classfile - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @run main CombinationsTargetTest3 */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java index 893283a945090..02caa8df61503 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/DeadCode.java @@ -26,18 +26,14 @@ import java.net.URL; import java.util.List; -import jdk.internal.classfile.*; +import java.lang.classfile.*; /* * @test * @bug 6917130 8006775 * @summary test that optimized away annotations are not emited to classfile - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ public class DeadCode extends ClassfileTestHelper { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/InstanceInitializer.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/InstanceInitializer.java index cdf9f78a93539..be3ca03c30c7e 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/InstanceInitializer.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/InstanceInitializer.java @@ -21,7 +21,7 @@ * questions. */ -import jdk.internal.classfile.*; +import java.lang.classfile.*; import java.lang.annotation.*; import java.util.ArrayList; @@ -29,12 +29,8 @@ * @test * @bug 8136419 8200301 * @summary test that type annotations on entities in initializers are emitted to classfile - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -XDdeduplicateLambdas=false InstanceInitializer.java * @run main InstanceInitializer */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java index 8dff27a210838..f447dde8998a5 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/NewTypeArguments.java @@ -21,7 +21,7 @@ * questions. */ -import jdk.internal.classfile.*; +import java.lang.classfile.*; import java.lang.annotation.*; import java.io.*; import java.net.URL; @@ -31,12 +31,8 @@ /* * @test ClassLiterals * @summary test that new type arguments are emitted to classfile - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ public class NewTypeArguments extends ClassfileTestHelper{ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java index d38bee259e6aa..13082ba9dad9d 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/NoTargetAnnotations.java @@ -27,19 +27,15 @@ import java.net.URL; import java.util.List; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; /* * @test NoTargetAnnotations * @summary test that annotations with no Target meta type is emitted * only once as declaration annotation - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ public class NoTargetAnnotations extends ClassfileTestHelper { @@ -69,7 +65,7 @@ ClassModel getClassFile(String name) throws IOException { URL url = getClass().getResource(name); assert url != null; try (InputStream in = url.openStream()) { - return Classfile.of().parse(in.readAllBytes()); + return ClassFile.of().parse(in.readAllBytes()); } } diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Scopes.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Scopes.java index baf913f88a14a..35bc576a2caa0 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Scopes.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Scopes.java @@ -25,19 +25,15 @@ import java.io.*; import java.net.URL; import java.util.List; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; /* * @test * @bug 6843077 8006775 * @summary Qualified inner type annotation accessible to the class. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ @Scopes.UniqueInner diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/StaticInitializer.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/StaticInitializer.java index fe84a617d8d31..8034154478915 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/StaticInitializer.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/StaticInitializer.java @@ -24,18 +24,14 @@ import java.lang.annotation.*; import java.util.ArrayList; -import jdk.internal.classfile.*; +import java.lang.classfile.*; /* * @test * @bug 8136419 8200301 * @summary test that type annotations on entities in static initializers are emitted to classfile - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -XDdeduplicateLambdas=false StaticInitializer.java * @run main StaticInitializer */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/SyntheticParameters.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/SyntheticParameters.java index 817808d35777b..4b8d317d771f6 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/SyntheticParameters.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/SyntheticParameters.java @@ -25,18 +25,14 @@ * @test SyntheticParameters * @summary Test generation of annotations on inner class parameters. * @library /lib/annotations/ - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @run main SyntheticParameters */ import annotations.classfile.ClassfileInspector; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.TypeAnnotation; +import java.lang.classfile.ClassModel; +import java.lang.classfile.TypeAnnotation; import java.io.*; import java.lang.annotation.*; diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8008762.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8008762.java index e80a07b91b715..5dae330b193fd 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8008762.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8008762.java @@ -26,18 +26,14 @@ * @bug 8008762 * @summary Type annotation on inner class in anonymous class * shows up as regular annotation - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ import java.lang.annotation.*; import static java.lang.annotation.RetentionPolicy.*; import static java.lang.annotation.ElementType.*; -import jdk.internal.classfile.*; +import java.lang.classfile.*; public class T8008762 extends ClassfileTestHelper{ public static void main(String[] args) throws Exception { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8008769.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8008769.java index 18c5f90e0b356..fc9ffdfef1da2 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8008769.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8008769.java @@ -26,17 +26,13 @@ * @summary Repeated type-annotations on type parm of local variable * are not written to classfile. * @bug 8008769 - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ import java.lang.annotation.*; import static java.lang.annotation.RetentionPolicy.*; import static java.lang.annotation.ElementType.*; -import jdk.internal.classfile.*; +import java.lang.classfile.*; public class T8008769 extends ClassfileTestHelper{ public static void main(String[] args) throws Exception { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8010015.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8010015.java index 9b8d5e6a4ce38..635f4ce9fb264 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8010015.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/T8010015.java @@ -25,18 +25,14 @@ * @test * @summary Wrong classfile attribution in inner class of lambda expression. * @bug 8010015 - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ import java.lang.annotation.*; import static java.lang.annotation.RetentionPolicy.*; import static java.lang.annotation.ElementType.*; -import jdk.internal.classfile.*; +import java.lang.classfile.*; /* * A type-annotations on a field in an inner class not in a lambda expression diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TestAnonInnerClasses.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TestAnonInnerClasses.java index 9e96b91d7b5e6..59ed653927bd1 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TestAnonInnerClasses.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TestAnonInnerClasses.java @@ -33,15 +33,11 @@ * results in 2). Elements with no annotations expect 0. * Source template is read in from testanoninner.template * - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.io.*; import java.util.*; import java.nio.file.Files; @@ -321,7 +317,7 @@ public >void run() { 0,classFile.getAbsolutePath().indexOf(classFile.getPath())); for (String clazz : classes) { try { - cm = Classfile.of().parse(new File(testloc+clazz).toPath()); + cm = ClassFile.of().parse(new File(testloc+clazz).toPath()); } catch (Exception e) { e.printStackTrace(); } // Test for all methods and fields diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TestNewCastArray.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TestNewCastArray.java index e5f0622f42f3f..741747a9b4cd0 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TestNewCastArray.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TestNewCastArray.java @@ -25,15 +25,11 @@ * @test * @bug 8005681 * @summary Repeated annotations on new,array,cast. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.lang.annotation.*; import java.io.*; import java.util.List; @@ -204,7 +200,7 @@ public void run() { System.out.println("Testing " + testclazz); try { in = Objects.requireNonNull(getClass().getResource(testclazz)).openStream(); - cm = Classfile.of().parse(in.readAllBytes()); + cm = ClassFile.of().parse(in.readAllBytes()); in.close(); } catch(Exception e) { e.printStackTrace(); } diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TypeAnnotationPropagationTest.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TypeAnnotationPropagationTest.java index 9f8622386eb33..ae92d7aae0446 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TypeAnnotationPropagationTest.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TypeAnnotationPropagationTest.java @@ -25,20 +25,16 @@ * @test * @bug 8144185 * @summary javac produces incorrect RuntimeInvisibleTypeAnnotations length attribute - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ import static java.lang.annotation.ElementType.TYPE_USE; import static java.lang.annotation.RetentionPolicy.RUNTIME; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.Arrays; diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java index cca0af32abc4c..04907df12039c 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/TypeCasts.java @@ -26,18 +26,14 @@ import java.net.URL; import java.util.List; -import jdk.internal.classfile.*; +import java.lang.classfile.*; /* * @test * @bug 6843077 8006775 * @summary test that typecasts annotation are emitted if only the cast * expression is optimized away - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ public class TypeCasts extends ClassfileTestHelper{ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java index 0b54fdbe58c9c..31d9294f12032 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Wildcards.java @@ -26,17 +26,13 @@ import java.net.URL; import java.util.List; -import jdk.internal.classfile.*; +import java.lang.classfile.*; /* * @test Wildcards * @bug 6843077 8006775 * @summary test that annotations target wildcards get emitted to classfile - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ public class Wildcards extends ClassfileTestHelper { public static void main(String[] args) throws Exception { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java index d99f66e4e697d..8607b1cc312bd 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ClassExtends.java @@ -21,18 +21,14 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8042451 8164519 * @summary Test population of reference info for class extends clauses - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java ClassExtends.java * @run main Driver ClassExtends */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java index 4b9524fc621db..696d3b3292971 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ClassTypeParam.java @@ -21,18 +21,14 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8042451 * @summary Test population of reference info for class type parameters - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java ClassTypeParam.java * @run main Driver ClassTypeParam */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ConstructorInvocationTypeArgument.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ConstructorInvocationTypeArgument.java index 2522164a79849..bcffb424827e9 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ConstructorInvocationTypeArgument.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ConstructorInvocationTypeArgument.java @@ -25,17 +25,13 @@ * @test * @bug 8042451 * @summary Test population of reference info for constructor invocation type argument - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java ConstructorInvocationTypeArgument.java * @run main Driver ConstructorInvocationTypeArgument */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT; +import static java.lang.classfile.TypeAnnotation.TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT; public class ConstructorInvocationTypeArgument { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java index 9e76c3c05031a..beab5ea9fb532 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Constructors.java @@ -25,17 +25,13 @@ * @test * @bug 8026791 8042451 * @summary Test population of reference info for constructor results - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java Constructors.java * @run main Driver Constructors */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; public class Constructors { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java index 16559d03a482a..333fd9844b091 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Driver.java @@ -21,7 +21,7 @@ * questions. */ -import jdk.internal.classfile.*; +import java.lang.classfile.*; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; @@ -163,7 +163,7 @@ private String testClassOf(Method m, String testClassName) { private ClassModel compileAndReturn(String fullFile, String testClass, String... extraParams) throws Exception { File source = writeTestFile(fullFile, testClass); File clazzFile = compileTestFile(source, testClass, extraParams); - return Classfile.of().parse(clazzFile.toPath()); + return ClassFile.of().parse(clazzFile.toPath()); } protected File writeTestFile(String fullFile, String testClass) throws IOException { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java index 3fa4551d1b00b..b479f7dcfdc15 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ExceptionParameters.java @@ -21,19 +21,15 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8028576 8042451 * @summary Test population of reference info for exception parameters * @author Werner Dietl - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java ExceptionParameters.java * @run main Driver ExceptionParameters */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java index 8e7815c2bf204..7a77ac2390b36 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Fields.java @@ -25,17 +25,13 @@ * @test * @bug 8042451 8208470 * @summary Test population of reference info for field - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java Fields.java * @run main Driver Fields */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; public class Fields { // field types diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java index 249b723328b52..b52a20353d874 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/FromSpecification.java @@ -21,18 +21,14 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8042451 * @summary Test that the examples from the manual are stored as expected - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java FromSpecification.java * @run main Driver FromSpecification */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Initializers.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Initializers.java index c5de40c06905d..706edb453b13f 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Initializers.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Initializers.java @@ -21,19 +21,15 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8013852 8042451 * @summary Test population of reference info for instance and class initializers * @author Werner Dietl - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java Initializers.java * @run main Driver Initializers */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java index ccdffbae74628..690f0ddc1867b 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/Lambda.java @@ -26,19 +26,15 @@ * @bug 8008077 8029721 8042451 8043974 * @summary Test population of reference info for lambda expressions * javac crash for annotated parameter type of lambda in a field - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @ignore 8057687 emit correct byte code an attributes for type annotations * @compile -g Driver.java ReferenceInfoUtil.java Lambda.java * @run main Driver Lambda * @author Werner Dietl */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; public class Lambda { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodInvocationTypeArgument.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodInvocationTypeArgument.java index 5be36df634e22..f0df24e38056e 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodInvocationTypeArgument.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodInvocationTypeArgument.java @@ -25,17 +25,13 @@ * @test * @bug 8042451 * @summary Test population of reference info for method invocation type arguments - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java MethodInvocationTypeArgument.java * @run main Driver MethodInvocationTypeArgument */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.METHOD_INVOCATION_TYPE_ARGUMENT; +import static java.lang.classfile.TypeAnnotation.TargetType.METHOD_INVOCATION_TYPE_ARGUMENT; import static java.lang.System.lineSeparator; public class MethodInvocationTypeArgument { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java index b06ad3cec96a7..2f5b6d43636d2 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodParameters.java @@ -21,18 +21,14 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8042451 * @summary Test population of reference info for method parameters - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java MethodParameters.java * @run main Driver MethodParameters */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java index f6c15b5a0d03c..faae9c91c04b5 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReceivers.java @@ -21,18 +21,14 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8042451 * @summary Test population of reference info for method receivers - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java MethodReceivers.java * @run main Driver MethodReceivers */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java index ebc9217946c0e..ee7248db119f3 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodReturns.java @@ -21,18 +21,14 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8042451 * @summary Test population of reference info for method return - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java MethodReturns.java * @run main Driver MethodReturns */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java index 83b0d2e95e2f5..546b8cdeb0a23 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodThrows.java @@ -21,18 +21,14 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8042451 * @summary Test population of reference info for method exception clauses - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java MethodThrows.java * @run main Driver MethodThrows */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java index a4a267b83f6cc..fa6203e3fffe2 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MethodTypeParam.java @@ -21,19 +21,15 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; import static java.lang.System.lineSeparator; /* * @test * @bug 8042451 * @summary Test population of reference info for method type parameters - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java MethodTypeParam.java * @run main Driver MethodTypeParam */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java index b1a395aa81c93..a3d927a0fb93a 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/MultiCatch.java @@ -21,19 +21,15 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8006732 8006775 8042451 * @summary Test population of reference info for multicatch exception parameters * @author Werner Dietl - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java MultiCatch.java * @run main Driver MultiCatch */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java index 5ba71a33ab99f..f3b54ff35a1db 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java @@ -21,18 +21,14 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8042451 8044009 8044010 * @summary Test population of reference info for nested types - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @ignore 8057687 emit correct byte code an attributes for type annotations * @compile -g Driver.java ReferenceInfoUtil.java NestedTypes.java * @run main Driver NestedTypes diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java index ba7581df340b2..cac938a4869e5 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/NewObjects.java @@ -21,18 +21,14 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8042451 * @summary Test population of reference info for new object creations - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java NewObjects.java * @run main Driver NewObjects */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java index 51772f2e4609a..7e35a081de71d 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ReferenceInfoUtil.java @@ -21,8 +21,8 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.util.*; public class ReferenceInfoUtil { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java index 8d6b8b15ef8c2..70cb3a94bd8d3 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/RepeatingTypeAnnotations.java @@ -21,17 +21,13 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @summary Test population of reference info for repeating type annotations - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java RepeatingTypeAnnotations.java * @run main Driver RepeatingTypeAnnotations * @author Werner Dietl diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ResourceVariable.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ResourceVariable.java index 84fbed87e2152..e1be3ea1435ce 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ResourceVariable.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/ResourceVariable.java @@ -25,17 +25,13 @@ * @test * @bug 8042451 * @summary Test population of reference info for resource variable - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java ResourceVariable.java * @run main Driver ResourceVariable */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.RESOURCE_VARIABLE; +import static java.lang.classfile.TypeAnnotation.TargetType.RESOURCE_VARIABLE; import static java.lang.System.lineSeparator; public class ResourceVariable { diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java index acf044af92e34..9afaffe0bf1a6 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/TypeCasts.java @@ -21,18 +21,14 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8042451 * @summary Test population of reference info for type casts - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java TypeCasts.java * @run main Driver TypeCasts */ diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java index a1cd7fedccfa6..5cbb6a370fa0e 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/referenceinfos/TypeTests.java @@ -21,18 +21,14 @@ * questions. */ -import static jdk.internal.classfile.TypeAnnotation.TargetType.*; +import static java.lang.classfile.TypeAnnotation.TargetType.*; /* * @test * @bug 8042451 * @summary Test population of reference info for class literals - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g Driver.java ReferenceInfoUtil.java TypeTests.java * @run main Driver TypeTests */ diff --git a/test/langtools/tools/javac/api/TestGetSourceVersions.java b/test/langtools/tools/javac/api/TestGetSourceVersions.java index 710c3a831ea47..a4b91462add5b 100644 --- a/test/langtools/tools/javac/api/TestGetSourceVersions.java +++ b/test/langtools/tools/javac/api/TestGetSourceVersions.java @@ -24,7 +24,7 @@ /* * @test * @bug 6395981 6458819 7025784 8028543 8028544 8193291 8193292 8193292 8205393 8245585 8245585 8245585 8286034 - * 8296150 8306585 + * 8296150 8306585 8319414 * @summary JavaCompilerTool and Tool must specify version of JLS and JVMS * @author Peter von der Ah\u00e9 * @modules java.compiler @@ -37,6 +37,7 @@ * RELEASE_8 RELEASE_9 RELEASE_10 RELEASE_11 RELEASE_12 * RELEASE_13 RELEASE_14 RELEASE_15 RELEASE_16 RELEASE_17 * RELEASE_18 RELEASE_19 RELEASE_20 RELEASE_21 RELEASE_22 + * RELEASE_23 */ import java.util.EnumSet; diff --git a/test/langtools/tools/javac/api/snippets/TestJavaxToolsSnippets.java b/test/langtools/tools/javac/api/snippets/TestJavaxToolsSnippets.java index 10030df1679b1..eb5b071df6fc4 100644 --- a/test/langtools/tools/javac/api/snippets/TestJavaxToolsSnippets.java +++ b/test/langtools/tools/javac/api/snippets/TestJavaxToolsSnippets.java @@ -58,7 +58,11 @@ */ public class TestJavaxToolsSnippets extends TestRunner { public static void main(String... args) throws Exception { - new TestJavaxToolsSnippets().runTests(m -> new Object[] { Path.of(m.getName()) }); + try { + new TestJavaxToolsSnippets().runTests(m -> new Object[] { Path.of(m.getName()) }); + } catch (SnippetUtils.ConfigurationException e) { + System.err.println("NOTE: " + e.getMessage() + "; test skipped"); + } } SnippetUtils snippets = new SnippetUtils("java.compiler"); diff --git a/test/langtools/tools/javac/cast/intersection/DuplicatedCheckcastTest.java b/test/langtools/tools/javac/cast/intersection/DuplicatedCheckcastTest.java index affb5a0bc0b59..e8e947d408cba 100644 --- a/test/langtools/tools/javac/cast/intersection/DuplicatedCheckcastTest.java +++ b/test/langtools/tools/javac/cast/intersection/DuplicatedCheckcastTest.java @@ -27,13 +27,9 @@ * @summary javac should not emit duplicate checkcast for first bound of intersection type in cast * duplicate checkcast when destination type is not first type of intersection type * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main DuplicatedCheckcastTest @@ -42,10 +38,10 @@ import java.nio.file.Path; import java.util.ArrayList; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.ClassEntry; -import jdk.internal.classfile.instruction.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.ClassEntry; +import java.lang.classfile.instruction.*; import toolbox.JavacTask; import toolbox.TestRunner; @@ -100,7 +96,7 @@ private void duplicateCheckCastHelper(String source, String expected1, String ex .sources(source) .outdir(curPath) .run(); - cf = Classfile.of().parse(curPath.resolve("IntersectionTypeTest.class")); + cf = ClassFile.of().parse(curPath.resolve("IntersectionTypeTest.class")); ArrayList checkCastList = new ArrayList<>(); for (MethodModel method : cf.methods()) { if (method.methodName().equalsString("test")) { diff --git a/test/langtools/tools/javac/classfiles/ClassVersionChecker.java b/test/langtools/tools/javac/classfiles/ClassVersionChecker.java index 36b2a6249cf61..f44aa90a2600f 100644 --- a/test/langtools/tools/javac/classfiles/ClassVersionChecker.java +++ b/test/langtools/tools/javac/classfiles/ClassVersionChecker.java @@ -23,7 +23,7 @@ /* * @test - * @bug 7157626 8001112 8188870 8173382 8193290 8205619 8245586 8257453 + * @bug 7157626 8001112 8188870 8173382 8193290 8205619 8245586 8257453 8306586 * @summary Test major version for all legal combinations for -source and -target * @author sgoel * @@ -57,6 +57,7 @@ private static enum Version { TWENTY("20", 64), TWENTY_ONE("21", 65), TWENTY_TWO("22", 66), + TWENTY_THREE("23", 67), ; // Reduce code churn when appending new constants private Version(String release, int classFileVer) { diff --git a/test/langtools/tools/javac/classfiles/InnerClasses/SyntheticClasses.java b/test/langtools/tools/javac/classfiles/InnerClasses/SyntheticClasses.java index d1cdd1985d5d8..bab02ade067a5 100644 --- a/test/langtools/tools/javac/classfiles/InnerClasses/SyntheticClasses.java +++ b/test/langtools/tools/javac/classfiles/InnerClasses/SyntheticClasses.java @@ -25,20 +25,16 @@ * @bug 8034854 * @summary Verify that the InnerClasses attribute has outer_class_info_index zero if it has * inner_name_index zero (for synthetic classes) - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile SyntheticClasses.java * @run main SyntheticClasses */ import java.io.*; import java.util.*; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; public class SyntheticClasses { @@ -49,7 +45,7 @@ public static void main(String[] args) throws IOException { private void run() throws IOException { File testClasses = new File(System.getProperty("test.classes")); for (File classFile : Objects.requireNonNull(testClasses.listFiles(f -> f.getName().endsWith(".class")))) { - ClassModel cf = Classfile.of().parse(classFile.toPath()); + ClassModel cf = ClassFile.of().parse(classFile.toPath()); if (cf.thisClass().asInternalName().matches(".*\\$[0-9]+")) { EnclosingMethodAttribute encl = cf.findAttribute(Attributes.ENCLOSING_METHOD).orElse(null); if (encl != null) { diff --git a/test/langtools/tools/javac/classfiles/T8255757/T8255757.java b/test/langtools/tools/javac/classfiles/T8255757/T8255757.java index 2611b5f885aa8..231a132e5795f 100644 --- a/test/langtools/tools/javac/classfiles/T8255757/T8255757.java +++ b/test/langtools/tools/javac/classfiles/T8255757/T8255757.java @@ -26,13 +26,9 @@ * @bug 8255757 * @summary Javac shouldn't emit duplicate pool entries on array::clone * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main T8255757 @@ -40,8 +36,8 @@ import java.nio.file.Path; -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.*; import toolbox.JavacTask; import toolbox.ToolBox; @@ -79,7 +75,7 @@ void test2(Object[] o) { .outdir(curPath) .run(); - ClassModel cf = Classfile.of().parse(curPath.resolve("Test.class")); + ClassModel cf = ClassFile.of().parse(curPath.resolve("Test.class")); int num = 0; for (PoolEntry pe : cf.constantPool()) { if (pe instanceof MethodRefEntry methodRefEntry) { diff --git a/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultTest.java b/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultTest.java index 5aafc65fb362b..d099c4940f9a2 100644 --- a/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultTest.java @@ -26,21 +26,17 @@ * @bug 8042947 * @summary Checking AnnotationDefault attribute. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build AnnotationDefaultTest AnnotationDefaultVerifier * @run main AnnotationDefaultTest */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.io.File; import java.io.IOException; import java.lang.annotation.RetentionPolicy; diff --git a/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultVerifier.java b/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultVerifier.java index 0a10e710c9a34..a5598d1f24270 100644 --- a/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultVerifier.java +++ b/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultVerifier.java @@ -21,9 +21,9 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.ConstantPoolBuilder; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.ConstantPoolBuilder; import jdk.internal.classfile.impl.*; import java.util.Arrays; @@ -70,7 +70,7 @@ private TestElementValue get(int tag) { private abstract class TestElementValue { public void testLength(TestResult testCase, AnnotationDefaultAttribute attr) { - BufWriter buf = new BufWriterImpl(ConstantPoolBuilder.of(), (ClassfileImpl) Classfile.of()); + BufWriter buf = new BufWriterImpl(ConstantPoolBuilder.of(), (ClassFileImpl) ClassFile.of()); attr.defaultValue().writeTo(buf); testCase.checkEquals(((BoundAttribute)attr).payloadLen(), buf.size(), "attribute_length"); diff --git a/test/langtools/tools/javac/classfiles/attributes/EnclosingMethod/EnclosingMethodTest.java b/test/langtools/tools/javac/classfiles/attributes/EnclosingMethod/EnclosingMethodTest.java index 837fb64287b7f..d34d3a7db0570 100644 --- a/test/langtools/tools/javac/classfiles/attributes/EnclosingMethod/EnclosingMethodTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/EnclosingMethod/EnclosingMethodTest.java @@ -26,20 +26,16 @@ * @bug 8042931 8215470 * @summary Checking EnclosingMethod attribute of anonymous/local class. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @run main EnclosingMethodTest */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.EnclosingMethodAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.EnclosingMethodAttribute; import jdk.internal.classfile.impl.BoundAttribute; import java.io.File; diff --git a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTest.java b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTest.java index 6a2faa34b9c14..8312b535f50f9 100644 --- a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTest.java @@ -26,14 +26,10 @@ * @summary Tests a line number table attribute for language constructions in different containers. * @bug 8040131 * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase * @build LineNumberTestBase Container TestCase diff --git a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java index 867a67057e98c..f9227dde4df6f 100644 --- a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java @@ -21,8 +21,8 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import jdk.internal.classfile.impl.BoundAttribute; import java.io.InputStream; @@ -69,7 +69,7 @@ protected void test(List testCases) throws Exception { for (JavaFileObject file : compile(testCase.extraCompilerOptions, testCase.src).getClasses().values()) { ClassModel classFile; try (InputStream input = file.openInputStream()) { - classFile = Classfile.of().parse(input.readAllBytes()); + classFile = ClassFile.of().parse(input.readAllBytes()); } for (MethodModel m : classFile.methods()) { CodeAttribute code_attribute = m.findAttribute(Attributes.CODE).orElse(null); diff --git a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/MultipleRecordPatterns.java b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/MultipleRecordPatterns.java index b567c05151db0..53a60b69cb032 100644 --- a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/MultipleRecordPatterns.java +++ b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/MultipleRecordPatterns.java @@ -26,14 +26,10 @@ * @bug 8307814 * @summary Verify correct LineNumberTable is generated for unrolled record patterns. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase * @build LineNumberTestBase TestCase diff --git a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/RuleSwitchBreaks.java b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/RuleSwitchBreaks.java index f6dca5ed6b029..58f1386a0006b 100644 --- a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/RuleSwitchBreaks.java +++ b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/RuleSwitchBreaks.java @@ -26,14 +26,10 @@ * @bug 8262891 * @summary Verify correct LineNumberTable for rule switches. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase * @build LineNumberTestBase TestCase diff --git a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/StringSwitchBreaks.java b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/StringSwitchBreaks.java index 977fec346c43f..e22a847370b2e 100644 --- a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/StringSwitchBreaks.java +++ b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/StringSwitchBreaks.java @@ -26,14 +26,10 @@ * @bug 8261606 * @summary Tests a line number table attribute for language constructions in different containers. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase * @build LineNumberTestBase TestCase diff --git a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/T8050993.java b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/T8050993.java index 5ec7ba973c20d..dade8e984304f 100644 --- a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/T8050993.java +++ b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/T8050993.java @@ -2,12 +2,8 @@ * @test /nodynamiccopyright/ * @bug 8050993 * @summary Verify that the condition in the conditional lexpression gets a LineNumberTable entry - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g T8050993.java * @run main T8050993 */ @@ -19,12 +15,12 @@ import java.util.Set; import java.util.stream.Collectors; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; public class T8050993 { public static void main(String[] args) throws IOException { - ClassModel someTestIn = Classfile.of().parse(T8050993.class.getResourceAsStream("T8050993.class").readAllBytes()); + ClassModel someTestIn = ClassFile.of().parse(T8050993.class.getResourceAsStream("T8050993.class").readAllBytes()); Set expectedLineNumbers = new HashSet<>(Arrays.asList(49, 50, 47, 48)); for (MethodModel m : someTestIn.methods()) { if (m.methodName().equalsString("method")) { diff --git a/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTableTest.java b/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTableTest.java index 7dd7a3e706b01..1139b8d2fdefc 100644 --- a/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTableTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTableTest.java @@ -26,14 +26,10 @@ * @summary local variable table attribute test. * @bug 8040097 * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase * @build LocalVariableTestBase @@ -41,7 +37,7 @@ * @run main LocalVariableTableTest */ -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.attribute.*; import jdk.internal.classfile.impl.BoundAttribute; import java.io.IOException; diff --git a/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTestBase.java b/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTestBase.java index 7fe81fe7f1ded..9d2e19c86bafa 100644 --- a/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTestBase.java @@ -21,8 +21,8 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.io.IOException; import java.lang.annotation.Repeatable; @@ -60,7 +60,7 @@ public abstract class LocalVariableTestBase extends TestBase { public LocalVariableTestBase(Class clazz) { this.clazz = clazz; try { - this.classFile = Classfile.of().parse(getClassFile(clazz).toPath()); + this.classFile = ClassFile.of().parse(getClassFile(clazz).toPath()); } catch (IOException e) { throw new IllegalArgumentException("Can't read classfile for specified class", e); } diff --git a/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTypeTableTest.java b/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTypeTableTest.java index 38fb687b429cf..6681231e4b254 100644 --- a/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTypeTableTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/LocalVariableTable/LocalVariableTypeTableTest.java @@ -26,21 +26,17 @@ * @summary local variable type table attribute test. * @bug 8040097 * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase LocalVariableTestBase * @compile -g LocalVariableTypeTableTest.java * @run main LocalVariableTypeTableTest */ -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.attribute.*; import jdk.internal.classfile.impl.BoundAttribute; import java.io.IOException; diff --git a/test/langtools/tools/javac/classfiles/attributes/Module/ModuleFlagTest.java b/test/langtools/tools/javac/classfiles/attributes/Module/ModuleFlagTest.java index 42be9f74e8257..a0e88b7c602b7 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Module/ModuleFlagTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Module/ModuleFlagTest.java @@ -26,21 +26,17 @@ * @bug 8080878 * @summary Checking ACC_MODULE flag is generated for module-info. * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask toolbox.ToolBox * @run main ModuleFlagTest */ -import jdk.internal.classfile.AccessFlags; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.AccessFlags; +import java.lang.classfile.ClassFile; import java.lang.reflect.AccessFlag; import java.io.IOException; @@ -61,10 +57,10 @@ public static void main(String[] args) throws IOException { .files(moduleInfo) .run(); - AccessFlags accessFlags = Classfile.of().parse(outdir.resolve("module-info.class")) + AccessFlags accessFlags = ClassFile.of().parse(outdir.resolve("module-info.class")) .flags(); if (!accessFlags.has(AccessFlag.MODULE)) { - throw new RuntimeException("Classfile doesn't have module access flag"); + throw new RuntimeException("ClassFile doesn't have module access flag"); } } } diff --git a/test/langtools/tools/javac/classfiles/attributes/Module/ModuleTest.java b/test/langtools/tools/javac/classfiles/attributes/Module/ModuleTest.java index ca4550a44e6c9..c6a329b7d0b39 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Module/ModuleTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Module/ModuleTest.java @@ -25,15 +25,11 @@ * @test * @summary Module attribute tests * @bug 8080878 8161906 8162713 8170250 + * @enablePreview * @modules java.compiler * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @library /tools/lib ../lib /tools/javac/lib * @build toolbox.ToolBox toolbox.JavacTask toolbox.ToolBox diff --git a/test/langtools/tools/javac/classfiles/attributes/Module/ModuleTestBase.java b/test/langtools/tools/javac/classfiles/attributes/Module/ModuleTestBase.java index ce6231b6ec199..8f7e5c042504d 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Module/ModuleTestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/Module/ModuleTestBase.java @@ -21,9 +21,9 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.*; import java.io.IOException; import java.lang.annotation.Retention; @@ -69,7 +69,7 @@ protected void run() throws Exception { } protected void testModuleAttribute(Path modulePath, ModuleDescriptor moduleDescriptor) throws Exception { - ClassModel classFile = Classfile.of().parse(modulePath.resolve("module-info.class")); + ClassModel classFile = ClassFile.of().parse(modulePath.resolve("module-info.class")); ModuleAttribute moduleAttribute = classFile.findAttribute(Attributes.MODULE).orElse(null); assert moduleAttribute != null; testModuleName(moduleDescriptor, moduleAttribute); @@ -193,7 +193,7 @@ interface Mask { } public enum ModuleFlag implements Mask { - OPEN("open", Classfile.ACC_OPEN); + OPEN("open", ClassFile.ACC_OPEN); private final String token; private final int mask; @@ -210,9 +210,9 @@ public int getMask() { } public enum RequiresFlag implements Mask { - TRANSITIVE("transitive", Classfile.ACC_TRANSITIVE), - STATIC("static", Classfile.ACC_STATIC_PHASE), - MANDATED("", Classfile.ACC_MANDATED); + TRANSITIVE("transitive", ClassFile.ACC_TRANSITIVE), + STATIC("static", ClassFile.ACC_STATIC_PHASE), + MANDATED("", ClassFile.ACC_MANDATED); private final String token; private final int mask; @@ -229,7 +229,7 @@ public int getMask() { } public enum ExportsFlag implements Mask { - SYNTHETIC("", Classfile.ACC_SYNTHETIC); + SYNTHETIC("", ClassFile.ACC_SYNTHETIC); private final String token; private final int mask; @@ -246,7 +246,7 @@ public int getMask() { } public enum OpensFlag implements Mask { - SYNTHETIC("", Classfile.ACC_SYNTHETIC); + SYNTHETIC("", ClassFile.ACC_SYNTHETIC); private final String token; private final int mask; diff --git a/test/langtools/tools/javac/classfiles/attributes/Signature/ConstructorTest.java b/test/langtools/tools/javac/classfiles/attributes/Signature/ConstructorTest.java index 384e8973a3d45..ae6b5f740c437 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Signature/ConstructorTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Signature/ConstructorTest.java @@ -26,13 +26,9 @@ * @bug 8049238 * @summary Checks Signature attribute for constructors. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build ConstructorTest Driver ExpectedSignature ExpectedSignatureContainer diff --git a/test/langtools/tools/javac/classfiles/attributes/Signature/Driver.java b/test/langtools/tools/javac/classfiles/attributes/Signature/Driver.java index 30913ad2118b6..4e565cde4239a 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Signature/Driver.java +++ b/test/langtools/tools/javac/classfiles/attributes/Signature/Driver.java @@ -21,8 +21,8 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.SignatureAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.SignatureAttribute; import jdk.internal.classfile.impl.BoundAttribute; import java.io.File; diff --git a/test/langtools/tools/javac/classfiles/attributes/Signature/EnumTest.java b/test/langtools/tools/javac/classfiles/attributes/Signature/EnumTest.java index 554ba11e4ad1e..661b340573539 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Signature/EnumTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Signature/EnumTest.java @@ -26,13 +26,9 @@ * @bug 8049238 * @summary Checks Signature attribute for enum. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build EnumTest Driver ExpectedSignature ExpectedSignatureContainer diff --git a/test/langtools/tools/javac/classfiles/attributes/Signature/ExceptionTest.java b/test/langtools/tools/javac/classfiles/attributes/Signature/ExceptionTest.java index f43a58fd88485..d15efea17dff0 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Signature/ExceptionTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Signature/ExceptionTest.java @@ -26,13 +26,9 @@ * @bug 8049238 * @summary Checks Signature attribute for methods which throw exceptions. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build ExceptionTest Driver ExpectedSignature ExpectedSignatureContainer diff --git a/test/langtools/tools/javac/classfiles/attributes/Signature/FieldTest.java b/test/langtools/tools/javac/classfiles/attributes/Signature/FieldTest.java index be604ff8fc621..e5a7dfa480ea7 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Signature/FieldTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Signature/FieldTest.java @@ -26,13 +26,9 @@ * @bug 8049238 * @summary Checks Signature attribute for fields. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build FieldTest Driver ExpectedSignature ExpectedSignatureContainer diff --git a/test/langtools/tools/javac/classfiles/attributes/Signature/InnerClassTest.java b/test/langtools/tools/javac/classfiles/attributes/Signature/InnerClassTest.java index c0b65f0f213ac..ae3670aca034a 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Signature/InnerClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Signature/InnerClassTest.java @@ -26,13 +26,9 @@ * @bug 8049238 * @summary Checks Signature attribute for inner classes. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassTest Driver ExpectedSignature ExpectedSignatureContainer diff --git a/test/langtools/tools/javac/classfiles/attributes/Signature/MethodParameterTest.java b/test/langtools/tools/javac/classfiles/attributes/Signature/MethodParameterTest.java index f9f644436c333..3444cc14ce7d8 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Signature/MethodParameterTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Signature/MethodParameterTest.java @@ -26,13 +26,9 @@ * @bug 8049238 * @summary Checks Signature attribute for method parameters. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build MethodParameterTest Driver ExpectedSignature ExpectedSignatureContainer diff --git a/test/langtools/tools/javac/classfiles/attributes/Signature/MethodTypeBoundTest.java b/test/langtools/tools/javac/classfiles/attributes/Signature/MethodTypeBoundTest.java index 5cc5155814101..51e668779b608 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Signature/MethodTypeBoundTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Signature/MethodTypeBoundTest.java @@ -26,13 +26,9 @@ * @bug 8049238 * @summary Checks Signature attribute for type bounds. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build MethodTypeBoundTest Driver ExpectedSignature ExpectedSignatureContainer diff --git a/test/langtools/tools/javac/classfiles/attributes/Signature/ReturnTypeTest.java b/test/langtools/tools/javac/classfiles/attributes/Signature/ReturnTypeTest.java index 2855767e72e8e..e805baca82a8e 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Signature/ReturnTypeTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Signature/ReturnTypeTest.java @@ -26,14 +26,10 @@ * @bug 8049238 * @summary Checks Signature attribute for array return type of method. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules java.desktop * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build ReturnTypeTest Driver ExpectedSignature ExpectedSignatureContainer diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/AnonymousClassTest.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/AnonymousClassTest.java index 4aba5356fac5e..63eb7369ff023 100644 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/AnonymousClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/AnonymousClassTest.java @@ -26,13 +26,9 @@ * @summary sourcefile attribute test for anonymous class. * @bug 8040129 * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase * @run main AnonymousClassTest diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/InnerClassTest.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/InnerClassTest.java index 99c3d0be96968..e2442f421d884 100644 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/InnerClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/InnerClassTest.java @@ -26,13 +26,9 @@ * @summary sourcefile attribute test for inner class. * @bug 8040129 * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase * @run main InnerClassTest diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/LocalClassTest.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/LocalClassTest.java index 8a25a4cf6dd4e..a5b44936edea3 100644 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/LocalClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/LocalClassTest.java @@ -26,13 +26,9 @@ * @summary sourcefile attribute test for local class. * @bug 8040129 * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase * @run main LocalClassTest diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/MixTest.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/MixTest.java index 0bc727559108c..1c7aae4ae0ffb 100644 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/MixTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/MixTest.java @@ -26,13 +26,9 @@ * @summary sourcefile attribute test for complex structure of nested classes and other types. * @bug 8040129 * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase * @run main MixTest diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/ModuleInfoTest.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/ModuleInfoTest.java index 8107017fa40b0..886ee032ed29b 100644 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/ModuleInfoTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/ModuleInfoTest.java @@ -26,13 +26,9 @@ * @summary sourcefile attribute test for module-info. * @bug 8080878 * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask InMemoryFileManager TestBase SourceFileTestBase * @run main ModuleInfoTest diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java index ea925c0b7e36d..af9e603c964b6 100644 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/NoSourceFileAttribute.java @@ -26,21 +26,17 @@ * @summary sourcefile attribute test for file compiled without debug information. * @bug 8040129 * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase * @compile -g:none NoSourceFileAttribute.java * @run main NoSourceFileAttribute */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.io.IOException; @@ -52,7 +48,7 @@ public static void main(String[] args) throws Exception { public void test() throws IOException { assertNull( - Classfile.of().parse(getClassFile(NoSourceFileAttribute.class).toPath()).findAttribute(Attributes.SOURCE_FILE).orElse(null), + ClassFile.of().parse(getClassFile(NoSourceFileAttribute.class).toPath()).findAttribute(Attributes.SOURCE_FILE).orElse(null), "Classfile should have no SourceFile attribute when compiled without debug information."); } } diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java index cf9acbee4a104..f827873588ec6 100644 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java @@ -21,8 +21,8 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.SourceFileAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.SourceFileAttribute; import jdk.internal.classfile.impl.BoundAttribute; import java.io.InputStream; @@ -50,7 +50,7 @@ public class SourceFileTestBase extends TestBase { * @param fileName expected name of the file from which the test file is compiled. */ protected void test(Class classToTest, String fileName) throws Exception { - assertAttributePresent(Classfile.of().parse(getClassFile(classToTest).toPath()), fileName); + assertAttributePresent(ClassFile.of().parse(getClassFile(classToTest).toPath()), fileName); } /** @@ -60,7 +60,7 @@ protected void test(Class classToTest, String fileName) throws Exception { * @param fileName expected name of the file from which the test file is compiled. */ protected void test(String classToTest, String fileName) throws Exception { - assertAttributePresent(Classfile.of().parse(getClassFile(classToTest + ".class").toPath()), fileName); + assertAttributePresent(ClassFile.of().parse(getClassFile(classToTest + ".class").toPath()), fileName); } /** @@ -70,7 +70,7 @@ protected void test(String classToTest, String fileName) throws Exception { * @param fileName expected name of the file from which the test file is compiled. */ protected void test(Path classToTest, String fileName) throws Exception { - assertAttributePresent(Classfile.of().parse(classToTest), fileName); + assertAttributePresent(ClassFile.of().parse(classToTest), fileName); } /** @@ -87,7 +87,7 @@ protected void compileAndTest(String sourceCode, String... classesToTest) throws for (String className : classesToTest) { ClassModel classFile; try (InputStream input = classes.get(className).openInputStream()) { - classFile = Classfile.of().parse(input.readAllBytes()); + classFile = ClassFile.of().parse(input.readAllBytes()); } assertAttributePresent(classFile, fileName); } diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase_legacy.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase_legacy.java new file mode 100644 index 0000000000000..b8fdcff4e8869 --- /dev/null +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase_legacy.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.SourceFile_attribute; + +import java.io.InputStream; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.tools.JavaFileObject; + +import toolbox.ToolBox; + +/** + * Base class for Source file attribute tests. Checks expected file name for specified classes in the SourceFile attribute. + * To add new tests you should extend the SourceFileTestBase class and invoke {@link #test} for static sources + * or {@link #compileAndTest} for generated sources. For more information see corresponding methods. + * + * @see #test + * @see #compileAndTest + */ +public class SourceFileTestBase_legacy extends TestBase { + /** + * Checks expected fileName for the specified class in the SourceFile attribute. + * + * @param classToTest class to check its SourceFile attribute + * @param fileName expected name of the file from which the test file is compiled. + */ + protected void test(Class classToTest, String fileName) throws Exception { + assertAttributePresent(ClassFile.read(getClassFile(classToTest)), fileName); + } + + /** + * Checks expected fileName for the specified class in the SourceFile attribute. + * + * @param classToTest class name to check its SourceFile attribute + * @param fileName expected name of the file from which the test file is compiled. + */ + protected void test(String classToTest, String fileName) throws Exception { + assertAttributePresent(ClassFile.read(getClassFile(classToTest + ".class")), fileName); + } + + /** + * Checks expected fileName for the specified class in the SourceFile attribute. + * + * @param classToTest path of class to check its SourceFile attribute + * @param fileName expected name of the file from which the test file is compiled. + */ + protected void test(Path classToTest, String fileName) throws Exception { + assertAttributePresent(ClassFile.read(classToTest), fileName); + } + + /** + * Compiles sourceCode and for each specified class name checks the SourceFile attribute. + * The file name is extracted from source code. + * + * @param sourceCode source code to compile + * @param classesToTest class names to check their SourceFile attribute. + */ + protected void compileAndTest(String sourceCode, String... classesToTest) throws Exception { + + Map classes = compile(sourceCode).getClasses(); + String fileName = ToolBox.getJavaFileNameFromSource(sourceCode); + for (String className : classesToTest) { + ClassFile classFile; + try (InputStream input = classes.get(className).openInputStream()) { + classFile = ClassFile.read(input); + } + assertAttributePresent(classFile, fileName); + } + } + + private void assertAttributePresent(ClassFile classFile, String fileName) throws Exception { + + //We need to count attributes with the same names because there is no appropriate API in the ClassFile. + + List sourceFileAttributes = new ArrayList<>(); + for (Attribute a : classFile.attributes.attrs) { + if (Attribute.SourceFile.equals(a.getName(classFile.constant_pool))) { + sourceFileAttributes.add((SourceFile_attribute) a); + } + } + + assertEquals(sourceFileAttributes.size(), 1, "Should be the only SourceFile attribute"); + + SourceFile_attribute attribute = sourceFileAttributes.get(0); + + assertEquals(classFile.constant_pool.getUTF8Info(attribute.attribute_name_index).value, + Attribute.SourceFile, "Incorrect attribute name"); + assertEquals(classFile.constant_pool.getUTF8Info(attribute.sourcefile_index).value, fileName, + "Incorrect source file name"); + assertEquals(attribute.attribute_length, 2, "Incorrect attribute length"); + } +} diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java index c08fc263da0be..92a6e6b9bae18 100644 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SyntheticClassTest.java @@ -25,16 +25,11 @@ * @test * @summary sourcefile attribute test for synthetic class. * @bug 8040129 - * @library /tools/lib /tools/javac/lib ../lib + * @library /tools/lib /tools/javac/lib ../lib_legacy * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl - * @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase + * jdk.jdeps/com.sun.tools.classfile + * @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase_legacy * @compile -source 10 -target 10 SyntheticClassTest.java * @run main SyntheticClassTest true * @clean SyntheticClassTest$1 @@ -44,7 +39,7 @@ import java.nio.file.NoSuchFileException; -public class SyntheticClassTest extends SourceFileTestBase { +public class SyntheticClassTest extends SourceFileTestBase_legacy { public static void main(String[] args) throws Exception { boolean expectSynthetic = Boolean.parseBoolean(args[0]); new Inner(); diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/TopLevelClassesOneFileTest.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/TopLevelClassesOneFileTest.java index 9b4d543512b08..d29d2ef96008d 100644 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/TopLevelClassesOneFileTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/TopLevelClassesOneFileTest.java @@ -26,13 +26,9 @@ * @summary sourcefile attribute test for two type in one file. * @bug 8040129 * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase SourceFileTestBase * @run main TopLevelClassesOneFileTest diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassConstructorsTest.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassConstructorsTest.java index f6ea96b804856..1c220441d8da4 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassConstructorsTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassConstructorsTest.java @@ -25,13 +25,9 @@ * @test * @bug 8189335 * @summary Synthetic anonymous class used as access constructor tag conflicting with a top level class. + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassMembersTest.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassMembersTest.java index ed440845f0313..3eef2e12ba780 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassMembersTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateInnerClassMembersTest.java @@ -26,13 +26,9 @@ * @bug 8044537 * @summary Checking ACC_SYNTHETIC flag is generated for access method * generated to access to private methods and fields. + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateSiblingsTest.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateSiblingsTest.java index 4e3d0565ea4a7..94f4af3a1e27d 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateSiblingsTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/AccessToPrivateSiblingsTest.java @@ -26,13 +26,9 @@ * @bug 8044537 * @summary Checking ACC_SYNTHETIC flag is generated for access method * generated to access to private methods and fields. + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/AssertFieldTest.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/AssertFieldTest.java index 223d60075dd59..8015177ff1407 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/AssertFieldTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/AssertFieldTest.java @@ -25,13 +25,9 @@ * @test * @bug 8044537 * @summary Checking ACC_SYNTHETIC flag is generated for assert statement. + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodForGenericMethodTest.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodForGenericMethodTest.java index d314c4bf12afa..fedcf817ee345 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodForGenericMethodTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodForGenericMethodTest.java @@ -25,13 +25,9 @@ * @test * @bug 8044537 * @summary Checking ACC_SYNTHETIC flag is generated for bridge method generated for generic method. + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTargetRelease14Test.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTargetRelease14Test.java index 13db7b34663ca..76d5d3c178dda 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTargetRelease14Test.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTargetRelease14Test.java @@ -29,17 +29,12 @@ * compiling with --release 14. * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl - * @library /tools/lib /tools/javac/lib ../lib + * jdk.jdeps/com.sun.tools.classfile + * @library /tools/lib /tools/javac/lib ../lib_legacy * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase - * @build SyntheticTestDriver ExpectedClass ExpectedClasses + * @build SyntheticTestDriver_legacy ExpectedClass ExpectedClasses * @compile --source 14 -target 14 -XDdeduplicateLambdas=false BridgeMethodsForLambdaTargetRelease14Test.java - * @run main SyntheticTestDriver BridgeMethodsForLambdaTargetRelease14Test + * @run main SyntheticTestDriver_legacy BridgeMethodsForLambdaTargetRelease14Test */ import java.util.Comparator; diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTest.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTest.java index c1f632b257666..10d93dd763109 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/BridgeMethodsForLambdaTest.java @@ -26,13 +26,9 @@ * @bug 8044537 8200301 8238358 * @summary Checking ACC_SYNTHETIC flag is generated for bridge method * generated for lambda expressions and method references. + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/EnumTest.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/EnumTest.java index 9f99a45340517..891f09ae083db 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/EnumTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/EnumTest.java @@ -25,13 +25,9 @@ * @test * @bug 8044537 * @summary Checking ACC_SYNTHETIC flag is generated for enum members. + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/PackageInfoTest.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/PackageInfoTest.java index d9f9a8c8f19d2..108a9a1645081 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/PackageInfoTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/PackageInfoTest.java @@ -25,13 +25,9 @@ * @test * @bug 8044537 * @summary Checking ACC_SYNTHETIC flag is generated for package-info. + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/SyntheticTestDriver.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/SyntheticTestDriver.java index bef23b4373b06..406df68a7fe21 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/SyntheticTestDriver.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/SyntheticTestDriver.java @@ -34,8 +34,8 @@ import java.util.stream.Stream; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.SyntheticAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.SyntheticAttribute; /** * The tests work as follows. Firstly, it looks through the test cases diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/SyntheticTestDriver_legacy.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/SyntheticTestDriver_legacy.java new file mode 100644 index 0000000000000..c9e333b0d4e7e --- /dev/null +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/SyntheticTestDriver_legacy.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.regex.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.sun.tools.classfile.*; + +/** + * The tests work as follows. Firstly, it looks through the test cases + * and extracts the appropriate compiled classes. Each test case contains + * a set of expected classes, methods and fields. Those class members must not have + * the Synthetic attribute, while other found classes, methods and fields must have + * the Synthetic attribute if they are not in the set of expected class members. + * + * Each test executes SyntheticTestDriver specifying the name of test cases and + * the number of expected synthetic classes. Each test class is annotated by + * annotations which contains non-synthetic class members. + * + * See the appropriate class for more information about a test case. + */ +public class SyntheticTestDriver_legacy extends TestResult { + + private static final String ACC_SYNTHETIC = "ACC_SYNTHETIC"; + + private final String testCaseName; + private final Map classes; + private final Map expectedClasses; + + public static void main(String[] args) + throws TestFailedException, ConstantPoolException, IOException, ClassNotFoundException { + if (args.length != 1 && args.length != 2) { + throw new IllegalArgumentException("Usage: SyntheticTestDriver []"); + } + int numberOfSyntheticClasses = args.length == 1 ? 0 : Integer.parseInt(args[1]); + new SyntheticTestDriver_legacy(args[0]).test(numberOfSyntheticClasses); + } + + public SyntheticTestDriver_legacy(String testCaseName) throws IOException, ConstantPoolException, ClassNotFoundException { + Class clazz = Class.forName(testCaseName); + this.testCaseName = testCaseName; + this.expectedClasses = Stream.of(clazz.getAnnotationsByType(ExpectedClass.class)) + .collect(Collectors.toMap(ExpectedClass::className, Function.identity())); + this.classes = new HashMap<>(); + Path classDir = getClassDir().toPath(); + Pattern filePattern = Pattern.compile(Pattern.quote(testCaseName.replace('.', File.separatorChar)) + ".*\\.class"); + List paths = Files.walk(classDir) + .map(p -> classDir.relativize(p.toAbsolutePath())) + .filter(p -> filePattern.matcher(p.toString()).matches()) + .collect(Collectors.toList()); + for (Path path : paths) { + String className = path.toString().replace(".class", "").replace(File.separatorChar, '.'); + classes.put(className, readClassFile(classDir.resolve(path).toFile())); + } + if (classes.isEmpty()) { + throw new RuntimeException("Classes have not been found."); + } + boolean success = classes.entrySet().stream() + .allMatch(e -> e.getKey().startsWith(testCaseName)); + if (!success) { + classes.forEach((className, $) -> printf("Found class: %s\n", className)); + throw new RuntimeException("Found classes are not from the test case : " + testCaseName); + } + } + + private String getMethodName(ClassFile classFile, Method method) + throws ConstantPoolException, Descriptor.InvalidDescriptor { + String methodName = method.getName(classFile.constant_pool); + String parameters = method.descriptor.getParameterTypes(classFile.constant_pool); + return methodName + parameters; + } + + public void test(int expectedNumberOfSyntheticClasses) throws TestFailedException { + try { + addTestCase(testCaseName); + Set foundClasses = new HashSet<>(); + + int numberOfSyntheticClasses = 0; + for (Map.Entry entry : classes.entrySet()) { + String className = entry.getKey(); + ClassFile classFile = entry.getValue(); + foundClasses.add(className); + if (testAttribute( + classFile, + () -> (Synthetic_attribute) classFile.getAttribute(Attribute.Synthetic), + classFile.access_flags::getClassFlags, + expectedClasses.keySet(), + className, + "Testing class " + className)) { + ++numberOfSyntheticClasses; + } + ExpectedClass expectedClass = expectedClasses.get(className); + Set expectedMethods = expectedClass != null + ? toSet(expectedClass.expectedMethods()) + : new HashSet<>(); + int numberOfSyntheticMethods = 0; + Set foundMethods = new HashSet<>(); + for (Method method : classFile.methods) { + String methodName = getMethodName(classFile, method); + foundMethods.add(methodName); + if (testAttribute( + classFile, + () -> (Synthetic_attribute) method.attributes.get(Attribute.Synthetic), + method.access_flags::getMethodFlags, + expectedMethods, + methodName, + "Testing method " + methodName + " in class " + + className)) { + ++numberOfSyntheticMethods; + } + } + checkContains(foundMethods, expectedMethods, + "Checking that all methods of class " + className + + " without Synthetic attribute have been found"); + checkEquals(numberOfSyntheticMethods, + expectedClass == null ? 0 : expectedClass.expectedNumberOfSyntheticMethods(), + "Checking number of synthetic methods in class: " + className); + + Set expectedFields = expectedClass != null + ? toSet(expectedClass.expectedFields()) + : new HashSet<>(); + int numberOfSyntheticFields = 0; + Set foundFields = new HashSet<>(); + for (Field field : classFile.fields) { + String fieldName = field.getName(classFile.constant_pool); + foundFields.add(fieldName); + if (testAttribute( + classFile, + () -> (Synthetic_attribute) field.attributes.get(Attribute.Synthetic), + field.access_flags::getFieldFlags, + expectedFields, + fieldName, + "Testing field " + fieldName + " in class " + + className)) { + ++numberOfSyntheticFields; + } + } + checkContains(foundFields, expectedFields, + "Checking that all fields of class " + className + + " without Synthetic attribute have been found"); + checkEquals(numberOfSyntheticFields, + expectedClass == null ? 0 : expectedClass.expectedNumberOfSyntheticFields(), + "Checking number of synthetic fields in class: " + className); + } + checkContains(foundClasses, expectedClasses.keySet(), + "Checking that all classes have been found"); + checkEquals(numberOfSyntheticClasses, expectedNumberOfSyntheticClasses, + "Checking number of synthetic classes"); + } catch (Exception e) { + addFailure(e); + } finally { + checkStatus(); + } + } + + private boolean testAttribute(ClassFile classFile, + Supplier getSyntheticAttribute, + Supplier> getAccessFlags, + Set expectedMembers, String memberName, + String info) throws ConstantPoolException { + echo(info); + String className = classFile.getName(); + Synthetic_attribute attr = getSyntheticAttribute.get(); + Set flags = getAccessFlags.get(); + if (expectedMembers.contains(memberName)) { + checkNull(attr, "Member must not have synthetic attribute : " + + memberName); + checkFalse(flags.contains(ACC_SYNTHETIC), + "Member must not have synthetic flag : " + memberName + + " in class : " + className); + return false; + } else { + return checkNull(attr, "Synthetic attribute should not be generated") + && checkTrue(flags.contains(ACC_SYNTHETIC), "Member must have synthetic flag : " + + memberName + " in class : " + className); + } + } + + private Set toSet(String[] strings) { + HashSet set = new HashSet<>(); + Collections.addAll(set, strings); + return set; + } +} diff --git a/test/langtools/tools/javac/classfiles/attributes/Synthetic/ThisFieldTest.java b/test/langtools/tools/javac/classfiles/attributes/Synthetic/ThisFieldTest.java index c32075207d5cf..ed87191d9c0e1 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Synthetic/ThisFieldTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/Synthetic/ThisFieldTest.java @@ -25,13 +25,9 @@ * @test * @bug 8044537 * @summary Checking ACC_SYNTHETIC flag is generated for "this$0" field. + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @library /tools/lib /tools/javac/lib ../lib * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/AnnotationsTestBase.java b/test/langtools/tools/javac/classfiles/attributes/annotations/AnnotationsTestBase.java index 25c804bd011ea..fb1f8839e286d 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/AnnotationsTestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/AnnotationsTestBase.java @@ -21,7 +21,7 @@ * questions. */ -import jdk.internal.classfile.Attribute; +import java.lang.classfile.Attribute; import javax.tools.JavaFileObject; import java.io.IOException; diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForGenericMethodTest.java b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForGenericMethodTest.java index 4aafea1b40b06..04bf7820b12fc 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForGenericMethodTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForGenericMethodTest.java @@ -26,12 +26,8 @@ * @bug 8044411 * @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations attribute. * Checks that the attribute is generated for bridge method. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * @library /tools/lib /tools/javac/lib ../lib diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerAnnotationTest.java b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerAnnotationTest.java index f0e65c2babf55..ac8069b2a76a5 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerAnnotationTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerAnnotationTest.java @@ -25,12 +25,8 @@ * @test * @bug 8044411 * @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations attribute. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * @library /tools/lib /tools/javac/lib ../lib diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerClassTest.java b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerClassTest.java index 139193446e4d1..2ad55bea369cf 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerClassTest.java @@ -25,12 +25,8 @@ * @test * @bug 8044411 * @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations attribute. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * @library /tools/lib /tools/javac/lib ../lib diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerEnumTest.java b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerEnumTest.java index 87070329ebdbb..c4ee74e8ee342 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerEnumTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerEnumTest.java @@ -25,12 +25,8 @@ * @test * @bug 8044411 * @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations attribute. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * @library /tools/lib /tools/javac/lib ../lib diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerInterfaceTest.java b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerInterfaceTest.java index ae11817cabc06..5d3bcc519ff8d 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerInterfaceTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForInnerInterfaceTest.java @@ -25,12 +25,8 @@ * @test * @bug 8044411 * @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations attribute. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * @library /tools/lib /tools/javac/lib ../lib diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForTopLevelClassTest.java b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForTopLevelClassTest.java index 55414c261c84f..948b8abfcecaf 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForTopLevelClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsForTopLevelClassTest.java @@ -25,12 +25,8 @@ * @test * @bug 8044411 * @summary Tests the RuntimeVisibleAnnotations/RuntimeInvisibleAnnotations attribute. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * @library /tools/lib /tools/javac/lib ../lib diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsTestBase.java b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsTestBase.java index af5ac818855bc..a36a84e5e8f9e 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsTestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeAnnotationsTestBase.java @@ -21,8 +21,8 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.io.IOException; import java.lang.annotation.RetentionPolicy; diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsForGenericMethodTest.java b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsForGenericMethodTest.java index e2b1a82d1b03f..2846325dd4a88 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsForGenericMethodTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsForGenericMethodTest.java @@ -26,12 +26,8 @@ * @bug 8044411 * @summary Tests the RuntimeParameterVisibleAnnotations/RuntimeParameterInvisibleAnnotations attribute. * Checks that the attribute is generated for bridge method. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * @library /tools/lib /tools/javac/lib ../lib diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsForLambdaTest.java b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsForLambdaTest.java index 26ee86a730cb6..baf3a599095d2 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsForLambdaTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsForLambdaTest.java @@ -25,12 +25,8 @@ * @test * @bug 8044411 8079060 8138612 * @summary Tests the RuntimeParameterVisibleAnnotations/RuntimeParameterInvisibleAnnotations attribute. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * @library /tools/lib /tools/javac/lib ../lib @@ -40,11 +36,11 @@ * @run main RuntimeParameterAnnotationsForLambdaTest */ -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.MethodModel; -import jdk.internal.classfile.attribute.RuntimeInvisibleParameterAnnotationsAttribute; -import jdk.internal.classfile.attribute.RuntimeVisibleParameterAnnotationsAttribute; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassModel; +import java.lang.classfile.MethodModel; +import java.lang.classfile.attribute.RuntimeInvisibleParameterAnnotationsAttribute; +import java.lang.classfile.attribute.RuntimeVisibleParameterAnnotationsAttribute; import java.util.List; import java.util.stream.Collectors; diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsTest.java b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsTest.java index e7c878ce7cbf6..a62c3a1d98917 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsTest.java @@ -25,12 +25,8 @@ * @test * @bug 8044411 * @summary Tests the RuntimeParameterVisibleAnnotations/RuntimeParameterInvisibleAnnotations attribute. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * @library /tools/lib /tools/javac/lib ../lib diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsTestBase.java b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsTestBase.java index 286e64ff5be48..04b1ba2dd54dc 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsTestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/RuntimeParameterAnnotationsTestBase.java @@ -21,8 +21,8 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import javax.tools.JavaFileObject; import java.io.IOException; diff --git a/test/langtools/tools/javac/classfiles/attributes/annotations/TestAnnotationInfo.java b/test/langtools/tools/javac/classfiles/attributes/annotations/TestAnnotationInfo.java index 46811a11c0f1d..5bf587d1b8b4c 100644 --- a/test/langtools/tools/javac/classfiles/attributes/annotations/TestAnnotationInfo.java +++ b/test/langtools/tools/javac/classfiles/attributes/annotations/TestAnnotationInfo.java @@ -21,8 +21,8 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.AnnotationValue; +import java.lang.classfile.*; +import java.lang.classfile.AnnotationValue; import java.lang.annotation.RetentionPolicy; import java.util.*; diff --git a/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java b/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java index b0482fe5a8939..8befbb143dad5 100644 --- a/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java @@ -26,22 +26,18 @@ * @bug 8042261 * @summary Checking that deprecated attribute does not apply to classes of deprecated package. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @run main DeprecatedPackageTest */ -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.attribute.DeprecatedAttribute; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassModel; +import java.lang.classfile.attribute.DeprecatedAttribute; public class DeprecatedPackageTest extends TestResult { diff --git a/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java b/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java index 82dc95f936641..607448dc5db14 100644 --- a/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java @@ -27,21 +27,17 @@ * @summary Checking what attribute is generated by annotation Deprecated * or javadoc deprecated for field, method, class(inner/local), interface. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @run main DeprecatedTest */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import jdk.internal.classfile.impl.BoundAttribute; import javax.tools.JavaFileObject; diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerAnnotationTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerAnnotationTest.java index 4f6c7da47306f..a07a111f024ed 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerAnnotationTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerAnnotationTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner annotations in inner annotation. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerClassTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerClassTest.java index a6787faf86052..f02da8d302a64 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerClassTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner annotations in inner class. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerEnumTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerEnumTest.java index 4b34834558a00..06ccbdf07252e 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerEnumTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerEnumTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner annotations in inner enum. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerInterfaceTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerInterfaceTest.java index baae4e0752a49..7fd6c7bd2590d 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerInterfaceTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerAnnotationsInInnerInterfaceTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner annotations in inner interface. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesHierarchyTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesHierarchyTest.java index 33c6017171213..eb7e6f2e2df58 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesHierarchyTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesHierarchyTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Test that inner classes have in its inner classes attribute enclosing classes and its immediate members. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @run main InnerClassesHierarchyTest @@ -45,9 +41,9 @@ import java.util.*; import java.util.stream.Collectors; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.*; public class InnerClassesHierarchyTest extends TestResult { diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInAnonymousClassTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInAnonymousClassTest.java index 970195f32bdac..45554408974de 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInAnonymousClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInAnonymousClassTest.java @@ -26,13 +26,9 @@ * @bug 8042251 8062373 * @summary Testing InnerClasses_attribute of inner classes in anonymous class. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerAnnotationTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerAnnotationTest.java index ab193de085f43..9b7be560ed4da 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerAnnotationTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerAnnotationTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner classes in inner annotation. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerClassTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerClassTest.java index 91fed895d0772..df638c9cd9106 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerClassTest.java @@ -26,13 +26,9 @@ * @bug 8034854 8042251 * @summary Testing InnerClasses_attribute of inner classes in inner class. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerEnumTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerEnumTest.java index bf0d4c653f60d..9ff973177ab34 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerEnumTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerEnumTest.java @@ -26,13 +26,9 @@ * @bug 8034854 8042251 * @summary Testing InnerClasses_attribute of inner classes in inner enum. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerInterfaceTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerInterfaceTest.java index 651c3f41c0203..722c1f4951abb 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerInterfaceTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInInnerInterfaceTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner classes in inner interface. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInLocalClassTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInLocalClassTest.java index 97ad838793611..bf5488f60b5c3 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInLocalClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesInLocalClassTest.java @@ -26,12 +26,8 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner classes in local class. * @library /tools/lib /tools/javac/lib ../lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesIndexTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesIndexTest.java index 241a6422c40fe..826365a8011a0 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesIndexTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesIndexTest.java @@ -26,21 +26,17 @@ * @bug 8042251 * @summary Test that outer_class_info_index of local and anonymous class is zero. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @run main InnerClassesIndexTest */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.ClassEntry; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.ClassEntry; import java.io.File; import java.io.FilenameFilter; import java.util.Arrays; diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTest.java index db293fddde6ee..f2901d4c9cbec 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTest.java @@ -26,13 +26,9 @@ * @bug 8034854 8042251 * @summary Testing inner classes attributes. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java index cf36ed9cca5b9..ca818817b6d69 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java @@ -21,9 +21,9 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.*; import jdk.internal.classfile.impl.BoundAttribute; import java.nio.file.Paths; diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerAnnotationTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerAnnotationTest.java index dbafcbfa45cd1..41d9627b278f1 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerAnnotationTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerAnnotationTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner enums in inner annotation. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerEnumTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerEnumTest.java index f37c21dc85fec..3136cce327d59 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerEnumTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerEnumTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner enums in inner enum. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerInterfaceTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerInterfaceTest.java index 7286dc61b7c3e..59d86c3f65af0 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerInterfaceTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumInInnerInterfaceTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner enums in inner interface. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumsInInnerClassTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumsInInnerClassTest.java index d6bebd285ede8..aeee14b8e90a7 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumsInInnerClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerEnumsInInnerClassTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner enums in inner class. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerAnnotationTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerAnnotationTest.java index b9a65195802ab..57f48bd6d3cc7 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerAnnotationTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerAnnotationTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner interfaces in inner annotation. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerClassTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerClassTest.java index cb14d1c3f215f..522d607760249 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerClassTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerClassTest.java @@ -26,13 +26,9 @@ * @summary Testing InnerClasses_attribute of inner interfaces in inner class. * @author aeremeev * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerEnumTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerEnumTest.java index a84240c00f6dd..53136291cfaa5 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerEnumTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerEnumTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner interfaces in inner enum. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerInterfaceTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerInterfaceTest.java index b7b5ceb0fe08d..6f3ea9da4ed5f 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerInterfaceTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerInterfacesInInnerInterfaceTest.java @@ -26,13 +26,9 @@ * @bug 8042251 * @summary Testing InnerClasses_attribute of inner interfaces in inner interface. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestResult TestBase * @build InnerClassesInInnerClassTestBase InnerClassesTestBase diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/NoInnerClassesTest.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/NoInnerClassesTest.java index 576b3872430a3..540bd09a18f49 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/NoInnerClassesTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/NoInnerClassesTest.java @@ -26,20 +26,16 @@ * @bug 8042251 * @summary Test that there are no inner classes attributes in case of there are no inner classes. * @library /tools/lib /tools/javac/lib ../lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox InMemoryFileManager TestBase * @run main NoInnerClassesTest */ -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.ClassModel; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassModel; import java.io.IOException; diff --git a/test/langtools/tools/javac/classfiles/attributes/lib/TestBase.java b/test/langtools/tools/javac/classfiles/attributes/lib/TestBase.java index 15364cafeb86d..4ae217b5fe30a 100644 --- a/test/langtools/tools/javac/classfiles/attributes/lib/TestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/lib/TestBase.java @@ -33,7 +33,7 @@ import javax.tools.JavaFileObject; import javax.tools.ToolProvider; -import jdk.internal.classfile.*; +import java.lang.classfile.*; import toolbox.JavacTask; import toolbox.ToolBox; @@ -128,7 +128,7 @@ public InMemoryFileManager compile(List options, String[]... sources) * @throws IOException if I/O error occurs */ public ClassModel readClassFile(InputStream is) throws IOException { - return Classfile.of().parse(is.readAllBytes()); + return ClassFile.of().parse(is.readAllBytes()); } /** diff --git a/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestBase.java b/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestBase.java new file mode 100644 index 0000000000000..08de973cc3f05 --- /dev/null +++ b/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestBase.java @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +import javax.tools.DiagnosticCollector; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.ToolProvider; + +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPoolException; + +import toolbox.JavacTask; +import toolbox.ToolBox; + +/** + * Base class for class file attribute tests. + * Contains methods for compiling generated sources in memory, + * for reading files from disk and a lot of assert* methods. + */ +public class TestBase { + + public static final String LINE_SEPARATOR = System.lineSeparator(); + public static final boolean isDumpOfSourceEnabled = Boolean.getBoolean("dump.src"); + + private InMemoryFileManager compile( + List options, + Function src2JavaFileObject, + List sources) + throws IOException, CompilationException { + + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + List src = sources.stream() + .map(src2JavaFileObject) + .collect(Collectors.toList()); + + DiagnosticCollector dc = new DiagnosticCollector<>(); + try (InMemoryFileManager fileManager + = new InMemoryFileManager(compiler.getStandardFileManager(null, null, null))) { + JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, dc, options, null, src); + boolean success = task.call(); + if (!success) { + String errorMessage = dc.getDiagnostics().stream() + .map(Object::toString) + .collect(Collectors.joining("\n")); + throw new CompilationException("Compilation Error\n\n" + errorMessage); + } + return fileManager; + } + } + + /** + * Compiles sources in memory. + * + * @param sources to compile + * @return in-memory file manager which contains class files and class loader + */ + public InMemoryFileManager compile(String... sources) + throws IOException, CompilationException { + return compile(Collections.emptyList(), sources); + } + + /** + * Compiles sources in memory. + * + * @param options compiler options. + * @param sources sources to compile. + * @return in-memory file manager which contains class files and class loader. + */ + public InMemoryFileManager compile(List options, String... sources) + throws IOException, CompilationException { + return compile(options, ToolBox.JavaSource::new, Arrays.asList(sources)); + } + + /** + * Compiles sources in memory. + * + * @param sources sources[i][0] - name of file, sources[i][1] - sources. + * @return in-memory file manager which contains class files and class loader. + */ + public InMemoryFileManager compile(String[]... sources) throws IOException, + CompilationException { + return compile(Collections.emptyList(), sources); + } + + /** + * Compiles sources in memory. + * + * @param options compiler options + * @param sources sources[i][0] - name of file, sources[i][1] - sources. + * @return in-memory file manager which contains class files and class loader. + */ + public InMemoryFileManager compile(List options, String[]... sources) + throws IOException, CompilationException { + return compile(options, src -> new ToolBox.JavaSource(src[0], src[1]), Arrays.asList(sources)); + } + + /** + * Returns class file that is read from {@code is}. + * + * @param is an input stream + * @return class file that is read from {@code is} + * @throws IOException if I/O error occurs + * @throws ConstantPoolException if constant pool error occurs + */ + public ClassFile readClassFile(InputStream is) throws IOException, ConstantPoolException { + return ClassFile.read(is); + } + + /** + * Returns class file that is read from {@code fileObject}. + * + * @param fileObject a file object + * @return class file that is read from {@code fileObject} + * @throws IOException if I/O error occurs + * @throws ConstantPoolException if constant pool error occurs + */ + public ClassFile readClassFile(JavaFileObject fileObject) throws IOException, ConstantPoolException { + try (InputStream is = fileObject.openInputStream()) { + return readClassFile(is); + } + } + + /** + * Returns class file that corresponds to {@code clazz}. + * + * @param clazz a class + * @return class file that is read from {@code clazz} + * @throws IOException if I/O error occurs + * @throws ConstantPoolException if constant pool error occurs + */ + public ClassFile readClassFile(Class clazz) throws IOException, ConstantPoolException { + return readClassFile(getClassFile(clazz)); + } + + /** + * Returns class file that corresponds to {@code className}. + * + * @param className a class name + * @return class file that is read from {@code className} + * @throws IOException if I/O error occurs + * @throws ConstantPoolException if constant pool error occurs + */ + public ClassFile readClassFile(String className) throws IOException, ConstantPoolException { + return readClassFile(getClassFile(className + ".class")); + } + + /** + * Returns class file that is read from {@code file}. + * + * @param file a file + * @return class file that is read from {@code file} + * @throws IOException if I/O error occurs + * @throws ConstantPoolException if constant pool error occurs + */ + public ClassFile readClassFile(File file) throws IOException, ConstantPoolException { + try (InputStream is = new FileInputStream(file)) { + return readClassFile(is); + } + } + + public void assertEquals(Object actual, Object expected, String message) { + if (!Objects.equals(actual, expected)) + throw new AssertionFailedException(String.format("%s%nGot: %s, Expected: %s", + message, actual, expected)); + } + + public void assertNull(Object actual, String message) { + assertEquals(actual, null, message); + } + + public void assertNotNull(Object actual, String message) { + if (Objects.isNull(actual)) { + throw new AssertionFailedException(message + " : Expected not null value"); + } + } + + public void assertTrue(boolean actual, String message) { + assertEquals(actual, true, message); + } + + public void assertFalse(boolean actual, String message) { + assertEquals(actual, false, message); + } + + public void assertContains(Set found, Set expected, String message) { + Set copy = new HashSet<>(expected); + copy.removeAll(found); + assertTrue(found.containsAll(expected), message + " : " + copy); + } + + public void writeToFile(Path path, String source) throws IOException { + try (BufferedWriter writer = Files.newBufferedWriter(path)) { + writer.write(source); + } + } + + public void writeToFileIfEnabled(Path path, String source) throws IOException { + if (isDumpOfSourceEnabled) { + writeToFile(path, source); + } else { + System.err.println("Source dumping disabled. To enable, run the test with '-Ddump.src=true'"); + } + } + + public File getSourceDir() { + return new File(System.getProperty("test.src", ".")); + } + + public File getClassDir() { + return new File(System.getProperty("test.classes", TestBase.class.getResource(".").getPath())); + } + + public File getSourceFile(String fileName) { + return new File(getSourceDir(), fileName); + } + + public File getClassFile(String fileName) { + return new File(getClassDir(), fileName); + } + + public File getClassFile(Class clazz) { + return getClassFile(clazz.getName().replace(".", "/") + ".class"); + } + + /** + * Prints message to standard error. New lines are converted to system dependent NL. + * + * @param message string to print. + */ + public void echo(String message) { + printf(message + "\n"); + } + + /** + * Substitutes args in template and prints result to standard error. + * New lines are converted to system dependent NL. + * + * @param template template in standard String.format(...) format. + * @param args arguments to substitute in template. + */ + public void printf(String template, Object... args) { + System.err.printf(String.format(template, args).replace("\n", LINE_SEPARATOR)); + } + + public static class CompilationException extends Exception { + + public CompilationException(String message) { + super(message); + } + } + + public static class AssertionFailedException extends RuntimeException { + public AssertionFailedException(String message) { + super(message); + } + } +} diff --git a/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestResult.java b/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestResult.java new file mode 100644 index 0000000000000..4c9662f110ff2 --- /dev/null +++ b/test/langtools/tools/javac/classfiles/attributes/lib_legacy/TestResult.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.*; + +/** + * This class accumulates test results. Test results can be checked with method {@code checkStatus}. + */ +public class TestResult extends TestBase { + + private final List testCasesInfo; + + public TestResult() { + testCasesInfo = new ArrayList<>(); + } + + /** + * Adds new test case info. + * + * @param info the information about test case + */ + public void addTestCase(String info) { + System.err.println("Test case: " + info); + testCasesInfo.add(new Info(info)); + } + + public boolean checkEquals(Object actual, Object expected, String message) { + echo("Testing : " + message); + if (!Objects.equals(actual, expected)) { + getLastTestCase().addAssert(String.format("%s\n" + + "Expected: %s,\n" + + " Got: %s", message, expected, actual)); + return false; + } + return true; + } + + public boolean checkNull(Object actual, String message) { + return checkEquals(actual, null, message); + } + + public boolean checkNotNull(Object actual, String message) { + echo("Testing : " + message); + if (Objects.isNull(actual)) { + getLastTestCase().addAssert(message + " : Expected not null value"); + return false; + } + return true; + } + + public boolean checkFalse(boolean actual, String message) { + return checkEquals(actual, false, message); + } + + public boolean checkTrue(boolean actual, String message) { + return checkEquals(actual, true, message); + } + + public boolean checkContains(Collection found, Collection expected, String message) { + Set copy = new HashSet<>(expected); + copy.removeAll(found); + if (!found.containsAll(expected)) { + return checkTrue(false, message + " FAIL : not found elements : " + copy + "\n" + + "Actual: " + found); + } else { + return checkTrue(true, message + " PASS : all elements found"); + } + } + + public void addFailure(Throwable th) { + if (testCasesInfo.isEmpty()) { + testCasesInfo.add(new Info("Dummy info")); + } + getLastTestCase().addFailure(th); + } + + private Info getLastTestCase() { + if (testCasesInfo.isEmpty()) { + throw new IllegalStateException("Test case should be created"); + } + return testCasesInfo.get(testCasesInfo.size() - 1); + } + + /** + * Throws {@code TestFailedException} if one of the checks are failed + * or an exception occurs. Prints error message of failed test cases. + * + * @throws TestFailedException if one of the checks are failed + * or an exception occurs + */ + public void checkStatus() throws TestFailedException { + int passed = 0; + int failed = 0; + for (Info testCaseInfo : testCasesInfo) { + if (testCaseInfo.isFailed()) { + String info = testCaseInfo.info().replace("\n", LINE_SEPARATOR); + String errorMessage = testCaseInfo.getMessage().replace("\n", LINE_SEPARATOR); + System.err.printf("Failure in test case:%n%s%n%s%n", info, errorMessage); + ++failed; + } else { + ++passed; + } + } + System.err.printf("Test cases: passed: %d, failed: %d, total: %d.%n", passed, failed, passed + failed); + if (failed > 0) { + throw new TestFailedException("Test failed"); + } + if (passed + failed == 0) { + throw new TestFailedException("Test cases were not found"); + } + } + + @Override + public void printf(String template, Object... args) { + getLastTestCase().printf(template, args); + } + + private static class Info { + + private final String info; + private final StringWriter writer; + private boolean isFailed; + + private Info(String info) { + this.info = info; + writer = new StringWriter(); + } + + public String info() { + return info; + } + + public boolean isFailed() { + return isFailed; + } + + public void printf(String template, Object... args) { + writer.write(String.format(template, args)); + } + + public void addFailure(Throwable th) { + isFailed = true; + printf("[ERROR] : %s\n", getStackTrace(th)); + } + + public void addAssert(String e) { + isFailed = true; + printf("[ASSERT] : %s\n", e); + } + + public String getMessage() { + return writer.toString(); + } + + public String getStackTrace(Throwable throwable) { + StringWriter stringWriter = new StringWriter(); + try (PrintWriter printWriter = new PrintWriter(stringWriter)) { + throwable.printStackTrace(printWriter); + } + return stringWriter.toString(); + } + } + + public static class TestFailedException extends Exception { + public TestFailedException(String message) { + super(message); + } + } +} diff --git a/test/langtools/tools/javac/classreader/8171132/BadConstantValue.java b/test/langtools/tools/javac/classreader/8171132/BadConstantValue.java index 9fbe9ef49900e..b4230c461c1a4 100644 --- a/test/langtools/tools/javac/classreader/8171132/BadConstantValue.java +++ b/test/langtools/tools/javac/classreader/8171132/BadConstantValue.java @@ -25,12 +25,8 @@ * @test * @bug 8171132 * @summary Improve class reading of invalid or out-of-range ConstantValue attributes - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.jvm @@ -40,7 +36,7 @@ * @run main BadConstantValue */ -import jdk.internal.classfile.*; +import java.lang.classfile.*; import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.code.ClassFinder.BadClassFile; import com.sun.tools.javac.code.Symtab; @@ -185,11 +181,11 @@ private static BadClassFile loadBadClass(String className) { * B's type and A's ConstantValue attribute. */ private static void swapConstantValues(File file) throws Exception { - ClassModel cf = Classfile.of().parse(file.toPath()); + ClassModel cf = ClassFile.of().parse(file.toPath()); FieldModel a = cf.fields().getFirst(); FieldModel b = cf.fields().get(1); - byte[] Bytes = Classfile.of().transform(cf, ClassTransform - .dropping(ce -> ce instanceof ClassfileVersion || ce instanceof FieldModel) + byte[] Bytes = ClassFile.of().transform(cf, ClassTransform + .dropping(ce -> ce instanceof ClassFileVersion || ce instanceof FieldModel) .andThen(ClassTransform.endHandler(classBuilder -> classBuilder .withField(b.fieldName(), b.fieldType(), fieldBuilder -> { fieldBuilder.withFlags(b.flags().flagsMask()); diff --git a/test/langtools/tools/javac/classwriter/IndyCorrectInvocationName.java b/test/langtools/tools/javac/classwriter/IndyCorrectInvocationName.java index db1c9fd649ec1..8711118b8fd4c 100644 --- a/test/langtools/tools/javac/classwriter/IndyCorrectInvocationName.java +++ b/test/langtools/tools/javac/classwriter/IndyCorrectInvocationName.java @@ -27,6 +27,7 @@ * @summary Verify the correct constantpool entries are created for invokedynamic instructions using * the same bootstrap and type, but different name. * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.comp @@ -34,11 +35,6 @@ * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.tree * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * jdk.jdeps/com.sun.tools.javap * @build toolbox.JarTask toolbox.JavacTask toolbox.JavapTask toolbox.ToolBox @@ -59,10 +55,10 @@ import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskListener; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.*; -import jdk.internal.classfile.instruction.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.*; +import java.lang.classfile.instruction.*; import com.sun.tools.javac.api.BasicJavacTask; import com.sun.tools.javac.code.Symbol; @@ -168,7 +164,7 @@ public static CallSite bootstrap(Lookup lookup, String name, MethodType type) th } Path testClass = classes.resolve("Test.class"); - ClassModel cf = Classfile.of().parse(testClass); + ClassModel cf = ClassFile.of().parse(testClass); BootstrapMethodsAttribute bootAttr = cf.findAttribute(Attributes.BOOTSTRAP_METHODS).orElseThrow(); if (bootAttr.bootstrapMethodsSize() != 1) { throw new AssertionError("Incorrect number of bootstrap methods: " + diff --git a/test/langtools/tools/javac/code/CharImmediateValue.java b/test/langtools/tools/javac/code/CharImmediateValue.java index 891883f77b4fa..24f60c5d53920 100644 --- a/test/langtools/tools/javac/code/CharImmediateValue.java +++ b/test/langtools/tools/javac/code/CharImmediateValue.java @@ -27,6 +27,7 @@ * @summary Verify constant/immediate char values are correctly enhanced to ints when used in unary * operators * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.comp @@ -34,11 +35,6 @@ * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.tree * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * jdk.jdeps/com.sun.tools.javap * @build toolbox.JarTask toolbox.JavacTask toolbox.JavapTask toolbox.ToolBox @@ -58,8 +54,8 @@ import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskListener; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCIdent; @@ -136,7 +132,7 @@ public static String run() { } Path testClass = classes.resolve("Test.class"); - ClassModel cf = Classfile.of().parse(testClass); + ClassModel cf = ClassFile.of().parse(testClass); CodeAttribute codeAttr = cf.methods().get(1).findAttribute(Attributes.CODE).orElseThrow(); boolean seenCast = false; for (CodeElement i : codeAttr.elementList()) { diff --git a/test/langtools/tools/javac/constDebug/ConstDebugTest.java b/test/langtools/tools/javac/constDebug/ConstDebugTest.java index 4920d305b0f65..59a6e4daa24d8 100644 --- a/test/langtools/tools/javac/constDebug/ConstDebugTest.java +++ b/test/langtools/tools/javac/constDebug/ConstDebugTest.java @@ -25,23 +25,19 @@ * @test * @bug 4645152 4785453 * @summary javac compiler incorrectly inserts when -g is specified - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @run compile -g ConstDebugTest.java * @run main ConstDebugTest */ import java.nio.file.Paths; -import jdk.internal.classfile.*; +import java.lang.classfile.*; public class ConstDebugTest { public static final long l = 12; public static void main(String args[]) throws Exception { - ClassModel classModel = Classfile.of().parse(Paths.get(System.getProperty("test.classes"), + ClassModel classModel = ClassFile.of().parse(Paths.get(System.getProperty("test.classes"), ConstDebugTest.class.getSimpleName() + ".class")); for (MethodModel method: classModel.methods()) { if (method.methodName().equalsString("")) { diff --git a/test/langtools/tools/javac/defaultMethods/BadClassfile.java b/test/langtools/tools/javac/defaultMethods/BadClassfile.java index bdfdbf9647ac9..366692f17e3c4 100644 --- a/test/langtools/tools/javac/defaultMethods/BadClassfile.java +++ b/test/langtools/tools/javac/defaultMethods/BadClassfile.java @@ -26,12 +26,8 @@ * @bug 8025087 * @summary Verify that pre-JDK8 classfiles with default and/or static methods * are refused correctly. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.comp @@ -42,7 +38,7 @@ * @run main BadClassfile */ -import jdk.internal.classfile.*; +import java.lang.classfile.*; import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.code.ClassFinder.BadClassFile; import com.sun.tools.javac.code.Symbol; @@ -64,8 +60,8 @@ public static void main(String... args) throws Exception { private static void test(String classname, String expected) throws Exception { File classfile = new File(System.getProperty("test.classes", "."), classname + ".class"); - ClassModel cf = Classfile.of().parse(classfile.toPath()); - Classfile.of().transform(cf, ClassTransform.dropping(ce -> ce instanceof ClassfileVersion) + ClassModel cf = ClassFile.of().parse(classfile.toPath()); + ClassFile.of().transform(cf, ClassTransform.dropping(ce -> ce instanceof ClassFileVersion) .andThen(ClassTransform.endHandler(classBuilder -> classBuilder.withVersion(Target.JDK1_7.majorVersion, Target.JDK1_7.minorVersion)))); JavaCompiler c = ToolProvider.getSystemJavaCompiler(); JavacTaskImpl task = (JavacTaskImpl) c.getTask(null, null, null, Arrays.asList("-classpath", System.getProperty("test.classes", ".")), null, null); diff --git a/test/langtools/tools/javac/defaultMethods/CheckACC_STRICTFlagOnDefaultMethodTest.java b/test/langtools/tools/javac/defaultMethods/CheckACC_STRICTFlagOnDefaultMethodTest.java index f1cb54b41ac28..8df5d1e09395a 100644 --- a/test/langtools/tools/javac/defaultMethods/CheckACC_STRICTFlagOnDefaultMethodTest.java +++ b/test/langtools/tools/javac/defaultMethods/CheckACC_STRICTFlagOnDefaultMethodTest.java @@ -25,21 +25,23 @@ * @test * @bug 8012723 * @summary strictfp interface misses strictfp modifer on default method - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @modules jdk.jdeps/com.sun.tools.classfile * @compile -source 16 -target 16 CheckACC_STRICTFlagOnDefaultMethodTest.java * @run main CheckACC_STRICTFlagOnDefaultMethodTest */ -import jdk.internal.classfile.*; -import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.io.File; +import java.io.IOException; + +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.Descriptor; +import com.sun.tools.classfile.Descriptor.InvalidDescriptor; +import com.sun.tools.classfile.Method; + +import static com.sun.tools.classfile.AccessFlags.ACC_STRICT; public class CheckACC_STRICTFlagOnDefaultMethodTest { private static final String AssertionErrorMessage = @@ -50,11 +52,13 @@ public class CheckACC_STRICTFlagOnDefaultMethodTest { private List errors = new ArrayList<>(); - public static void main(String[] args) throws IOException { + public static void main(String[] args) + throws IOException, ConstantPoolException, InvalidDescriptor { new CheckACC_STRICTFlagOnDefaultMethodTest().run(); } - private void run() throws IOException { + private void run() + throws IOException, ConstantPoolException, InvalidDescriptor { String testClasses = System.getProperty("test.classes"); check(testClasses, "CheckACC_STRICTFlagOnDefaultMethodTest$StrictfpInterface.class"); @@ -66,20 +70,39 @@ private void run() throws IOException { } } - void check(String dir, String... fileNames) throws IOException { + void check(String dir, String... fileNames) + throws + IOException, + ConstantPoolException, + Descriptor.InvalidDescriptor { for (String fileName : fileNames) { - ClassModel classFileToCheck = Classfile.of().parse(new File(dir, fileName).toPath()); + ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName)); - for (MethodModel method : classFileToCheck.methods()) { - if ((method.flags().flagsMask() & Classfile.ACC_STRICT) == 0) { + for (Method method : classFileToCheck.methods) { + if ((method.access_flags.flags & ACC_STRICT) == 0) { errors.add(String.format(offendingMethodErrorMessage, - method.methodName().stringValue(), - classFileToCheck.thisClass().asInternalName())); + method.getName(classFileToCheck.constant_pool), + classFileToCheck.getName())); } } } } +// this version of the code can be used when ClassFile API in not in a preview +// void check(String dir, String... fileNames) throws IOException { +// for (String fileName : fileNames) { +// ClassModel classFileToCheck = ClassFile.of().parse(new File(dir, fileName).toPath()); +// +// for (MethodModel method : classFileToCheck.methods()) { +// if ((method.flags().flagsMask() & ClassFile.ACC_STRICT) == 0) { +// errors.add(String.format(offendingMethodErrorMessage, +// method.methodName().stringValue(), +// classFileToCheck.thisClass().asInternalName())); +// } +// } +// } +// } + strictfp interface StrictfpInterface { default void default_interface_method() {} static void static_interface_method() {} diff --git a/test/langtools/tools/javac/defaultMethods/TestDefaultBody.java b/test/langtools/tools/javac/defaultMethods/TestDefaultBody.java index e44c819e6158e..5cad9ed6293ca 100644 --- a/test/langtools/tools/javac/defaultMethods/TestDefaultBody.java +++ b/test/langtools/tools/javac/defaultMethods/TestDefaultBody.java @@ -25,18 +25,14 @@ * @test * @bug 7192246 * @summary check that code attributed for default methods is correctly generated - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.MemberRefEntry; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.MemberRefEntry; +import java.lang.classfile.instruction.InvokeInstruction; import java.io.*; public class TestDefaultBody { @@ -67,7 +63,7 @@ public void run() throws Exception { void verifyDefaultBody(File f) { System.err.println("verify: " + f); try { - ClassModel cf = Classfile.of().parse(f.toPath()); + ClassModel cf = ClassFile.of().parse(f.toPath()); MethodModel testMethod = null; CodeAttribute codeAttr = null; for (MethodModel m : cf.methods()) { @@ -83,7 +79,7 @@ void verifyDefaultBody(File f) { if (testMethod == null) { throw new Error("Test method not found"); } - if ((testMethod.flags().flagsMask() & Classfile.ACC_ABSTRACT) != 0) { + if ((testMethod.flags().flagsMask() & ClassFile.ACC_ABSTRACT) != 0) { throw new Error("Test method is abstract"); } if (codeAttr == null) { diff --git a/test/langtools/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java b/test/langtools/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java index bdf88fb341d02..5d334224dc7ce 100644 --- a/test/langtools/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java +++ b/test/langtools/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java @@ -25,15 +25,11 @@ * @test * @bug 7192246 * @summary check that javac does not generate bridge methods for defaults - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ -import jdk.internal.classfile.*; +import java.lang.classfile.*; import java.io.*; @@ -74,7 +70,7 @@ public void run() throws Exception { void checkNoBridgeOnDefaults(File f) { System.err.println("check: " + f); try { - ClassModel cf = Classfile.of().parse(f.toPath()); + ClassModel cf = ClassFile.of().parse(f.toPath()); for (MethodModel m : cf.methods()) { String mname = m.methodName().stringValue(); if (mname.equals(TEST_METHOD_NAME)) { diff --git a/test/langtools/tools/javac/defaultMethods/super/TestDirectSuperInterfaceInvoke.java b/test/langtools/tools/javac/defaultMethods/super/TestDirectSuperInterfaceInvoke.java index 6886107e5abe8..5e171b3cdf0fd 100644 --- a/test/langtools/tools/javac/defaultMethods/super/TestDirectSuperInterfaceInvoke.java +++ b/test/langtools/tools/javac/defaultMethods/super/TestDirectSuperInterfaceInvoke.java @@ -25,21 +25,17 @@ * @test * @bug 8027281 * @summary As per JVMS 4.9.2, invokespecial can only refer to direct superinterfaces - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile TestDirectSuperInterfaceInvoke.java * @run main TestDirectSuperInterfaceInvoke */ import java.io.File; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.MemberRefEntry; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.MemberRefEntry; +import java.lang.classfile.instruction.InvokeInstruction; interface BaseInterface { public default int testedMethod(){ return 1; } @@ -88,7 +84,7 @@ void verifyDefaultBody(String classFile) { String workDir = System.getProperty("test.classes"); File file = new File(workDir, classFile); try { - final ClassModel cf = Classfile.of().parse(file.toPath()); + final ClassModel cf = ClassFile.of().parse(file.toPath()); for (MethodModel m : cf.methods()) { CodeAttribute codeAttr = m.findAttribute(Attributes.CODE).orElseThrow(); for (CodeElement ce : codeAttr.elementList()) { diff --git a/test/langtools/tools/javac/diags/CheckResourceKeys.java b/test/langtools/tools/javac/diags/CheckResourceKeys.java index ced98b7f66616..e69d023130af2 100644 --- a/test/langtools/tools/javac/diags/CheckResourceKeys.java +++ b/test/langtools/tools/javac/diags/CheckResourceKeys.java @@ -25,13 +25,9 @@ * @test * @bug 6964768 6964461 6964469 6964487 6964460 6964481 6980021 * @summary need test program to validate javac resource bundles + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.resources:open - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl */ @@ -39,8 +35,8 @@ import java.util.*; import java.util.regex.*; import javax.tools.*; -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.*; import com.sun.tools.javac.code.Lint.LintCategory; /** @@ -496,7 +492,7 @@ JavaFileManager.Location findJavacLocation(JavaFileManager fm) { */ void scan(JavaFileObject fo, Set results) throws IOException { try (InputStream in = fo.openInputStream()) { - ClassModel cm = Classfile.of().parse(in.readAllBytes()); + ClassModel cm = ClassFile.of().parse(in.readAllBytes()); for (PoolEntry pe : cm.constantPool()) { if (pe instanceof Utf8Entry entry) { String v = entry.stringValue(); diff --git a/test/langtools/tools/javac/diags/Example.java b/test/langtools/tools/javac/diags/Example.java index 6b6013b61cae1..1c76e429fd657 100644 --- a/test/langtools/tools/javac/diags/Example.java +++ b/test/langtools/tools/javac/diags/Example.java @@ -297,11 +297,9 @@ private void run(PrintWriter out, Set keys, boolean raw, boolean verbose // source for import statements or a magic comment for (File pf: procFiles) { if (pf.getName().equals("CreateBadClassFile.java")) { - pOpts.add("--add-exports=java.base/jdk.internal.classfile=ALL-UNNAMED"); - pOpts.add("--add-exports=java.base/jdk.internal.classfile.attribute=ALL-UNNAMED"); - pOpts.add("--add-exports=java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED"); - pOpts.add("--add-exports=java.base/jdk.internal.classfile.instruction=ALL-UNNAMED"); - pOpts.add("--add-exports=java.base/jdk.internal.classfile.components=ALL-UNNAMED"); + pOpts.add("--enable-preview"); + pOpts.add("--source"); + pOpts.add(String.valueOf(Runtime.version().feature())); pOpts.add("--add-exports=java.base/jdk.internal.classfile.impl=ALL-UNNAMED"); } } diff --git a/test/langtools/tools/javac/diags/examples.not-yet.txt b/test/langtools/tools/javac/diags/examples.not-yet.txt index 9d7d79eca165e..716301a913ff1 100644 --- a/test/langtools/tools/javac/diags/examples.not-yet.txt +++ b/test/langtools/tools/javac/diags/examples.not-yet.txt @@ -206,8 +206,8 @@ compiler.err.two.class.loaders.2 compiler.err.unmatched.quote compiler.err.unsupported.release.version compiler.warn.profile.target.conflict -compiler.warn.source.target.conflict -compiler.warn.target.default.source.conflict +compiler.err.source.target.conflict +compiler.err.target.default.source.conflict compiler.err.preview.not.latest compiler.err.preview.without.source.or.release compiler.misc.illegal.signature # the compiler can now detect more non-denotable types before class writing @@ -217,7 +217,3 @@ compiler.err.annotation.unrecognized.attribute.name # this one is transitional (waiting for FFM API to exit preview) compiler.warn.restricted.method - -# Pending removal -compiler.note.implicit.annotation.processing -compiler.warn.proc.use.proc.or.implicit diff --git a/test/langtools/tools/javac/diags/examples/BadConstantValueType/BadConstantValueType.java b/test/langtools/tools/javac/diags/examples/BadConstantValueType/BadConstantValueType.java index b57f2e62d8671..c8dac3a388dce 100644 --- a/test/langtools/tools/javac/diags/examples/BadConstantValueType/BadConstantValueType.java +++ b/test/langtools/tools/javac/diags/examples/BadConstantValueType/BadConstantValueType.java @@ -25,7 +25,7 @@ // key: compiler.misc.bad.class.file.header // key: compiler.err.cant.access // options: -processor CreateBadClassFile -// run: exec --add-exports java.base/jdk.internal.classfile=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.attribute=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.instruction=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.components=ALL-UNNAMED +// run: exec --enable-preview /* The annotation processor will create an invalid classfile with a static * final field of type java.lang.Object having ConstantValue attribute with diff --git a/test/langtools/tools/javac/diags/examples/BadConstantValueType/processors/CreateBadClassFile.java b/test/langtools/tools/javac/diags/examples/BadConstantValueType/processors/CreateBadClassFile.java index 24935e6207ebb..c199054305915 100644 --- a/test/langtools/tools/javac/diags/examples/BadConstantValueType/processors/CreateBadClassFile.java +++ b/test/langtools/tools/javac/diags/examples/BadConstantValueType/processors/CreateBadClassFile.java @@ -33,8 +33,8 @@ import javax.tools.*; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.attribute.ConstantValueAttribute; +import java.lang.classfile.ClassFile; +import java.lang.classfile.attribute.ConstantValueAttribute; /* Create an invalid classfile with a static final field of type object with * ConstantValue of type String. @@ -43,7 +43,7 @@ public class CreateBadClassFile extends AbstractProcessor { public boolean process(Set elems, RoundEnvironment renv) { if (++round == 1) { - byte[] bytes = Classfile.of().build(ClassDesc.of("Test"), cb -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("Test"), cb -> { cb.withSuperclass(ConstantDescs.CD_Object); cb.withVersion(51, 0); cb.withFlags(AccessFlag.ABSTRACT , diff --git a/test/langtools/tools/javac/diags/examples/EnumsMustBeStatic.java b/test/langtools/tools/javac/diags/examples/EnumsMustBeStatic.java index 222f2eb290364..6b9283827d41f 100644 --- a/test/langtools/tools/javac/diags/examples/EnumsMustBeStatic.java +++ b/test/langtools/tools/javac/diags/examples/EnumsMustBeStatic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,7 @@ */ // key: compiler.err.static.declaration.not.allowed.in.inner.classes -// key: compiler.warn.source.no.system.modules.path -// options: -source 15 +// options: --release 15 class EnumsMustBeStatic { class Nested { diff --git a/test/langtools/tools/javac/diags/examples/Expected3.java b/test/langtools/tools/javac/diags/examples/Expected3.java index 2b1ec3256187d..1a527034ff3e9 100644 --- a/test/langtools/tools/javac/diags/examples/Expected3.java +++ b/test/langtools/tools/javac/diags/examples/Expected3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ */ // key: compiler.err.expected3 -// key: compiler.warn.source.no.system.modules.path -// options: -source 15 +// options: --release 15 int Expected3; diff --git a/test/langtools/tools/javac/diags/examples/UnnamedClass.java b/test/langtools/tools/javac/diags/examples/ImplicitClass.java similarity index 96% rename from test/langtools/tools/javac/diags/examples/UnnamedClass.java rename to test/langtools/tools/javac/diags/examples/ImplicitClass.java index c78dcf14e6c44..c032bdefeffcd 100644 --- a/test/langtools/tools/javac/diags/examples/UnnamedClass.java +++ b/test/langtools/tools/javac/diags/examples/ImplicitClass.java @@ -21,7 +21,7 @@ * questions. */ - // key: compiler.misc.feature.unnamed.classes + // key: compiler.misc.feature.implicit.classes // key: compiler.warn.preview.feature.use.plural // options: -source ${jdk.version} --enable-preview -Xlint:preview diff --git a/test/langtools/tools/javac/diags/examples/UnnamedClassBad-Filename.java b/test/langtools/tools/javac/diags/examples/ImplicitClassBad-Filename.java similarity index 100% rename from test/langtools/tools/javac/diags/examples/UnnamedClassBad-Filename.java rename to test/langtools/tools/javac/diags/examples/ImplicitClassBad-Filename.java diff --git a/test/langtools/tools/javac/diags/examples/UnnamedClassHasPackage.java b/test/langtools/tools/javac/diags/examples/ImplicitClassHasPackage.java similarity index 92% rename from test/langtools/tools/javac/diags/examples/UnnamedClassHasPackage.java rename to test/langtools/tools/javac/diags/examples/ImplicitClassHasPackage.java index 96601f9a9458f..c90e0f3dfbcd2 100644 --- a/test/langtools/tools/javac/diags/examples/UnnamedClassHasPackage.java +++ b/test/langtools/tools/javac/diags/examples/ImplicitClassHasPackage.java @@ -21,12 +21,12 @@ * questions. */ - // key: compiler.err.unnamed.class.should.not.have.package.declaration + // key: compiler.err.implicit.class.should.not.have.package.declaration // key: compiler.note.preview.filename // key: compiler.note.preview.recompile // options: -source ${jdk.version} --enable-preview -package unnamed.classes; +package implicit.classes; public static void main(String... args) { } diff --git a/test/langtools/tools/javac/diags/examples/UnnamedClassNoMain.java b/test/langtools/tools/javac/diags/examples/ImplicitClassNoMain.java similarity index 95% rename from test/langtools/tools/javac/diags/examples/UnnamedClassNoMain.java rename to test/langtools/tools/javac/diags/examples/ImplicitClassNoMain.java index 0caacb60e6619..4c82341f5acaa 100644 --- a/test/langtools/tools/javac/diags/examples/UnnamedClassNoMain.java +++ b/test/langtools/tools/javac/diags/examples/ImplicitClassNoMain.java @@ -21,7 +21,7 @@ * questions. */ - // key: compiler.err.unnamed.class.does.not.have.main.method + // key: compiler.err.implicit.class.does.not.have.main.method // key: compiler.note.preview.filename // key: compiler.note.preview.recompile // options: -source ${jdk.version} --enable-preview diff --git a/test/langtools/tools/javac/diags/examples/InnerClassCantHaveStatic.java b/test/langtools/tools/javac/diags/examples/InnerClassCantHaveStatic.java index b1eaad961db6d..abe95b8a23ddb 100644 --- a/test/langtools/tools/javac/diags/examples/InnerClassCantHaveStatic.java +++ b/test/langtools/tools/javac/diags/examples/InnerClassCantHaveStatic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,7 @@ */ // key: compiler.err.icls.cant.have.static.decl -// key: compiler.warn.source.no.system.modules.path -// options: -source 15 +// options: --release 15 class InnerClassCantHaveStatic { class Inner { diff --git a/test/langtools/tools/javac/diags/examples/InterfaceNotAllowed.java b/test/langtools/tools/javac/diags/examples/InterfaceNotAllowed.java index a72e7ef12bd84..3c5d5602aa452 100644 --- a/test/langtools/tools/javac/diags/examples/InterfaceNotAllowed.java +++ b/test/langtools/tools/javac/diags/examples/InterfaceNotAllowed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,7 @@ */ // key: compiler.err.intf.not.allowed.here -// key: compiler.warn.source.no.system.modules.path -// options: -source 15 +// options: --release 15 class InterfaceNotAllowed { void m() { diff --git a/test/langtools/tools/javac/diags/examples/InvalidDefaultInterface/InvalidDefaultInterface.java b/test/langtools/tools/javac/diags/examples/InvalidDefaultInterface/InvalidDefaultInterface.java index 0b1899e151ce3..c61e123c64758 100644 --- a/test/langtools/tools/javac/diags/examples/InvalidDefaultInterface/InvalidDefaultInterface.java +++ b/test/langtools/tools/javac/diags/examples/InvalidDefaultInterface/InvalidDefaultInterface.java @@ -25,7 +25,7 @@ // key: compiler.misc.bad.class.file.header // key: compiler.err.cant.access // options: -processor CreateBadClassFile -// run: exec --add-exports java.base/jdk.internal.classfile=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.attribute=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.instruction=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.components=ALL-UNNAMED +// run: exec --enable-preview /* The annotation processor will create an invalid classfile with version 51.0 * and a non-abstract method in an interface. Loading the classfile will produce diff --git a/test/langtools/tools/javac/diags/examples/InvalidDefaultInterface/processors/CreateBadClassFile.java b/test/langtools/tools/javac/diags/examples/InvalidDefaultInterface/processors/CreateBadClassFile.java index fd3c8046b443e..fea4adb4e9920 100644 --- a/test/langtools/tools/javac/diags/examples/InvalidDefaultInterface/processors/CreateBadClassFile.java +++ b/test/langtools/tools/javac/diags/examples/InvalidDefaultInterface/processors/CreateBadClassFile.java @@ -32,19 +32,19 @@ import javax.tools.*; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; /* Create an invalid classfile with version 51.0 and a non-abstract method in an interface.*/ @SupportedAnnotationTypes("*") public class CreateBadClassFile extends AbstractProcessor { public boolean process(Set elems, RoundEnvironment renv) { if (++round == 1) { - byte[] bytes = Classfile.of().build(ClassDesc.of("Test"), classBuilder -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("Test"), classBuilder -> { classBuilder.withVersion(51, 0); classBuilder.withFlags(AccessFlag.ABSTRACT , AccessFlag.INTERFACE , AccessFlag.PUBLIC); - classBuilder.withMethod("test", MethodTypeDesc.of(ConstantDescs.CD_void), Classfile.ACC_PUBLIC, methodBuilder -> { + classBuilder.withMethod("test", MethodTypeDesc.of(ConstantDescs.CD_void), ClassFile.ACC_PUBLIC, methodBuilder -> { methodBuilder.withFlags(AccessFlag.PUBLIC);}); }); try { diff --git a/test/langtools/tools/javac/diags/examples/InvalidStaticInterface/InvalidStaticInterface.java b/test/langtools/tools/javac/diags/examples/InvalidStaticInterface/InvalidStaticInterface.java index 084b66985032c..264b8861107a2 100644 --- a/test/langtools/tools/javac/diags/examples/InvalidStaticInterface/InvalidStaticInterface.java +++ b/test/langtools/tools/javac/diags/examples/InvalidStaticInterface/InvalidStaticInterface.java @@ -25,7 +25,7 @@ // key: compiler.misc.bad.class.file.header // key: compiler.err.cant.access // options: -processor CreateBadClassFile -// run: exec --add-exports java.base/jdk.internal.classfile=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.attribute=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.instruction=ALL-UNNAMED --add-exports java.base/jdk.internal.classfile.components=ALL-UNNAMED +// run: exec --enable-preview /* The annotation processor will create an invalid classfile with version 51.0 * and a static method in an interface. Loading the classfile will produce diff --git a/test/langtools/tools/javac/diags/examples/InvalidStaticInterface/processors/CreateBadClassFile.java b/test/langtools/tools/javac/diags/examples/InvalidStaticInterface/processors/CreateBadClassFile.java index d1b3e29f52158..33e121ce9dfd3 100644 --- a/test/langtools/tools/javac/diags/examples/InvalidStaticInterface/processors/CreateBadClassFile.java +++ b/test/langtools/tools/javac/diags/examples/InvalidStaticInterface/processors/CreateBadClassFile.java @@ -32,21 +32,21 @@ import javax.tools.*; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; /* Create an invalid classfile with version 51.0 and a static method in an interface.*/ @SupportedAnnotationTypes("*") public class CreateBadClassFile extends AbstractProcessor { public boolean process(Set elems, RoundEnvironment renv) { if (++round == 1) { - byte[] bytes = Classfile.of().build(ClassDesc.of("Test"), classBuilder -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of("Test"), classBuilder -> { classBuilder.withVersion(51, 0); classBuilder.withFlags(AccessFlag.ABSTRACT, AccessFlag.INTERFACE, AccessFlag.PUBLIC); classBuilder.withSuperclass(ConstantDescs.CD_Object); classBuilder.withMethod("test", ConstantDescs.MTD_void, - Classfile.ACC_PUBLIC | Classfile.ACC_STATIC, methodBuilder -> { + ClassFile.ACC_PUBLIC | ClassFile.ACC_STATIC, methodBuilder -> { methodBuilder.withCode(xb -> { xb.return_(); }); diff --git a/test/langtools/tools/javac/diags/examples/LocalEnum.java b/test/langtools/tools/javac/diags/examples/LocalEnum.java index fdf875c969776..a7cc2b6dc0baf 100644 --- a/test/langtools/tools/javac/diags/examples/LocalEnum.java +++ b/test/langtools/tools/javac/diags/examples/LocalEnum.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,7 @@ */ // key: compiler.err.local.enum -// key: compiler.warn.source.no.system.modules.path -// options: -source 15 +// options: --release 15 class LocalEnum { void m() { diff --git a/test/langtools/tools/javac/diags/examples/ObsoleteSourceAndTarget.java b/test/langtools/tools/javac/diags/examples/ObsoleteSourceAndTarget.java index 5cf52f2d76aeb..d4a94f032b0b4 100644 --- a/test/langtools/tools/javac/diags/examples/ObsoleteSourceAndTarget.java +++ b/test/langtools/tools/javac/diags/examples/ObsoleteSourceAndTarget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ // key: compiler.warn.option.obsolete.target // key: compiler.warn.option.obsolete.suppression // key: compiler.warn.source.no.bootclasspath +// key: compiler.misc.source.no.bootclasspath.with.target // options: -source 1.8 -target 1.8 class ObsoleteSourceAndTarget { diff --git a/test/langtools/tools/javac/diags/examples/OptionRemovedSource.java b/test/langtools/tools/javac/diags/examples/OptionRemovedSource.java index fadc5142f0c2b..f40ea3225e9e5 100644 --- a/test/langtools/tools/javac/diags/examples/OptionRemovedSource.java +++ b/test/langtools/tools/javac/diags/examples/OptionRemovedSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ // key: compiler.err.option.removed.source // key: compiler.warn.source.no.bootclasspath +// key: compiler.misc.source.no.bootclasspath // options: -source 1.5 class RemovedSourceAndTarget { diff --git a/test/langtools/tools/javac/diags/examples/OptionRemovedTarget.java b/test/langtools/tools/javac/diags/examples/OptionRemovedTarget.java index 81f6d8e0ee066..e38994ec532fd 100644 --- a/test/langtools/tools/javac/diags/examples/OptionRemovedTarget.java +++ b/test/langtools/tools/javac/diags/examples/OptionRemovedTarget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ // key: compiler.err.option.removed.source // key: compiler.err.option.removed.target // key: compiler.warn.source.no.bootclasspath +// key: compiler.misc.source.no.bootclasspath.with.target // options: -source 1.5 -target 1.5 class RemovedSourceAndTarget { diff --git a/test/langtools/tools/javac/diags/examples/ProcUseProcOrImplicit/ProcUseProcOrImplicit.java b/test/langtools/tools/javac/diags/examples/ProcUseProcOrImplicit/ProcUseProcOrImplicit.java index 6d9d9a70ee919..3a697d40cf838 100644 --- a/test/langtools/tools/javac/diags/examples/ProcUseProcOrImplicit/ProcUseProcOrImplicit.java +++ b/test/langtools/tools/javac/diags/examples/ProcUseProcOrImplicit/ProcUseProcOrImplicit.java @@ -21,6 +21,8 @@ * questions. */ +// key: compiler.warn.proc.use.proc.or.implicit +// key: compiler.note.implicit.annotation.processing // options: -Xprefer:source import p.SomeClass; diff --git a/test/langtools/tools/javac/diags/examples/Records.java b/test/langtools/tools/javac/diags/examples/Records.java index 9acc44d0f4393..f356ceed5998f 100644 --- a/test/langtools/tools/javac/diags/examples/Records.java +++ b/test/langtools/tools/javac/diags/examples/Records.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ // key: compiler.misc.feature.records // key: compiler.err.feature.not.supported.in.source.plural -// key: compiler.warn.source.no.system.modules.path -// options: -source 15 +// options: --release 15 record R() {} diff --git a/test/langtools/tools/javac/diags/examples/SealedTypes.java b/test/langtools/tools/javac/diags/examples/SealedTypes.java index 85aca18b2afa1..4bd55525554b7 100644 --- a/test/langtools/tools/javac/diags/examples/SealedTypes.java +++ b/test/langtools/tools/javac/diags/examples/SealedTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,7 @@ // key: compiler.misc.feature.sealed.classes // key: compiler.err.feature.not.supported.in.source.plural -// key: compiler.warn.source.no.system.modules.path -// options: -source 16 +// options: --release 16 sealed class Sealed {} diff --git a/test/langtools/tools/javac/diags/examples/SourceNoBootclasspath.java b/test/langtools/tools/javac/diags/examples/SourceNoBootclasspath.java index 2c30b9e1a3302..5f02a437dbe80 100644 --- a/test/langtools/tools/javac/diags/examples/SourceNoBootclasspath.java +++ b/test/langtools/tools/javac/diags/examples/SourceNoBootclasspath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ // key: compiler.warn.source.no.bootclasspath +// key: compiler.misc.source.no.bootclasspath // key: compiler.warn.option.obsolete.source // key: compiler.warn.option.obsolete.suppression // options: -source 8 diff --git a/test/langtools/tools/javac/diags/examples/SourceNoSystemModulesPath.java b/test/langtools/tools/javac/diags/examples/SourceNoSystemModulesPath.java index 915d5600a6ffe..5967a9b65715d 100644 --- a/test/langtools/tools/javac/diags/examples/SourceNoSystemModulesPath.java +++ b/test/langtools/tools/javac/diags/examples/SourceNoSystemModulesPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,6 +22,7 @@ */ // key: compiler.warn.source.no.system.modules.path +// key: compiler.misc.source.no.system.modules.path // options: -source 9 class SourceNoSystemModulesPath { } diff --git a/test/langtools/tools/javac/diags/examples/SourceNoSystemModulesPathWithTarget.java b/test/langtools/tools/javac/diags/examples/SourceNoSystemModulesPathWithTarget.java new file mode 100644 index 0000000000000..6132c44db6872 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/SourceNoSystemModulesPathWithTarget.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.warn.source.no.system.modules.path +// key: compiler.misc.source.no.system.modules.path.with.target +// options: -source 9 -target 9 + +class SourceNoSystemModulesPath { } diff --git a/test/langtools/tools/javac/diags/examples/TextBlockSource.java b/test/langtools/tools/javac/diags/examples/TextBlockSource.java index f805491cd42ad..9fa6ecca1b8ef 100644 --- a/test/langtools/tools/javac/diags/examples/TextBlockSource.java +++ b/test/langtools/tools/javac/diags/examples/TextBlockSource.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,7 @@ // key: compiler.misc.feature.text.blocks // key: compiler.err.feature.not.supported.in.source.plural - // key: compiler.warn.source.no.system.modules.path - // options: -source 14 + // options: --release 14 class TextBlockSource { String m() { diff --git a/test/langtools/tools/javac/diags/examples/UnderscoreInLambdaExpression.java b/test/langtools/tools/javac/diags/examples/UnderscoreInLambdaExpression.java index dd68a2c212879..d88aa9bc1272e 100644 --- a/test/langtools/tools/javac/diags/examples/UnderscoreInLambdaExpression.java +++ b/test/langtools/tools/javac/diags/examples/UnderscoreInLambdaExpression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,7 @@ // key: compiler.err.feature.not.supported.in.source.plural // key: compiler.misc.feature.unnamed.variables -// key: compiler.warn.source.no.system.modules.path -// options: -source 21 +// options: --release 21 public class UnderscoreInLambdaExpression { java.util.function.Function f = _ -> "x"; diff --git a/test/langtools/tools/javac/expression/_super/NonDirectSuper/NonDirectSuper.java b/test/langtools/tools/javac/expression/_super/NonDirectSuper/NonDirectSuper.java index d19be79c6e49b..05942c567222b 100644 --- a/test/langtools/tools/javac/expression/_super/NonDirectSuper/NonDirectSuper.java +++ b/test/langtools/tools/javac/expression/_super/NonDirectSuper/NonDirectSuper.java @@ -26,12 +26,8 @@ * @bug 8027789 * @summary check that the direct superclass is used as the site when calling * a superclass' method - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile Base.java NonDirectSuper.java * @run main test.NonDirectSuper */ @@ -40,11 +36,11 @@ import java.io.File; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.MemberRefEntry; -import jdk.internal.classfile.instruction.FieldInstruction; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.MemberRefEntry; +import java.lang.classfile.instruction.FieldInstruction; +import java.lang.classfile.instruction.InvokeInstruction; public class NonDirectSuper { public static void main(String... args) { @@ -63,7 +59,7 @@ void run() { void verifyInvokeSpecialRefToObject(File clazz) { try { - final ClassModel cf = Classfile.of().parse(clazz.toPath()); + final ClassModel cf = ClassFile.of().parse(clazz.toPath()); for (MethodModel m : cf.methods()) { CodeAttribute codeAttr = m.findAttribute(Attributes.CODE).orElseThrow(); for (CodeElement ce : codeAttr.elementList()) { diff --git a/test/langtools/tools/javac/file/SymLinkArchiveTest.java b/test/langtools/tools/javac/file/SymLinkArchiveTest.java index adce7b9cc9760..eba933af49e6c 100644 --- a/test/langtools/tools/javac/file/SymLinkArchiveTest.java +++ b/test/langtools/tools/javac/file/SymLinkArchiveTest.java @@ -26,13 +26,9 @@ * @bug 8181897 * @summary * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox * @run main SymLinkArchiveTest diff --git a/test/langtools/tools/javac/file/SymLinkShortNameTest.java b/test/langtools/tools/javac/file/SymLinkShortNameTest.java index 991e682479579..28f25f8b5bf98 100644 --- a/test/langtools/tools/javac/file/SymLinkShortNameTest.java +++ b/test/langtools/tools/javac/file/SymLinkShortNameTest.java @@ -26,13 +26,9 @@ * @bug 8193277 * @summary SimpleFileObject inconsistency between getName and getShortName * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox * @run main SymLinkShortNameTest diff --git a/test/langtools/tools/javac/file/SymLinkTest.java b/test/langtools/tools/javac/file/SymLinkTest.java index c0afdd6da017c..f9dea1d8bc3c3 100644 --- a/test/langtools/tools/javac/file/SymLinkTest.java +++ b/test/langtools/tools/javac/file/SymLinkTest.java @@ -28,13 +28,9 @@ * class.public.should.be.in.file diagnostic and SourceFile * attribute content * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox * @run main SymLinkTest @@ -45,8 +41,8 @@ import java.nio.file.Path; import java.nio.file.Paths; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.SourceFileAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.SourceFileAttribute; import toolbox.JavacTask; import toolbox.TestRunner; import toolbox.TestRunner.Test; @@ -98,7 +94,7 @@ void test(Path base, String name) throws Exception{ .run() .writeAll(); - ClassModel cf = Classfile.of().parse(classes.resolve("HelloWorld.class")); + ClassModel cf = ClassFile.of().parse(classes.resolve("HelloWorld.class")); SourceFileAttribute sf = cf.findAttribute(Attributes.SOURCE_FILE).orElseThrow(); String sourceFile = sf.sourceFile().stringValue(); diff --git a/test/langtools/tools/javac/flow/LVTHarness.java b/test/langtools/tools/javac/flow/LVTHarness.java index 9ca5364264183..6e8afef990311 100644 --- a/test/langtools/tools/javac/flow/LVTHarness.java +++ b/test/langtools/tools/javac/flow/LVTHarness.java @@ -28,12 +28,8 @@ * javac crash while creating LVT entry for a local variable defined in * an inner block * @library /tools/javac/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @build JavacTestingAbstractProcessor LVTHarness * @run main LVTHarness */ @@ -59,8 +55,8 @@ import javax.tools.ToolProvider; import com.sun.source.util.JavacTask; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import static javax.tools.StandardLocation.*; import static javax.tools.JavaFileObject.Kind.SOURCE; @@ -126,7 +122,7 @@ protected void check() throws Exception { } void checkClassFile(File file) throws IOException { - ClassModel classFile = Classfile.of().parse(file.toPath()); + ClassModel classFile = ClassFile.of().parse(file.toPath()); //lets get all the methods in the class file. for (MethodModel method : classFile.methods()) { diff --git a/test/langtools/tools/javac/generics/bridges/BridgeHarness.java b/test/langtools/tools/javac/generics/bridges/BridgeHarness.java index 480d5d703ba14..acf1a3cdef1cf 100644 --- a/test/langtools/tools/javac/generics/bridges/BridgeHarness.java +++ b/test/langtools/tools/javac/generics/bridges/BridgeHarness.java @@ -26,12 +26,8 @@ * @bug 8013789 * @summary Compiler should emit bridges in interfaces * @library /tools/javac/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.util * @build JavacTestingAbstractProcessor BridgeHarness @@ -39,7 +35,7 @@ */ import com.sun.source.util.JavacTask; -import jdk.internal.classfile.*; +import java.lang.classfile.*; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.util.List; @@ -147,7 +143,7 @@ protected void compileAndCheck() throws Exception { */ protected void checkBridges(JavaFileObject jfo) { try (InputStream is = jfo.openInputStream()) { - ClassModel cf = Classfile.of().parse(is.readAllBytes()); + ClassModel cf = ClassFile.of().parse(is.readAllBytes()); System.err.println("checking: " + cf.thisClass().asInternalName()); List bridgeList = bridgesMap.get(cf.thisClass().asInternalName()); @@ -157,7 +153,7 @@ protected void checkBridges(JavaFileObject jfo) { } for (MethodModel m : cf.methods()) { - if ((m.flags().flagsMask() & (Classfile.ACC_SYNTHETIC | Classfile.ACC_BRIDGE)) != 0) { + if ((m.flags().flagsMask() & (ClassFile.ACC_SYNTHETIC | ClassFile.ACC_BRIDGE)) != 0) { //this is a bridge - see if there's a match in the bridge list Bridge match = null; for (Bridge b : bridgeList) { diff --git a/test/langtools/tools/javac/importscope/T8193717.java b/test/langtools/tools/javac/importscope/T8193717.java index 4c88c57974d97..bb2f0e8746226 100644 --- a/test/langtools/tools/javac/importscope/T8193717.java +++ b/test/langtools/tools/javac/importscope/T8193717.java @@ -26,12 +26,8 @@ * @bug 8193717 * @summary Check that code with a lot named imports can compile. * @library /tools/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.jdeps/com.sun.tools.javap @@ -61,7 +57,7 @@ import javax.tools.StandardLocation; import javax.tools.ToolProvider; -import jdk.internal.classfile.*; +import java.lang.classfile.*; import toolbox.JavacTask; import toolbox.ToolBox; @@ -102,10 +98,10 @@ private static String getSimpleName(int c) { } private byte[] generateClassFile(String name) throws IOException { - byte[] bytes = Classfile.of().build(ClassDesc.of(name), classBuilder -> { + byte[] bytes = ClassFile.of().build(ClassDesc.of(name), classBuilder -> { classBuilder.withSuperclass(ClassDesc.ofInternalName("java/lang/Object")) .withVersion(51, 0) - .withFlags(Classfile.ACC_ABSTRACT | Classfile.ACC_INTERFACE | Classfile.ACC_PUBLIC); + .withFlags(ClassFile.ACC_ABSTRACT | ClassFile.ACC_INTERFACE | ClassFile.ACC_PUBLIC); }); ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write(bytes); diff --git a/test/langtools/tools/javac/jvm/ClassRefDupInConstantPoolTest.java b/test/langtools/tools/javac/jvm/ClassRefDupInConstantPoolTest.java index e588978549a35..df700552ae940 100644 --- a/test/langtools/tools/javac/jvm/ClassRefDupInConstantPoolTest.java +++ b/test/langtools/tools/javac/jvm/ClassRefDupInConstantPoolTest.java @@ -25,23 +25,19 @@ * @test * @bug 8015927 * @summary Class reference duplicates in constant pool - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @clean ClassRefDupInConstantPoolTest$Duplicates * @run main ClassRefDupInConstantPoolTest */ import java.util.TreeSet; -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.*; public class ClassRefDupInConstantPoolTest { public static void main(String[] args) throws Exception { - ClassModel cls = Classfile.of().parse(ClassRefDupInConstantPoolTest.class. + ClassModel cls = ClassFile.of().parse(ClassRefDupInConstantPoolTest.class. getResourceAsStream("ClassRefDupInConstantPoolTest$Duplicates.class").readAllBytes()); ConstantPool pool = cls.constantPool(); diff --git a/test/langtools/tools/javac/lambda/ByteCodeTest.java b/test/langtools/tools/javac/lambda/ByteCodeTest.java index 1eedf9c97204f..7a5943935bebf 100644 --- a/test/langtools/tools/javac/lambda/ByteCodeTest.java +++ b/test/langtools/tools/javac/lambda/ByteCodeTest.java @@ -26,18 +26,14 @@ * @bug 8011738 * @author sogoel * @summary Code translation test for Lambda expressions, method references - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @run main ByteCodeTest */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.BootstrapMethodsAttribute; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.BootstrapMethodsAttribute; +import java.lang.classfile.constantpool.*; import java.io.BufferedWriter; import java.io.File; @@ -78,7 +74,7 @@ public static void main(String[] args) { private static boolean verifyClassFileAttributes(File classFile, TestCases tc) { ClassModel c = null; try { - c = Classfile.of().parse(classFile.toPath()); + c = ClassFile.of().parse(classFile.toPath()); } catch (IOException e) { e.printStackTrace(); } diff --git a/test/langtools/tools/javac/lambda/LambdaCapture08.java b/test/langtools/tools/javac/lambda/LambdaCapture08.java new file mode 100644 index 0000000000000..8f5e03ec329c1 --- /dev/null +++ b/test/langtools/tools/javac/lambda/LambdaCapture08.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8321207 + * @summary javac is not accepting correct code + * @compile LambdaCapture08.java + */ + +import java.util.function.*; + +interface LambdaCapture08 { + Object O = new Object() { + IntSupplier x(int m) { + return () -> m; + } + }; +} diff --git a/test/langtools/tools/javac/lambda/LambdaTestStrictFPFlag.java b/test/langtools/tools/javac/lambda/LambdaTestStrictFPFlag.java index 7ec06d21f7749..b24144aa80fb7 100644 --- a/test/langtools/tools/javac/lambda/LambdaTestStrictFPFlag.java +++ b/test/langtools/tools/javac/lambda/LambdaTestStrictFPFlag.java @@ -25,18 +25,14 @@ * @test * @bug 8046060 * @summary Different results of floating point multiplication for lambda code block - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @modules jdk.jdeps/com.sun.tools.classfile * @compile -source 16 -target 16 LambdaTestStrictFPFlag.java * @run main LambdaTestStrictFPFlag */ import java.io.*; import java.net.URL; -import jdk.internal.classfile.*; +import com.sun.tools.classfile.*; public class LambdaTestStrictFPFlag { public static void main(String[] args) throws Exception { @@ -44,11 +40,12 @@ public static void main(String[] args) throws Exception { } void run() throws Exception { - ClassModel cm = getClassFile("LambdaTestStrictFPFlag$Test.class"); + ClassFile cf = getClassFile("LambdaTestStrictFPFlag$Test.class"); + ConstantPool cp = cf.constant_pool; boolean found = false; - for (MethodModel meth: cm.methods()) { - if (meth.methodName().stringValue().startsWith("lambda$")) { - if ((meth.flags().flagsMask() & Classfile.ACC_STRICT) == 0){ + for (Method meth: cf.methods) { + if (meth.getName(cp).startsWith("lambda$")) { + if ((meth.access_flags.flags & AccessFlags.ACC_STRICT) == 0) { throw new Exception("strict flag missing from lambda"); } found = true; @@ -59,11 +56,30 @@ void run() throws Exception { } } - ClassModel getClassFile(String name) throws IOException { +// this version of the code can be used when ClassFile API in not in a preview +// void run() throws Exception { +// ClassModel cm = getClassFile("LambdaTestStrictFPFlag$Test.class"); +// boolean found = false; +// for (MethodModel meth: cm.methods()) { +// if (meth.methodName().stringValue().startsWith("lambda$")) { +// if ((meth.flags().flagsMask() & ClassFile.ACC_STRICT) == 0){ +// throw new Exception("strict flag missing from lambda"); +// } +// found = true; +// } +// } +// if (!found) { +// throw new Exception("did not find lambda method"); +// } +// } + + ClassFile getClassFile(String name) throws IOException, ConstantPoolException { URL url = getClass().getResource(name); - assert url != null; - try (InputStream in = url.openStream()) { - return Classfile.of().parse(in.readAllBytes()); + InputStream in = url.openStream(); + try { + return ClassFile.read(in); + } finally { + in.close(); } } diff --git a/test/langtools/tools/javac/lambda/LocalVariableTable.java b/test/langtools/tools/javac/lambda/LocalVariableTable.java index 3b94f1972e556..3a6367511994b 100644 --- a/test/langtools/tools/javac/lambda/LocalVariableTable.java +++ b/test/langtools/tools/javac/lambda/LocalVariableTable.java @@ -25,12 +25,8 @@ * @test * @bug 8025998 8026749 8054220 8058227 * @summary Missing LV table in lambda bodies - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g LocalVariableTable.java * @run main LocalVariableTable */ @@ -38,8 +34,8 @@ import java.io.*; import java.lang.annotation.*; import java.util.*; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; /* * The test checks that a LocalVariableTable attribute is generated for the @@ -87,7 +83,7 @@ void check(Class c) throws Exception { return; } - ClassModel cm = Classfile.of().parse(Objects.requireNonNull(getClass().getResource(c.getName() + ".class")).openStream().readAllBytes()); + ClassModel cm = ClassFile.of().parse(Objects.requireNonNull(getClass().getResource(c.getName() + ".class")).openStream().readAllBytes()); MethodModel m = getLambdaMethod(cm); if (m == null) { error("lambda method not found"); diff --git a/test/langtools/tools/javac/lambda/TestBootstrapMethodsCount.java b/test/langtools/tools/javac/lambda/TestBootstrapMethodsCount.java index 99d55c9e0ed6d..c8b405b706adf 100644 --- a/test/langtools/tools/javac/lambda/TestBootstrapMethodsCount.java +++ b/test/langtools/tools/javac/lambda/TestBootstrapMethodsCount.java @@ -26,12 +26,8 @@ * @bug 8129547 * @summary Excess entries in BootstrapMethods with the same (bsm, bsmKind, bsmStaticArgs), but different dynamicArgs * @library /tools/javac/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.jvm @@ -57,8 +53,8 @@ import com.sun.source.util.TaskListener; import com.sun.source.util.TreeScanner; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.BootstrapMethodsAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.BootstrapMethodsAttribute; import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.code.Symbol; @@ -115,7 +111,7 @@ public void run(JavaCompiler comp) { void verifyBytecode() { File compiledTest = new File("Test.class"); try { - ClassModel cf = Classfile.of().parse(compiledTest.toPath()); + ClassModel cf = ClassFile.of().parse(compiledTest.toPath()); BootstrapMethodsAttribute bsm_attr = cf.findAttribute(Attributes.BOOTSTRAP_METHODS).orElseThrow(); int length = bsm_attr.bootstrapMethodsSize(); if (length != 1) { diff --git a/test/langtools/tools/javac/lambda/TestInvokeDynamic.java b/test/langtools/tools/javac/lambda/TestInvokeDynamic.java index 006588146b5f2..56bb63fc2c990 100644 --- a/test/langtools/tools/javac/lambda/TestInvokeDynamic.java +++ b/test/langtools/tools/javac/lambda/TestInvokeDynamic.java @@ -28,12 +28,8 @@ * Add back-end support for invokedynamic * temporarily workaround combo tests are causing time out in several platforms * @library /tools/javac/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.file @@ -56,10 +52,10 @@ import com.sun.source.util.TaskListener; import com.sun.source.util.TreeScanner; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.*; -import jdk.internal.classfile.instruction.InvokeDynamicInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.*; +import java.lang.classfile.instruction.InvokeDynamicInstruction; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.MethodHandleSymbol; @@ -257,7 +253,7 @@ void verifyBytecode(Result> res) { return; } try (InputStream is = res.get().iterator().next().openInputStream()){ - ClassModel cm = Classfile.of().parse(is.readAllBytes()); + ClassModel cm = ClassFile.of().parse(is.readAllBytes()); MethodModel testMethod = null; for (MethodModel m : cm.methods()) { if (m.methodName().equalsString("test")) { diff --git a/test/langtools/tools/javac/lambda/bytecode/TestLambdaBytecode.java b/test/langtools/tools/javac/lambda/bytecode/TestLambdaBytecode.java index bc5a673dc95c1..dd63748936102 100644 --- a/test/langtools/tools/javac/lambda/bytecode/TestLambdaBytecode.java +++ b/test/langtools/tools/javac/lambda/bytecode/TestLambdaBytecode.java @@ -27,12 +27,8 @@ * @summary Lambda back-end should generate invokevirtual for method handles referring to * private instance methods as lambda proxy is a nestmate of the target clsas * @library /tools/javac/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.util @@ -40,10 +36,10 @@ * @run main TestLambdaBytecode */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.*; -import jdk.internal.classfile.instruction.InvokeDynamicInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.*; +import java.lang.classfile.instruction.InvokeDynamicInstruction; import java.io.IOException; import java.io.InputStream; @@ -210,7 +206,7 @@ void verifyBytecode(Result> res) { return; } try (InputStream is = res.get().iterator().next().openInputStream()) { - ClassModel cf = Classfile.of().parse(is.readAllBytes()); + ClassModel cf = ClassFile.of().parse(is.readAllBytes()); MethodModel testMethod = null; for (MethodModel m : cf.methods()) { if (m.methodName().equalsString("test")) { diff --git a/test/langtools/tools/javac/lambda/bytecode/TestLambdaBytecodeTargetRelease14.java b/test/langtools/tools/javac/lambda/bytecode/TestLambdaBytecodeTargetRelease14.java index 6a566c1edb855..2ac3e322970e6 100644 --- a/test/langtools/tools/javac/lambda/bytecode/TestLambdaBytecodeTargetRelease14.java +++ b/test/langtools/tools/javac/lambda/bytecode/TestLambdaBytecodeTargetRelease14.java @@ -27,12 +27,8 @@ * @summary Lambda back-end should generate invokespecial for method handles referring to * private instance methods when compiling with --release 14 * @library /tools/javac/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.util @@ -40,11 +36,11 @@ * @run main TestLambdaBytecodeTargetRelease14 */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.InvokeDynamicEntry; -import jdk.internal.classfile.constantpool.MethodHandleEntry; -import jdk.internal.classfile.instruction.InvokeDynamicInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.InvokeDynamicEntry; +import java.lang.classfile.constantpool.MethodHandleEntry; +import java.lang.classfile.instruction.InvokeDynamicInstruction; import java.io.IOException; import java.io.InputStream; @@ -212,7 +208,7 @@ void verifyBytecode(Result> res) { return; } try (InputStream is = res.get().iterator().next().openInputStream()) { - ClassModel cm = Classfile.of().parse(is.readAllBytes()); + ClassModel cm = ClassFile.of().parse(is.readAllBytes()); MethodModel testMethod = null; for (MethodModel m : cm.methods()) { if (m.methodName().equalsString("test")) { diff --git a/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java b/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java index 32ea7a6d8ca5f..fddf11b57e4f0 100644 --- a/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java +++ b/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java @@ -24,11 +24,8 @@ /** * @test 8200301 8201194 * @summary deduplicate lambda methods with the same body, target type, and captured state - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview + * @modules * java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.code jdk.compiler/com.sun.tools.javac.comp @@ -46,10 +43,10 @@ import com.sun.source.util.TaskEvent; import com.sun.source.util.TaskEvent.Kind; import com.sun.source.util.TaskListener; -import jdk.internal.classfile.BootstrapMethodEntry; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.BootstrapMethodsAttribute; -import jdk.internal.classfile.constantpool.MethodHandleEntry; +import java.lang.classfile.BootstrapMethodEntry; +import java.lang.classfile.*; +import java.lang.classfile.attribute.BootstrapMethodsAttribute; +import java.lang.classfile.constantpool.MethodHandleEntry; import com.sun.tools.javac.api.ClientCodeWrapper.Trusted; import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.code.Symbol; @@ -143,7 +140,7 @@ public static void main(String[] args) throws Exception { for (JavaFileObject output : generated) { ClassModel cm; try (InputStream input = output.openInputStream()) { - cm = Classfile.of().parse(input.readAllBytes()); + cm = ClassFile.of().parse(input.readAllBytes()); } if (cm.thisClass().asInternalName().equals("com/sun/tools/javac/comp/Deduplication$R")) { continue; diff --git a/test/langtools/tools/javac/lambda/lambdaNaming/TestNonSerializableLambdaNameStability.java b/test/langtools/tools/javac/lambda/lambdaNaming/TestNonSerializableLambdaNameStability.java index 4a5ff01aaa954..8052c4b67bc72 100644 --- a/test/langtools/tools/javac/lambda/lambdaNaming/TestNonSerializableLambdaNameStability.java +++ b/test/langtools/tools/javac/lambda/lambdaNaming/TestNonSerializableLambdaNameStability.java @@ -26,12 +26,8 @@ * @bug 8067422 * @summary Check that the lambda names are not unnecessarily unstable * @library /tools/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.jdeps/com.sun.tools.javap @@ -45,7 +41,7 @@ import java.util.List; import javax.tools.StandardLocation; -import jdk.internal.classfile.*; +import java.lang.classfile.*; import toolbox.JavacTask; import toolbox.ToolBox; @@ -87,7 +83,7 @@ void run() throws Exception { byte[] fileBytes = fm.getFileBytes(StandardLocation.CLASS_OUTPUT, file); try (InputStream in = new ByteArrayInputStream(fileBytes)) { boolean foundLambdaMethod = false; - ClassModel cf = Classfile.of().parse(in.readAllBytes()); + ClassModel cf = ClassFile.of().parse(in.readAllBytes()); StringBuilder seenMethods = new StringBuilder(); String sep = ""; for (MethodModel m : cf.methods()) { diff --git a/test/langtools/tools/javac/launcher/BasicSourceLauncherTests.java b/test/langtools/tools/javac/launcher/BasicSourceLauncherTests.java new file mode 100644 index 0000000000000..1a686a8a38f6d --- /dev/null +++ b/test/langtools/tools/javac/launcher/BasicSourceLauncherTests.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import static org.junit.jupiter.api.Assertions.*; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +/* + * @test + * @enablePreview + * @bug 8304400 + * @summary Test basic features of javac's source-code launcher + * @modules jdk.compiler/com.sun.tools.javac.launcher + * @run junit BasicSourceLauncherTests + */ +class BasicSourceLauncherTests { + @Test + void launchHelloClassInHelloJavaUnit(@TempDir Path base) throws Exception { + var hello = Files.writeString(base.resolve("Hello.java"), + """ + public class Hello { + public static void main(String... args) { + System.out.println("Hi"); + } + } + """); + + var run = Run.of(hello); + var result = run.result(); + assertAll("# " + run, + () -> assertLinesMatch( + """ + Hi + """.lines(), run.stdOut().lines()), + () -> assertTrue(run.stdErr().isEmpty()), + () -> assertNull(run.exception()), + () -> assertEquals(Set.of("Hello"), result.classNames()), + () -> assertNotNull(result.programClass().getResource("Hello.java")), + () -> assertNotNull(result.programClass().getResource("Hello.class"))); + } + + @Test + void launchHelloClassInHalloJavaUnit(@TempDir Path base) throws Exception { + var hallo = Files.writeString(base.resolve("Hallo.java"), + """ + public class Hello { + public static void main(String... args) { + System.out.println("Hi!"); + } + } + """); + + var run = Run.of(hallo); + var result = run.result(); + assertAll("# " + run, + () -> assertLinesMatch( + """ + Hi! + """.lines(), run.stdOut().lines()), + () -> assertTrue(run.stdErr().isEmpty()), + () -> assertNull(run.exception()), + () -> assertEquals(Set.of("Hello"), result.classNames()), + () -> assertNotNull(result.programClass().getResource("Hallo.java")), + () -> assertNotNull(result.programClass().getResource("Hello.class"))); + } + + @Test + void launchMinifiedJavaProgram(@TempDir Path base) throws Exception { + var hi = Files.writeString(base.resolve("Hi.java"), + """ + void main() { + System.out.println("Hi!"); + } + """); + + // Replace with plain Run.of(hi) once implict classes are out of preview + System.setProperty("jdk.internal.javac.source", String.valueOf(Runtime.version().feature())); + var run = Run.of(hi, List.of("--enable-preview"), List.of()); + System.clearProperty("jdk.internal.javac.source"); + + assertAll("# " + run, + () -> assertLinesMatch( + """ + Hi! + """.lines(), run.stdOut().lines()), + () -> assertTrue(run.stdErr().isEmpty()), + () -> assertNull(run.exception())); + } +} diff --git a/test/langtools/tools/javac/launcher/GetResourceTest.java b/test/langtools/tools/javac/launcher/GetResourceTest.java index 9433ec657b2e1..4b46cb034eeed 100644 --- a/test/langtools/tools/javac/launcher/GetResourceTest.java +++ b/test/langtools/tools/javac/launcher/GetResourceTest.java @@ -23,8 +23,9 @@ /* * @test - * @bug 8210009 + * @bug 8210009 8321739 * @summary Source Launcher classloader should support getResource and getResourceAsStream + * @enablePreview * @modules jdk.compiler * @library /tools/lib * @build toolbox.JavaTask toolbox.ToolBox @@ -39,8 +40,8 @@ import toolbox.ToolBox; /* - * The body of this test is in ${test.src}/src/CLTest.java, - * which is executed in single-file source-launcher mode, + * The body of this test is in ${test.src}/src/p/q/CLTest.java, + * which is executed in source-launcher mode, * in order to test the classloader used to launch such programs. */ public class GetResourceTest { @@ -51,10 +52,9 @@ public static void main(String... args) throws Exception { void run() throws Exception { ToolBox tb = new ToolBox(); - Path file = Paths.get(tb.testSrc).resolve("src").resolve("CLTest.java"); + Path file = Paths.get(tb.testSrc).resolve("src/p/q").resolve("CLTest.java"); new JavaTask(tb) - .vmOptions("--add-exports", "java.base/jdk.internal.classfile=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED") + .vmOptions("--enable-preview", "--source", String.valueOf(Runtime.version().feature())) .className(file.toString()) // implies source file mode .run(Task.Expect.SUCCESS) .writeAll(); diff --git a/test/langtools/tools/javac/launcher/ModuleSourceLauncherTests.java b/test/langtools/tools/javac/launcher/ModuleSourceLauncherTests.java new file mode 100644 index 0000000000000..d5103525f571a --- /dev/null +++ b/test/langtools/tools/javac/launcher/ModuleSourceLauncherTests.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8304400 + * @summary Test source launcher running Java programs contained in one module + * @modules jdk.compiler/com.sun.tools.javac.launcher + * @run junit ModuleSourceLauncherTests + */ + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Set; +import java.util.spi.ToolProvider; + +class ModuleSourceLauncherTests { + @Test + void testHelloModularWorld(@TempDir Path base) throws Exception { + var packageFolder = Files.createDirectories(base.resolve("com/greetings")); + var mainFile = Files.writeString(packageFolder.resolve("Main.java"), + """ + package com.greetings; + public class Main { + public static void main(String... args) { + System.out.println("Greetings!"); + System.out.println(" module -> " + Main.class.getModule().getName()); + System.out.println(" package -> " + Main.class.getPackageName()); + System.out.println(" class -> " + Main.class.getSimpleName()); + } + } + """); + Files.writeString(base.resolve("module-info.java"), + """ + module com.greetings {} + """); + + var run = Run.of(mainFile); + assertAll("Run -> " + run, + () -> assertLinesMatch( + """ + Greetings! + module -> com.greetings + package -> com.greetings + class -> Main + """.lines(), + run.stdOut().lines()), + () -> assertTrue(run.stdErr().isEmpty()), + () -> assertNull(run.exception()) + ); + + var module = run.result().programClass().getModule(); + assertEquals("com.greetings", module.getName()); + var reference = module.getLayer().configuration().findModule(module.getName()).orElseThrow().reference(); + try (var reader = reference.open()) { + assertLinesMatch( + """ + com/ + com/greetings/ + com/greetings/Main.class + com/greetings/Main.java + module-info.class + module-info.java + """.lines(), + reader.list()); + } + } + + @Test + void testTwoAndHalfPackages(@TempDir Path base) throws Exception { + var fooFolder = Files.createDirectories(base.resolve("foo")); + var program = Files.writeString(fooFolder.resolve("Main.java"), + """ + package foo; + public class Main { + public static void main(String... args) throws Exception { + var module = Main.class.getModule(); + System.out.println("To the " + bar.Bar.class + " from " + module); + try (var stream = module.getResourceAsStream("baz/baz.txt")) { + System.out.println(new String(stream.readAllBytes())); + } + } + } + """); + var barFolder = Files.createDirectories(base.resolve("bar")); + Files.writeString(barFolder.resolve("Bar.java"), "package bar; public record Bar() {}"); + var bazFolder = Files.createDirectories(base.resolve("baz")); + Files.writeString(bazFolder.resolve("baz.txt"), "baz"); + + Files.writeString(base.resolve("module-info.java"), + """ + module m { + exports foo; + exports bar; + opens baz; + } + """); + + var run = Run.of(program); + var result = run.result(); + assertAll("Run -> " + run, + () -> assertLinesMatch( + """ + To the class bar.Bar from module m + baz + """.lines(), + run.stdOut().lines()), + () -> assertTrue(run.stdErr().isEmpty()), + () -> assertNull(run.exception()), + () -> assertEquals(Set.of("foo", "bar", "baz"), result.programClass().getModule().getPackages()) + ); + + var module = run.result().programClass().getModule(); + assertEquals("m", module.getName()); + var reference = module.getLayer().configuration().findModule(module.getName()).orElseThrow().reference(); + try (var reader = reference.open()) { + assertLinesMatch( + """ + bar/ + bar/Bar.class + bar/Bar.java + baz/ + baz/baz.txt + foo/ + foo/Main.class + foo/Main.java + module-info.class + module-info.java + """.lines(), + reader.list()); + } + } + + @Test + void testUserModuleOnModulePath(@TempDir Path base) throws Exception { + Files.createDirectories(base.resolve("foo", "foo")); + Files.writeString(base.resolve("foo", "module-info.java"), + """ + module foo { + exports foo; + } + """); + Files.writeString(base.resolve("foo", "foo", "Foo.java"), + """ + package foo; + public record Foo() {} + """); + var javac = ToolProvider.findFirst("javac").orElseThrow(); + javac.run(System.out, System.err, "--module-source-path", base.toString(), "--module", "foo", "-d", base.toString()); + + Files.createDirectories(base.resolve("bar", "bar")); + Files.writeString(base.resolve("bar", "module-info.java"), + """ + module bar { + requires foo; + } + """); + Files.writeString(base.resolve("bar", "bar","Prog1.java"), + """ + package bar; + class Prog1 { + public static void main(String... args) { + System.out.println(new foo.Foo()); + } + } + """); + + var command = List.of( + Path.of(System.getProperty("java.home"), "bin", "java").toString(), + "-p", ".", + "bar/bar/Prog1.java"); + var redirectedOut = base.resolve("out.redirected"); + var redirectedErr = base.resolve("err.redirected"); + var process = new ProcessBuilder(command) + .directory(base.toFile()) + .redirectOutput(redirectedOut.toFile()) + .redirectError(redirectedErr.toFile()) + .start(); + var code = process.waitFor(); + var out = Files.readAllLines(redirectedOut); + var err = Files.readAllLines(redirectedErr); + + assertAll( + () -> assertEquals(0, code), + () -> assertLinesMatch( + """ + Foo[] + """.lines(), out.stream()), + () -> assertTrue(err.isEmpty()) + ); + } +} diff --git a/test/langtools/tools/javac/launcher/MultiFileSourceLauncherTests.java b/test/langtools/tools/javac/launcher/MultiFileSourceLauncherTests.java new file mode 100644 index 0000000000000..12a5bf09dfefb --- /dev/null +++ b/test/langtools/tools/javac/launcher/MultiFileSourceLauncherTests.java @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8304400 + * @summary Test source launcher running Java programs spanning multiple files + * @modules jdk.compiler/com.sun.tools.javac.launcher + * @run junit MultiFileSourceLauncherTests + */ + +import static org.junit.jupiter.api.Assertions.*; + +import com.sun.tools.javac.launcher.Fault; +import java.nio.file.*; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.io.*; + +class MultiFileSourceLauncherTests { + @Test + void testHelloWorldInTwoCompilationUnits(@TempDir Path base) throws Exception { + var hello = Files.writeString(base.resolve("Hello.java"), + """ + public class Hello { + public static void main(String... args) { + System.out.println("Hello " + new World("Terra")); + System.out.println(Hello.class.getResource("Hello.java")); + System.out.println(Hello.class.getResource("World.java")); + } + } + """); + Files.writeString(base.resolve("World.java"), + """ + record World(String name) {} + """); + + var run = Run.of(hello); + assertLinesMatch( + """ + Hello World[name=Terra] + \\Qfile:\\E.+\\QHello.java\\E + \\Qfile:\\E.+\\QWorld.java\\E + """.lines(), + run.stdOut().lines()); + assertTrue(run.stdErr().isEmpty(), run.toString()); + assertNull(run.exception(), run.toString()); + } + + @Test + void testLoadingOfEnclosedTypes(@TempDir Path base) throws Exception { + var hello = Files.writeString(base.resolve("Hello.java"), + """ + public class Hello { + public static void main(String... args) throws Exception { + System.out.println(Class.forName("World$Core")); + System.out.println(Class.forName("p.q.Unit$First$Second")); + } + } + """); + Files.writeString(base.resolve("World.java"), + """ + record World(String name) { + record Core() {} + } + """); + var pq = Files.createDirectories(base.resolve("p/q")); + Files.writeString(pq.resolve("Unit.java"), + """ + package p.q; + record Unit() { + record First() { + record Second() {} + } + } + """); + + var run = Run.of(hello); + assertAll("Run -> " + run, + () -> assertLinesMatch( + """ + class World$Core + class p.q.Unit$First$Second + """.lines(), + run.stdOut().lines()), + () -> assertTrue(run.stdErr().isEmpty()), + () -> assertNull(run.exception()) + ); + } + + @Test + void testMultiplePackages(@TempDir Path base) throws Exception { + var packageA = Files.createDirectories(base.resolve("a")); + var hello = Files.writeString(packageA.resolve("Hello.java"), + """ + package a; + import b.World; + public class Hello { + public static void main(String... args) { + System.out.println("Hello " + new World("in package b")); + } + } + """); + var packageB = Files.createDirectories(base.resolve("b")); + Files.writeString(packageB.resolve("World.java"), + """ + package b; + public record World(String name) {} + """); + + var run = Run.of(hello); + assertLinesMatch( + """ + Hello World[name=in package b] + """.lines(), + run.stdOut().lines()); + assertTrue(run.stdErr().isEmpty(), run.toString()); + assertNull(run.exception(), run.toString()); + } + + @Test + void testMissingSecondUnit(@TempDir Path base) throws Exception { + var program = Files.writeString(base.resolve("Program.java"), + """ + public class Program { + public static void main(String... args) { + System.out.println("Hello " + new MissingSecondUnit()); + } + } + """); + + var run = Run.of(program); + assertTrue(run.stdOut().isEmpty(), run.toString()); + assertLinesMatch( + """ + %s:3: error: cannot find symbol + System.out.println("Hello " + new MissingSecondUnit()); + ^ + symbol: class MissingSecondUnit + location: class Program + 1 error + """.formatted(program.toString()) + .lines(), + run.stdErr().lines(), + run.toString()); + assertTrue(run.exception() instanceof Fault); + } + + @Test + void testSecondUnitWithSyntaxError(@TempDir Path base) throws Exception { + var program = Files.writeString(base.resolve("Program.java"), + """ + public class Program { + public static void main(String... args) { + System.out.println("Hello " + new BrokenSecondUnit()); + } + } + """); + var broken = Files.writeString(base.resolve("BrokenSecondUnit.java"), + """ + record BrokenSecondUnit {} + """); + + var run = Run.of(program); + assertTrue(run.stdOut().isEmpty(), run.toString()); + assertLinesMatch( + """ + %s:1: error: '(' expected + >> MORE LINES >> + """.formatted(broken.toString()) + .lines(), + run.stdErr().lines(), + run.toString()); + assertTrue(run.exception() instanceof Fault); + } + + @Test + void onlyJavaFilesReferencedByTheProgramAreCompiled(@TempDir Path base) throws Exception { + var prog = Files.writeString(base.resolve("Prog.java"), + """ + class Prog { + public static void main(String... args) { + Helper.run(); + } + } + """); + Files.writeString(base.resolve("Helper.java"), + """ + class Helper { + static void run() { + System.out.println("Hello!"); + } + } + """); + + var old = Files.writeString(base.resolve("OldProg.java"), + """ + class OldProg { + public static void main(String... args) { + Helper.run() + } + } + """); + + var run = Run.of(prog); + assertAll("Run := " + run, + () -> assertLinesMatch( + """ + Hello! + """.lines(), run.stdOut().lines()), + () -> assertTrue(run.stdErr().isEmpty()), + () -> assertNull(run.exception())); + + var fail = Run.of(old); + assertAll("Run := " + fail, + () -> assertTrue(fail.stdOut().isEmpty()), + () -> assertLinesMatch( + """ + %s:3: error: ';' expected + Helper.run() + ^ + 1 error + """.formatted(old).lines(), fail.stdErr().lines()), + () -> assertNotNull(fail.exception())); + } + + @Test + void classesDeclaredInSameFileArePreferredToClassesInOtherFiles(@TempDir Path base) throws Exception { + var prog = Files.writeString(base.resolve("Prog.java"), + """ + class Helper { + static void run() { + System.out.println("Same file."); + } + } + public class Prog { + public static void main(String... args) { + Helper.run(); + } + } + """); + Files.writeString(base.resolve("Helper.java"), + """ + class Helper { + static void run() { + System.out.println("Other file."); + } + } + """); + + var run = Run.of(prog); + assertAll("Run := " + run, + () -> assertLinesMatch( + """ + Same file. + """.lines(), run.stdOut().lines()), + () -> assertTrue(run.stdErr().isEmpty()), + () -> assertNull(run.exception())); + } + + @Test + void duplicateDeclarationOfClassFails(@TempDir Path base) throws Exception { + var prog = Files.writeString(base.resolve("Prog.java"), + """ + class Prog { + public static void main(String... args) { + Helper.run(); + Aux.cleanup(); + } + } + class Aux { + static void cleanup() {} + } + """); + var helper = Files.writeString(base.resolve("Helper.java"), + """ + class Helper { + static void run() {} + } + class Aux { + static void cleanup() {} + } + """); + + + var fail = Run.of(prog); + assertAll("Run := " + fail, + () -> assertTrue(fail.stdOut().isEmpty()), + () -> assertLinesMatch( + """ + %s:4: error: duplicate class: Aux + class Aux { + ^ + 1 error + """.formatted(helper).lines(), fail.stdErr().lines()), + () -> assertNotNull(fail.exception())); + } +} diff --git a/test/langtools/tools/javac/launcher/ProgramDescriptorTests.java b/test/langtools/tools/javac/launcher/ProgramDescriptorTests.java new file mode 100644 index 0000000000000..8e0f1cdba90cf --- /dev/null +++ b/test/langtools/tools/javac/launcher/ProgramDescriptorTests.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8304400 + * @summary Test source root directory computation + * @modules jdk.compiler/com.sun.tools.javac.launcher + * @run junit ProgramDescriptorTests + */ + +import com.sun.tools.javac.launcher.ProgramDescriptor; +import java.nio.file.Path; +import org.junit.jupiter.api.condition.DisabledOnOs; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.junit.jupiter.api.Assertions.*; + +class ProgramDescriptorTests { + @ParameterizedTest + @CsvSource(textBlock = + """ + '/', '/Program.java', '' + '/', '/a/Program.java', 'a', + '/', '/a/b/Program.java', 'a.b', + '/', '/a/b/c/Program.java', 'a.b.c' + + '/a', '/a/b/c/Program.java', 'b.c' + '/a/b', '/a/b/c/Program.java', 'c' + '/a/b/c', '/a/b/c/Program.java', '' + """) + @DisabledOnOs(OS.WINDOWS) + void checkComputeSourceRootPath(Path expected, Path program, String packageName) { + check(expected, program, packageName); + } + + @ParameterizedTest + @CsvSource(textBlock = + """ + 'C:\\', 'C:\\Program.java', '' + 'C:\\', 'C:\\a\\Program.java', 'a', + 'C:\\', 'C:\\a\\b\\Program.java', 'a.b', + 'C:\\', 'C:\\a\\b\\c\\Program.java', 'a.b.c' + + 'C:\\a', 'C:\\a\\b\\c\\Program.java', 'b.c' + 'C:\\a\\b', 'C:\\a\\b\\c\\Program.java', 'c' + 'C:\\a\\b\\c', 'C:\\a\\b\\c\\Program.java', '' + """) + @EnabledOnOs(OS.WINDOWS) + void checkComputeSourceRootPathOnWindows(Path expected, Path program, String packageName) { + check(expected, program, packageName); + } + + private void check(Path expectedRoot, Path programPath, String packageName) { + assertTrue(expectedRoot.isAbsolute(), "Expected path not absolute: " + expectedRoot); + assertTrue(programPath.isAbsolute(), "Program path not absolute: " + programPath); + + var actual = ProgramDescriptor.computeSourceRootPath(programPath, packageName); + assertEquals(expectedRoot, actual); + } +} diff --git a/test/langtools/tools/javac/launcher/Run.java b/test/langtools/tools/javac/launcher/Run.java new file mode 100644 index 0000000000000..4d40d9d6a4cd5 --- /dev/null +++ b/test/langtools/tools/javac/launcher/Run.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import com.sun.tools.javac.launcher.SourceLauncher; +import com.sun.tools.javac.launcher.Result; + +record Run(String stdOut, String stdErr, Throwable exception, Result result) { + static Run of(Path file) { + return Run.of(file, List.of(), List.of("1", "2", "3")); + } + + static Run of(Path file, List runtimeArgs, List appArgs) { + List args = new ArrayList<>(); + args.add(file.toString()); + args.addAll(appArgs); + + PrintStream prev = System.out; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (PrintStream out = new PrintStream(baos, true)) { + System.setOut(out); + StringWriter sw = new StringWriter(); + try (PrintWriter err = new PrintWriter(sw, true)) { + var launcher = new SourceLauncher(err); + var result = launcher.run(runtimeArgs.toArray(String[]::new), args.toArray(String[]::new)); + return new Run(baos.toString(), sw.toString(), null, result); + } catch (Throwable throwable) { + return new Run(baos.toString(), sw.toString(), throwable, null); + } + } finally { + System.setOut(prev); + } + } +} diff --git a/test/langtools/tools/javac/launcher/SourceLauncherTest.java b/test/langtools/tools/javac/launcher/SourceLauncherTest.java index 06190546d49f7..a054415cfe188 100644 --- a/test/langtools/tools/javac/launcher/SourceLauncherTest.java +++ b/test/langtools/tools/javac/launcher/SourceLauncherTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,22 +26,18 @@ * @bug 8192920 8204588 8246774 8248843 8268869 8235876 * @summary Test source launcher * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.launcher * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * java.base/jdk.internal.module * @build toolbox.JavaTask toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox * @run main SourceLauncherTest */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.ModuleResolutionAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.ModuleResolutionAttribute; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -62,13 +58,13 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; -import com.sun.tools.javac.launcher.Main; +import com.sun.tools.javac.launcher.SourceLauncher; +import com.sun.tools.javac.launcher.Fault; import toolbox.JavaTask; import toolbox.JavacTask; import toolbox.Task; import toolbox.TestRunner; -import toolbox.TestRunner.Test; import toolbox.ToolBox; import static jdk.internal.module.ClassFileConstants.WARN_INCUBATING; @@ -297,12 +293,20 @@ public void testHelloWorldWithShebangJava(Path base) throws IOException { @Test public void testNoClass(Path base) throws IOException { - Files.createDirectories(base); - Path file = base.resolve("NoClass.java"); + var path = Files.createDirectories(base.resolve("p")); + Path file = path.resolve("NoClass.java"); Files.write(file, List.of("package p;")); testError(file, "", "error: no class declared in source file"); } + @Test + public void testMismatchOfPathAndPackage(Path base) throws IOException { + Files.createDirectories(base); + Path file = base.resolve("MismatchOfPathAndPackage.java"); + Files.write(file, List.of("package p;")); + testError(file, "", "error: end of path to source file does not match its package name p: " + file); + } + @Test public void testLoadClass(Path base) throws IOException { Path src1 = base.resolve("src1"); @@ -543,7 +547,7 @@ public void testNoMain(Path base) throws IOException { "error: can't find main(String[]) method in class: NoMain"); } - @Test + //@Test temporary disabled as enabled preview allows no-param main public void testMainBadParams(Path base) throws IOException { tb.writeJavaFiles(base, "class BadParams { public static void main() { } }"); @@ -551,7 +555,7 @@ public void testMainBadParams(Path base) throws IOException { "error: can't find main(String[]) method in class: BadParams"); } - @Test + //@Test temporary disabled as enabled preview allows non-public main public void testMainNotPublic(Path base) throws IOException { tb.writeJavaFiles(base, "class NotPublic { static void main(String... args) { } }"); @@ -559,12 +563,12 @@ public void testMainNotPublic(Path base) throws IOException { "error: can't find main(String[]) method in class: NotPublic"); } - @Test + //@Test temporary disabled as enabled preview allows non-static main public void testMainNotStatic(Path base) throws IOException { tb.writeJavaFiles(base, "class NotStatic { public void main(String... args) { } }"); testError(base.resolve("NotStatic.java"), "", - "error: 'main' method is not declared 'public static'"); + "error: can't find main(String[]) method in class: NotStatic"); } @Test @@ -572,7 +576,7 @@ public void testMainNotVoid(Path base) throws IOException { tb.writeJavaFiles(base, "class NotVoid { public static int main(String... args) { return 0; } }"); testError(base.resolve("NotVoid.java"), "", - "error: 'main' method is not declared with a return type of 'void'"); + "error: can't find main(String[]) method in class: NotVoid"); } @Test @@ -623,7 +627,7 @@ public void testNoRecompileWithSuggestions(Path base) throws IOException { public void testNoOptionsWarnings(Path base) throws IOException { tb.writeJavaFiles(base, "public class Main { public static void main(String... args) {}}"); String log = new JavaTask(tb) - .vmOptions("--source", "8") + .vmOptions("--source", "21") .className(base.resolve("Main.java").toString()) .run(Task.Expect.SUCCESS) .getOutput(Task.OutputKind.STDERR); @@ -720,9 +724,9 @@ public void testNoDuplicateIncubatorWarning(Path base) throws Exception { } //where: private static void markModuleAsIncubator(Path moduleInfoFile) throws Exception { - ClassModel cf = Classfile.of().parse(moduleInfoFile); + ClassModel cf = ClassFile.of().parse(moduleInfoFile); ModuleResolutionAttribute newAttr = ModuleResolutionAttribute.of(WARN_INCUBATING); - byte[] newBytes = Classfile.of().transform(cf, ClassTransform.dropping(ce -> ce instanceof Attributes) + byte[] newBytes = ClassFile.of().transform(cf, ClassTransform.dropping(ce -> ce instanceof Attributes) .andThen(ClassTransform.endHandler(classBuilder -> classBuilder.with(newAttr)))); try (OutputStream out = Files.newOutputStream(moduleInfoFile)) { out.write(newBytes); @@ -740,7 +744,7 @@ Result run(Path file, List runtimeArgs, List appArgs) { System.setOut(out); StringWriter sw = new StringWriter(); try (PrintWriter err = new PrintWriter(sw, true)) { - Main m = new Main(err); + SourceLauncher m = new SourceLauncher(err); m.run(toArray(runtimeArgs), toArray(args)); return new Result(baos.toString(), sw.toString(), null); } catch (Throwable t) { @@ -797,10 +801,10 @@ void checkFault(String name, Throwable found, String expect) { expect = expect.replace("\n", tb.lineSeparator); out.println(name + ": " + found); if (found == null) { - error("No exception thrown; expected Main.Fault"); + error("No exception thrown; expected Fault"); } else { - if (!(found instanceof Main.Fault)) { - error("Unexpected exception; expected Main.Fault"); + if (!(found instanceof Fault)) { + error("Unexpected exception; expected Fault"); } if (!(found.getMessage().equals(expect))) { error("Unexpected detail message; expected: " + expect); @@ -832,15 +836,5 @@ String[] toArray(List list) { return list.toArray(new String[list.size()]); } - class Result { - private final String stdOut; - private final String stdErr; - private final Throwable exception; - - Result(String stdOut, String stdErr, Throwable exception) { - this.stdOut = stdOut; - this.stdErr = stdErr; - this.exception = exception; - } - } + record Result(String stdOut, String stdErr, Throwable exception) {} } diff --git a/test/langtools/tools/javac/launcher/src/java b/test/langtools/tools/javac/launcher/src/java new file mode 100644 index 0000000000000..b147852380718 --- /dev/null +++ b/test/langtools/tools/javac/launcher/src/java @@ -0,0 +1 @@ +A text file named `java` to simulate https://bugs.openjdk.org/browse/JDK-8321739 diff --git a/test/langtools/tools/javac/launcher/src/CLTest.java b/test/langtools/tools/javac/launcher/src/p/q/CLTest.java similarity index 92% rename from test/langtools/tools/javac/launcher/src/CLTest.java rename to test/langtools/tools/javac/launcher/src/p/q/CLTest.java index 3e04aab0e6a95..e4517e78fc449 100644 --- a/test/langtools/tools/javac/launcher/src/CLTest.java +++ b/test/langtools/tools/javac/launcher/src/p/q/CLTest.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. + * 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 @@ -31,7 +33,7 @@ * the URLs and streams returned by the methods being tested. * * $ java \ - * --add-exports java.base/jdk.internal.classfile=ALL-UNNAMED + * --enable-preview * /path/to/CLTest.java */ package p.q; @@ -39,8 +41,8 @@ import java.io.*; import java.net.*; import java.util.*; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; public class CLTest { public static void main(String... args) throws Exception { @@ -152,7 +154,7 @@ void checkClass(String name, URL u) throws Exception { } void checkClass(String name, InputStream in) throws Exception { - ClassModel cf = Classfile.of().parse(in.readAllBytes()); + ClassModel cf = ClassFile.of().parse(in.readAllBytes()); System.err.println(" class " + cf.thisClass().asInternalName()); if (!name.equals(cf.thisClass().asInternalName() + ".class")) { error("unexpected class found: " + cf.thisClass().asInternalName()); diff --git a/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java b/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java index 45b66f25cb37e..a4f47d0ff2f47 100644 --- a/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java +++ b/test/langtools/tools/javac/lib/JavacTestingAbstractProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,7 +112,7 @@ protected void addExports(String moduleName, String... packageNames) { * corresponding platform visitor type. */ - @SupportedSourceVersion(RELEASE_22) + @SupportedSourceVersion(RELEASE_23) public static abstract class AbstractAnnotationValueVisitor extends AbstractAnnotationValueVisitor14 { /** @@ -123,7 +123,7 @@ protected AbstractAnnotationValueVisitor() { } } - @SupportedSourceVersion(RELEASE_22) + @SupportedSourceVersion(RELEASE_23) public static abstract class AbstractElementVisitor extends AbstractElementVisitor14 { /** * Constructor for concrete subclasses to call. @@ -133,7 +133,7 @@ protected AbstractElementVisitor(){ } } - @SupportedSourceVersion(RELEASE_22) + @SupportedSourceVersion(RELEASE_23) public static abstract class AbstractTypeVisitor extends AbstractTypeVisitor14 { /** * Constructor for concrete subclasses to call. @@ -143,7 +143,7 @@ protected AbstractTypeVisitor() { } } - @SupportedSourceVersion(RELEASE_22) + @SupportedSourceVersion(RELEASE_23) public static class ElementKindVisitor extends ElementKindVisitor14 { /** * Constructor for concrete subclasses; uses {@code null} for the @@ -164,7 +164,7 @@ protected ElementKindVisitor(R defaultValue) { } } - @SupportedSourceVersion(RELEASE_22) + @SupportedSourceVersion(RELEASE_23) public static class ElementScanner extends ElementScanner14 { /** * Constructor for concrete subclasses; uses {@code null} for the @@ -183,7 +183,7 @@ protected ElementScanner(R defaultValue){ } } - @SupportedSourceVersion(RELEASE_22) + @SupportedSourceVersion(RELEASE_23) public static class SimpleAnnotationValueVisitor extends SimpleAnnotationValueVisitor14 { /** * Constructor for concrete subclasses; uses {@code null} for the @@ -204,7 +204,7 @@ protected SimpleAnnotationValueVisitor(R defaultValue) { } } - @SupportedSourceVersion(RELEASE_22) + @SupportedSourceVersion(RELEASE_23) public static class SimpleElementVisitor extends SimpleElementVisitor14 { /** * Constructor for concrete subclasses; uses {@code null} for the @@ -225,7 +225,7 @@ protected SimpleElementVisitor(R defaultValue){ } } - @SupportedSourceVersion(RELEASE_22) + @SupportedSourceVersion(RELEASE_23) public static class SimpleTypeVisitor extends SimpleTypeVisitor14 { /** * Constructor for concrete subclasses; uses {@code null} for the @@ -246,7 +246,7 @@ protected SimpleTypeVisitor(R defaultValue){ } } - @SupportedSourceVersion(RELEASE_22) + @SupportedSourceVersion(RELEASE_23) public static class TypeKindVisitor extends TypeKindVisitor14 { /** * Constructor for concrete subclasses to call; uses {@code null} diff --git a/test/langtools/tools/javac/linenumbers/ConditionalLineNumberTest.java b/test/langtools/tools/javac/linenumbers/ConditionalLineNumberTest.java index a8d4c49eecd39..2727c9bdbd82e 100644 --- a/test/langtools/tools/javac/linenumbers/ConditionalLineNumberTest.java +++ b/test/langtools/tools/javac/linenumbers/ConditionalLineNumberTest.java @@ -25,15 +25,11 @@ * @test * @bug 8034091 * @summary Add LineNumberTable attributes for conditional operator (?:) split across several lines. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.io.File; import java.io.IOException; @@ -55,7 +51,7 @@ public static void main(String[] args) throws Exception { } static List findEntries() throws IOException { - ClassModel self = Classfile.of().parse(ConditionalLineNumberTest.class.getResourceAsStream("ConditionalLineNumberTest.class").readAllBytes()); + ClassModel self = ClassFile.of().parse(ConditionalLineNumberTest.class.getResourceAsStream("ConditionalLineNumberTest.class").readAllBytes()); for (MethodModel m : self.methods()) { if (m.methodName().equalsString("method")) { CodeAttribute code_attribute = m.findAttribute(Attributes.CODE).orElse(null); diff --git a/test/langtools/tools/javac/linenumbers/FinallyLineNumberTest.java b/test/langtools/tools/javac/linenumbers/FinallyLineNumberTest.java index 2e4aaa131f02c..0a6f23593c1b1 100644 --- a/test/langtools/tools/javac/linenumbers/FinallyLineNumberTest.java +++ b/test/langtools/tools/javac/linenumbers/FinallyLineNumberTest.java @@ -25,15 +25,11 @@ * @test * @bug 8134759 * @summary Add LineNumberTable attribute for return bytecodes split around finally code - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.io.IOException; import java.util.List; @@ -84,7 +80,7 @@ public static void main(String[] args) throws Exception { } static List findEntries() throws IOException { - ClassModel self = Classfile.of().parse(FinallyLineNumberTest.class.getResourceAsStream("FinallyLineNumberTest.class").readAllBytes()); + ClassModel self = ClassFile.of().parse(FinallyLineNumberTest.class.getResourceAsStream("FinallyLineNumberTest.class").readAllBytes()); for (MethodModel m : self.methods()) { if (m.methodName().equalsString("method")) { CodeAttribute code_attribute = m.findAttribute(Attributes.CODE).orElseThrow(); diff --git a/test/langtools/tools/javac/linenumbers/NestedLineNumberTest.java b/test/langtools/tools/javac/linenumbers/NestedLineNumberTest.java index 9b042c7f8abdf..481534ec2a048 100644 --- a/test/langtools/tools/javac/linenumbers/NestedLineNumberTest.java +++ b/test/langtools/tools/javac/linenumbers/NestedLineNumberTest.java @@ -2,16 +2,12 @@ * @test /nodynamiccopyright/ * @bug 8061778 * @summary Wrong LineNumberTable for default constructors - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ import java.util.List; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.io.IOException; @@ -25,13 +21,13 @@ public static void main(String[] args) throws Exception { } int line = lines.get(0).lineNumber(); - if (line != 54) { - error(String.format("LineNumberTable contains wrong line number - expected %d, found %d", 54, line)); + if (line != 50) { + error(String.format("LineNumberTable contains wrong line number - expected %d, found %d", 50, line)); } } static List findEntries() throws IOException { - ClassModel self = Classfile.of().parse(NestedLineNumberTest.Test.class.getResourceAsStream("NestedLineNumberTest$Test.class").readAllBytes()); + ClassModel self = ClassFile.of().parse(NestedLineNumberTest.Test.class.getResourceAsStream("NestedLineNumberTest$Test.class").readAllBytes()); for (MethodModel m : self.methods()) { if ("".equals(m.methodName().stringValue())) { CodeAttribute code_attribute = m.findAttribute(Attributes.CODE).orElseThrow(); diff --git a/test/langtools/tools/javac/linenumbers/NullCheckLineNumberTest.java b/test/langtools/tools/javac/linenumbers/NullCheckLineNumberTest.java index 018641747fdf1..91c562b2360e9 100644 --- a/test/langtools/tools/javac/linenumbers/NullCheckLineNumberTest.java +++ b/test/langtools/tools/javac/linenumbers/NullCheckLineNumberTest.java @@ -2,15 +2,11 @@ * @test /nodynamiccopyright/ * @bug 8172880 * @summary Wrong LineNumberTable for synthetic null checks - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.io.IOException; import java.util.AbstractMap.SimpleEntry; @@ -40,13 +36,13 @@ public Test() { public static void main(String[] args) throws Exception { List actualEntries = findEntries(); List expectedEntries = List.of( - new SimpleEntry<>(29, 0), - new SimpleEntry<>(30, 4), - new SimpleEntry<>(32, 9), - new SimpleEntry<>(33, 16), - new SimpleEntry<>(34, 32), - new SimpleEntry<>(35, 46), - new SimpleEntry<>(36, 52) + new SimpleEntry<>(25, 0), + new SimpleEntry<>(26, 4), + new SimpleEntry<>(28, 9), + new SimpleEntry<>(29, 16), + new SimpleEntry<>(30, 32), + new SimpleEntry<>(31, 46), + new SimpleEntry<>(32, 52) ); if (!Objects.equals(actualEntries, expectedEntries)) { error(String.format("Unexpected LineNumberTable: %s", actualEntries.toString())); @@ -57,14 +53,14 @@ public static void main(String[] args) throws Exception { } catch (NullPointerException npe) { if (Arrays.stream(npe.getStackTrace()) .noneMatch(se -> se.getFileName().contains("NullCheckLineNumberTest") && - se.getLineNumber() == 34)) { - throw new AssertionError("Should go through line 34!"); + se.getLineNumber() == 30)) { + throw new AssertionError("Should go through line 30!"); } } } static List findEntries() throws IOException { - ClassModel self = Classfile.of().parse(Objects.requireNonNull(Test.class.getResourceAsStream("NullCheckLineNumberTest$Test.class")).readAllBytes()); + ClassModel self = ClassFile.of().parse(Objects.requireNonNull(Test.class.getResourceAsStream("NullCheckLineNumberTest$Test.class")).readAllBytes()); for (MethodModel m : self.methods()) { if ("".equals(m.methodName().stringValue())) { CodeAttribute code_attribute = m.findAttribute(Attributes.CODE).orElseThrow(); diff --git a/test/langtools/tools/javac/meth/TestCP.java b/test/langtools/tools/javac/meth/TestCP.java index 3f942f5b42dee..31a5bd1762f3c 100644 --- a/test/langtools/tools/javac/meth/TestCP.java +++ b/test/langtools/tools/javac/meth/TestCP.java @@ -25,19 +25,15 @@ * @test * @bug 6991980 * @summary polymorphic signature calls don't share the same CP entries - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @run main TestCP */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.MemberRefEntry; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.MemberRefEntry; +import java.lang.classfile.instruction.InvokeInstruction; import java.lang.invoke.*; import java.io.*; @@ -128,7 +124,7 @@ void verifySigPolyInvokeVirtual(File f, String psType) { System.err.println("verify: " + f); try { int count = 0; - ClassModel cf = Classfile.of().parse(f.toPath()); + ClassModel cf = ClassFile.of().parse(f.toPath()); MethodModel testMethod = null; for (MethodModel m : cf.methods()) { if (m.methodName().equalsString(TEST_METHOD_NAME)) { diff --git a/test/langtools/tools/javac/modules/AnnotationsOnModules.java b/test/langtools/tools/javac/modules/AnnotationsOnModules.java index a797ae8d44e72..59b48fd49549c 100644 --- a/test/langtools/tools/javac/modules/AnnotationsOnModules.java +++ b/test/langtools/tools/javac/modules/AnnotationsOnModules.java @@ -26,13 +26,9 @@ * @bug 8159602 8170549 8171255 8171322 8254023 * @summary Test annotations on module declaration. * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask ModuleTestBase * @run main AnnotationsOnModules @@ -56,9 +52,9 @@ import javax.lang.model.element.ModuleElement; import javax.lang.model.element.TypeElement; -import jdk.internal.classfile.*; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.ClassFile; +import java.lang.classfile.attribute.*; import toolbox.JavacTask; import toolbox.Task; import toolbox.Task.OutputKind; @@ -89,7 +85,7 @@ public void testSimpleAnnotation(Path base) throws Exception { .run() .writeAll(); - ClassModel cf = Classfile.of().parse(modulePath.resolve("m1x").resolve("module-info.class")); + ClassModel cf = ClassFile.of().parse(modulePath.resolve("m1x").resolve("module-info.class")); RuntimeVisibleAnnotationsAttribute annotations = cf.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).orElse(null); if (annotations == null || annotations.annotations().size() != 1) { @@ -143,7 +139,7 @@ public void testSimpleJavadocDeprecationTag(Path base) throws Exception { throw new AssertionError("Output is not empty. Expected no output and no warnings."); } - ClassModel cf = Classfile.of().parse(modulePath.resolve("A").resolve("module-info.class")); + ClassModel cf = ClassFile.of().parse(modulePath.resolve("A").resolve("module-info.class")); RuntimeVisibleAnnotationsAttribute annotations = cf.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).orElse(null); if (annotations != null && annotations.annotations().size() > 0) { @@ -194,7 +190,7 @@ public void testEnhancedDeprecatedAnnotation(Path base) throws Exception { throw new AssertionError("Expected output not found. Expected: " + expected); } - ClassModel cf = Classfile.of().parse(modulePath.resolve("A").resolve("module-info.class")); + ClassModel cf = ClassFile.of().parse(modulePath.resolve("A").resolve("module-info.class")); RuntimeVisibleAnnotationsAttribute annotations = cf.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).orElse(null); if (annotations == null ) { @@ -317,7 +313,7 @@ public void testAnnotationWithImport(Path base) throws Exception { .run() .writeAll(); - ClassModel cf = Classfile.of().parse(modulePath.resolve("m1x").resolve("module-info.class")); + ClassModel cf = ClassFile.of().parse(modulePath.resolve("m1x").resolve("module-info.class")); RuntimeInvisibleAnnotationsAttribute annotations = cf.findAttribute(Attributes.RUNTIME_INVISIBLE_ANNOTATIONS).orElse(null); if (annotations == null || annotations.annotations().size() != 1) { @@ -359,7 +355,7 @@ public void testAnnotationWithImportFromAnotherModule(Path base) throws Exceptio .run() .writeAll(); - ClassModel cf = Classfile.of().parse(modulePath.resolve("B").resolve("module-info.class")); + ClassModel cf = ClassFile.of().parse(modulePath.resolve("B").resolve("module-info.class")); RuntimeInvisibleAnnotationsAttribute annotations = cf.findAttribute(Attributes.RUNTIME_INVISIBLE_ANNOTATIONS).orElse(null); if (annotations == null ) { @@ -434,7 +430,7 @@ public void testAnnotationWithoutTarget(Path base) throws Exception { .run() .writeAll(); - ClassModel cf = Classfile.of().parse(classes.resolve("m1x").resolve("module-info.class")); + ClassModel cf = ClassFile.of().parse(classes.resolve("m1x").resolve("module-info.class")); RuntimeInvisibleAnnotationsAttribute invisibleAnnotations = cf.findAttribute(Attributes.RUNTIME_INVISIBLE_ANNOTATIONS).orElse(null); if (invisibleAnnotations == null) { diff --git a/test/langtools/tools/javac/modules/IncubatingTest.java b/test/langtools/tools/javac/modules/IncubatingTest.java index 70df2bbe05ae2..776023db5e521 100644 --- a/test/langtools/tools/javac/modules/IncubatingTest.java +++ b/test/langtools/tools/javac/modules/IncubatingTest.java @@ -26,13 +26,9 @@ * @bug 8171177 8187591 * @summary Verify that ModuleResolution attribute flags are honored. * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * java.base/jdk.internal.module * jdk.jdeps/com.sun.tools.javap @@ -53,9 +49,9 @@ import java.util.List; import java.util.Map; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.ModuleResolutionAttribute; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.ModuleResolutionAttribute; +import java.lang.classfile.constantpool.*; import toolbox.JavacTask; import toolbox.Task; import toolbox.Task.Expect; @@ -268,9 +264,9 @@ private void copyJavaBase(Path targetDir) throws IOException { } private void addModuleResolutionAttribute(Path classfile, int resolution_flags) throws Exception { - ClassModel cm = Classfile.of().parse(classfile); + ClassModel cm = ClassFile.of().parse(classfile); ModuleResolutionAttribute modRAttr = ModuleResolutionAttribute.of(resolution_flags); - byte[] newBytes = Classfile.of().transform(cm, ClassTransform.dropping(ce -> ce instanceof ModuleResolutionAttribute). + byte[] newBytes = ClassFile.of().transform(cm, ClassTransform.dropping(ce -> ce instanceof ModuleResolutionAttribute). andThen(ClassTransform.endHandler(classBuilder -> classBuilder.with(modRAttr)))); try (OutputStream out = Files.newOutputStream(classfile)) { out.write(newBytes); diff --git a/test/langtools/tools/javac/modules/JavaBaseTest.java b/test/langtools/tools/javac/modules/JavaBaseTest.java index 110c796525bf3..64f914e5d2fff 100644 --- a/test/langtools/tools/javac/modules/JavaBaseTest.java +++ b/test/langtools/tools/javac/modules/JavaBaseTest.java @@ -26,16 +26,12 @@ * @bug 8193125 8196623 * @summary test modifiers with java.base * @library /tools/lib + * @enablePreview * @modules * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.jvm * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.platform - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main JavaBaseTest @@ -48,8 +44,8 @@ import java.util.*; import java.util.stream.StreamSupport; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import com.sun.tools.javac.jvm.Target; import com.sun.tools.javac.platform.JDKPlatformProvider; @@ -208,7 +204,7 @@ void createClass(Path base, List mods, String target) throws Exception { jct.files(tb.findJavaFiles(src1)) .run(Task.Expect.SUCCESS); - ClassModel cm1 = Classfile.of().parse(modules1.resolve("module-info.class")); + ClassModel cm1 = ClassFile.of().parse(modules1.resolve("module-info.class")); ModuleAttribute modAttr1 = cm1.findAttribute(Attributes.MODULE).orElseThrow(); List requires = Arrays.asList(new ModuleRequireInfo[modAttr1.requires().size()]); @@ -219,8 +215,8 @@ void createClass(Path base, List mods, String target) throws Exception { if (e1.requires().name().equalsString("java.base")) { for (String mod : mods) { switch (mod) { - case "static" -> flags |= Classfile.ACC_STATIC_PHASE; - case "transitive" -> flags |= Classfile.ACC_TRANSITIVE; + case "static" -> flags |= ClassFile.ACC_STATIC_PHASE; + case "transitive" -> flags |= ClassFile.ACC_TRANSITIVE; } } e2 = ModuleRequireInfo.of(e1.requires(), flags, e1.requiresVersion().orElse(null)); @@ -241,7 +237,7 @@ void createClass(Path base, List mods, String target) throws Exception { modAttr1.provides()); Path modInfo = base.resolve("test-modules").resolve("module-info.class"); Files.createDirectories(modInfo.getParent()); - byte[] newBytes = Classfile.of().transform(cm1, ClassTransform.dropping(ce -> ce instanceof ModuleAttribute). + byte[] newBytes = ClassFile.of().transform(cm1, ClassTransform.dropping(ce -> ce instanceof ModuleAttribute). andThen(ClassTransform.endHandler(classBuilder -> classBuilder.with(modAttr2)))); try (OutputStream out = Files.newOutputStream(modInfo)) { out.write(newBytes); diff --git a/test/langtools/tools/javac/modules/ModuleVersion.java b/test/langtools/tools/javac/modules/ModuleVersion.java index 6c6d04b15fc11..d6b514eee318c 100644 --- a/test/langtools/tools/javac/modules/ModuleVersion.java +++ b/test/langtools/tools/javac/modules/ModuleVersion.java @@ -25,13 +25,9 @@ * @test * @summary simple tests of module uses * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase * @run main ModuleVersion @@ -41,8 +37,8 @@ import java.nio.file.Files; import java.nio.file.Path; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.ModuleAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.ModuleAttribute; import toolbox.JavacTask; import toolbox.Task.Expect; import toolbox.Task.OutputKind; @@ -116,7 +112,7 @@ public void testMultipleModuleVersions(Path base) throws Exception { } private void checkModuleVersion(Path classfile, String version) throws IOException { - ClassModel cm = Classfile.of().parse(classfile); + ClassModel cm = ClassFile.of().parse(classfile); ModuleAttribute moduleAttribute = cm.findAttribute(Attributes.MODULE).orElse(null); diff --git a/test/langtools/tools/javac/modules/OpenModulesTest.java b/test/langtools/tools/javac/modules/OpenModulesTest.java index 319aa24f3874f..4523b72654802 100644 --- a/test/langtools/tools/javac/modules/OpenModulesTest.java +++ b/test/langtools/tools/javac/modules/OpenModulesTest.java @@ -25,13 +25,9 @@ * @test * @summary tests for multi-module mode compilation * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * jdk.jdeps/com.sun.tools.javap * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase @@ -47,8 +43,8 @@ import java.util.Map; import java.util.Objects; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.ModuleAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.ModuleAttribute; import toolbox.JavacTask; import toolbox.JavapTask; import toolbox.Task; @@ -236,10 +232,10 @@ public void testNonZeroOpensInOpen(Path base) throws Exception { .writeAll(); Path miClass = m1Classes.resolve("module-info.class"); - ClassModel cm = Classfile.of().parse(miClass); + ClassModel cm = ClassFile.of().parse(miClass); ModuleAttribute module = cm.findAttribute(Attributes.MODULE).orElseThrow(); ModuleAttribute newModule = ModuleAttribute.of(module.moduleName(), - module.moduleFlagsMask() | Classfile.ACC_OPEN, + module.moduleFlagsMask() | ClassFile.ACC_OPEN, module.moduleVersion().orElse(null), module.requires(), module.exports(), @@ -247,7 +243,7 @@ public void testNonZeroOpensInOpen(Path base) throws Exception { module.uses(), module.provides()); - byte[] newBytes = Classfile.of().transform(cm, ClassTransform.dropping(ce -> ce instanceof ModuleAttribute). + byte[] newBytes = ClassFile.of().transform(cm, ClassTransform.dropping(ce -> ce instanceof ModuleAttribute). andThen(ClassTransform.endHandler(classBuilder -> classBuilder.with(newModule)))); try (OutputStream out = Files.newOutputStream(miClass)) { out.write(newBytes); diff --git a/test/langtools/tools/javac/multicatch/7005371/T7005371.java b/test/langtools/tools/javac/multicatch/7005371/T7005371.java index 9a4cb55a46e49..bf83cd26089b1 100644 --- a/test/langtools/tools/javac/multicatch/7005371/T7005371.java +++ b/test/langtools/tools/javac/multicatch/7005371/T7005371.java @@ -25,19 +25,15 @@ * @test * @bug 7005371 * @summary Multicatch: assertion error while generating LocalVariableTypeTable attribute - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g SubTest.java * @run main T7005371 */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.attribute.LocalVariableTypeTableAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.attribute.LocalVariableTypeTableAttribute; import java.io.*; @@ -63,7 +59,7 @@ public void run() throws Exception { void verifyLocalVariableTypeTableAttr(File f) { System.err.println("verify: " + f); try { - ClassModel cf = Classfile.of().parse(f.toPath()); + ClassModel cf = ClassFile.of().parse(f.toPath()); MethodModel testMethod = null; for (MethodModel m : cf.methods()) { if (m.methodName().equalsString(TEST_METHOD_NAME)) { diff --git a/test/langtools/tools/javac/multicatch/Pos05.java b/test/langtools/tools/javac/multicatch/Pos05.java index baeb17918bb46..1dade792178ba 100644 --- a/test/langtools/tools/javac/multicatch/Pos05.java +++ b/test/langtools/tools/javac/multicatch/Pos05.java @@ -25,18 +25,14 @@ * @test * @bug 6943289 * @summary Project Coin: Improved Exception Handling for Java (aka 'multicatch') - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @run main Pos05 */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.instruction.ExceptionCatch; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.instruction.ExceptionCatch; import java.io.*; public class Pos05 { @@ -83,7 +79,7 @@ void verifyMulticatchExceptionRanges(File f) { System.err.println("verify: " + f); try { int count = 0; - ClassModel cf = Classfile.of().parse(f.toPath()); + ClassModel cf = ClassFile.of().parse(f.toPath()); MethodModel testMethod = null; for (MethodModel m : cf.methods()) { if (m.methodName().equalsString(TEST_METHOD_NAME)) { diff --git a/test/langtools/tools/javac/options/BCPOrSystemNotSpecified.java b/test/langtools/tools/javac/options/BCPOrSystemNotSpecified.java index a4dea63ca364d..bfe1d9d11fd0f 100644 --- a/test/langtools/tools/javac/options/BCPOrSystemNotSpecified.java +++ b/test/langtools/tools/javac/options/BCPOrSystemNotSpecified.java @@ -78,7 +78,7 @@ public void testSource8(Path base) throws IOException { List log; List expected = Arrays.asList( - "- compiler.warn.source.no.bootclasspath: 8", + "- compiler.warn.source.no.bootclasspath: 8, (compiler.misc.source.no.bootclasspath: 8)", "- compiler.warn.option.obsolete.source: 8", "- compiler.warn.option.obsolete.suppression", "3 warnings" @@ -125,7 +125,7 @@ public void testSource9(Path base) throws IOException { List log; List expected = Arrays.asList( - "- compiler.warn.source.no.system.modules.path: 9", + "- compiler.warn.source.no.system.modules.path: 9, (compiler.misc.source.no.system.modules.path: 9)", "1 warning" ); diff --git a/test/langtools/tools/javac/options/T6900037.out b/test/langtools/tools/javac/options/T6900037.out index dd5352edc7c46..3e610c371c957 100644 --- a/test/langtools/tools/javac/options/T6900037.out +++ b/test/langtools/tools/javac/options/T6900037.out @@ -1,4 +1,4 @@ -- compiler.warn.source.no.bootclasspath: 8 +- compiler.warn.source.no.bootclasspath: 8, (compiler.misc.source.no.bootclasspath: 8) - compiler.warn.option.obsolete.source: 8 - compiler.warn.option.obsolete.suppression - compiler.err.warnings.and.werror diff --git a/test/langtools/tools/javac/options/smokeTests/OptionSmokeTest.java b/test/langtools/tools/javac/options/smokeTests/OptionSmokeTest.java index f128bf14f7fba..0fae2fab1f0ad 100644 --- a/test/langtools/tools/javac/options/smokeTests/OptionSmokeTest.java +++ b/test/langtools/tools/javac/options/smokeTests/OptionSmokeTest.java @@ -139,13 +139,13 @@ public void sourceAndModuleSourceCantBeTogether(Path base) throws Exception { @Test public void sourceAndTargetMismatch(Path base) throws Exception { - doTest(base, String.format("warning: source release %s requires target release %s", Source.DEFAULT.name, Source.DEFAULT.name), + doTest(base, String.format("error: specified target release %s is too old for the specified source release %s", Source.MIN.name, Source.DEFAULT.name), String.format("-source %s -target %s", Source.DEFAULT.name, Source.MIN.name)); } @Test public void targetConflictsWithDefaultSource(Path base) throws Exception { - doTest(base, String.format("warning: target release %s conflicts with default source release %s", Source.MIN.name, Source.DEFAULT.name), + doTest(base, String.format("error: specified target release %s is too old for the default source release %s", Source.MIN.name, Source.DEFAULT.name), String.format("-target %s", Source.MIN.name)); } diff --git a/test/langtools/tools/javac/parser/JavacParserTest.java b/test/langtools/tools/javac/parser/JavacParserTest.java index 14f0c506cd1a0..f9ccb39c05e1d 100644 --- a/test/langtools/tools/javac/parser/JavacParserTest.java +++ b/test/langtools/tools/javac/parser/JavacParserTest.java @@ -2472,7 +2472,7 @@ void main() { result, """ \n\ - /*synthetic*/ final class Test { + final class Test { \n\ void main() { (ERROR); diff --git a/test/langtools/tools/javac/patterns/Annotations.java b/test/langtools/tools/javac/patterns/Annotations.java index d9ae2b182477e..f14ab3fb9708f 100644 --- a/test/langtools/tools/javac/patterns/Annotations.java +++ b/test/langtools/tools/javac/patterns/Annotations.java @@ -26,17 +26,13 @@ * @bug 8256266 8281238 * @summary Verify annotations work correctly on binding variables * @library /tools/javac/lib + * @enablePreview * @modules java.compiler * jdk.compiler - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build JavacTestingAbstractProcessor * @compile Annotations.java - * @compile -processor Annotations -proc:only Annotations.java + * @compile -J--enable-preview -processor Annotations -proc:only Annotations.java * @run main Annotations */ @@ -54,9 +50,9 @@ import com.sun.source.tree.VariableTree; import com.sun.source.util.TreePathScanner; import com.sun.source.util.Trees; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute; import java.io.InputStream; public class Annotations extends JavacTestingAbstractProcessor { @@ -68,7 +64,7 @@ void run() throws Exception { InputStream annotationsClass = Annotations.class.getResourceAsStream("Annotations.class"); assert annotationsClass != null; - ClassModel cf = Classfile.of().parse(annotationsClass.readAllBytes()); + ClassModel cf = ClassFile.of().parse(annotationsClass.readAllBytes()); for (MethodModel m : cf.methods()) { if (m.methodName().equalsString("test")) { CodeAttribute codeAttr = m.findAttribute(Attributes.CODE).orElseThrow(); diff --git a/test/langtools/tools/javac/patterns/LocalVariableTable.java b/test/langtools/tools/javac/patterns/LocalVariableTable.java index af1a2baa1f7dc..9fa29b09065db 100644 --- a/test/langtools/tools/javac/patterns/LocalVariableTable.java +++ b/test/langtools/tools/javac/patterns/LocalVariableTable.java @@ -25,18 +25,14 @@ * @test * @bug 8231827 * @summary Ensure the LV table entries are generated for bindings - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile -g LocalVariableTable.java * @run main LocalVariableTable */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.io.*; import java.lang.annotation.*; import java.util.*; @@ -83,7 +79,7 @@ void check(Class c) throws Exception { return; } - ClassModel cf = Classfile.of().parse(Objects.requireNonNull(getClass().getResource(c.getName() + ".class")) + ClassModel cf = ClassFile.of().parse(Objects.requireNonNull(getClass().getResource(c.getName() + ".class")) .openStream().readAllBytes()); MethodModel m = getMethodByName(cf, c.getSimpleName().contains("Lambda") ? "lambda$" : "test"); if (m == null) { diff --git a/test/langtools/tools/javac/patterns/MatchExceptionTest.java b/test/langtools/tools/javac/patterns/MatchExceptionTest.java index 25b4f5f03cb9e..b54d0492bdf4f 100644 --- a/test/langtools/tools/javac/patterns/MatchExceptionTest.java +++ b/test/langtools/tools/javac/patterns/MatchExceptionTest.java @@ -26,13 +26,9 @@ * @bug 8297118 * @summary Verify javac uses MatchException or IncompatibleClassChangeError for exhaustive switches * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main MatchExceptionTest @@ -40,11 +36,11 @@ import java.nio.file.Path; -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.ClassEntry; -import jdk.internal.classfile.constantpool.ConstantPool; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.ClassEntry; +import java.lang.classfile.constantpool.ConstantPool; +import java.lang.classfile.constantpool.PoolEntry; import java.util.Arrays; -import jdk.internal.classfile.constantpool.PoolEntry; import toolbox.JavacTask; import toolbox.TestRunner; @@ -116,7 +112,7 @@ record Source(String source, boolean needs21) {} .outdir(curPath) .run(); - cf = Classfile.of().parse(curPath.resolve("Test.class")); + cf = ClassFile.of().parse(curPath.resolve("Test.class")); boolean incompatibleClassChangeErrror = false; boolean matchException = false; for (PoolEntry pe : cf.constantPool()) { diff --git a/test/langtools/tools/javac/patterns/NestedPatternVariablesBytecode.java b/test/langtools/tools/javac/patterns/NestedPatternVariablesBytecode.java index 05a417ad33568..3759676e2c38c 100644 --- a/test/langtools/tools/javac/patterns/NestedPatternVariablesBytecode.java +++ b/test/langtools/tools/javac/patterns/NestedPatternVariablesBytecode.java @@ -26,13 +26,9 @@ * @bug 8268748 * @summary Javac generates error opcodes when using nest pattern variables * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main NestedPatternVariablesBytecode @@ -43,8 +39,8 @@ import java.util.List; import java.util.stream.StreamSupport; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; import toolbox.JavacTask; import toolbox.TestRunner; @@ -84,7 +80,7 @@ String test(Object o) { .outdir(curPath) .run(); - cf = Classfile.of().parse(curPath.resolve("NestedPatterVariablesTest.class")); + cf = ClassFile.of().parse(curPath.resolve("NestedPatterVariablesTest.class")); MethodModel testMethod = cf.methods().stream() .filter(this::isTestMethod) .findAny() diff --git a/test/langtools/tools/javac/patterns/NoUnnecessaryCast.java b/test/langtools/tools/javac/patterns/NoUnnecessaryCast.java index 1b058e03db19a..b7e7df089a574 100644 --- a/test/langtools/tools/javac/patterns/NoUnnecessaryCast.java +++ b/test/langtools/tools/javac/patterns/NoUnnecessaryCast.java @@ -26,19 +26,15 @@ * @bug 8237528 * @summary Verify there are no unnecessary checkcasts and conditions generated * for the pattern matching in instanceof. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * @compile NoUnnecessaryCast.java * @run main NoUnnecessaryCast */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.ConstantPool; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.ConstantPool; import java.io.File; import java.io.IOException; @@ -54,7 +50,7 @@ public static void main(String[] args) throws IOException { } void checkClassFile(File file) throws IOException { - ClassModel classFile = Classfile.of().parse(file.toPath()); + ClassModel classFile = ClassFile.of().parse(file.toPath()); MethodModel method = classFile.methods().stream() .filter(m -> getName(m).equals("test")) diff --git a/test/langtools/tools/javac/patterns/T8312560.java b/test/langtools/tools/javac/patterns/T8312560.java new file mode 100644 index 0000000000000..fda3d79813287 --- /dev/null +++ b/test/langtools/tools/javac/patterns/T8312560.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +/* + * @test + * @bug 8312560 + * @summary Annotation on Decomposed Record Component in Enhanced For Loop Fails Compilation + * @compile T8312560.java + */ +public class T8312560 { + void m(Object o) { + if (o instanceof R(@A var x)) {} + } + + @interface A { + } + + record R(Integer x) { + } +} diff --git a/test/langtools/tools/javac/patterns/T8317300.out b/test/langtools/tools/javac/patterns/T8317300.out index f28fd7467d80a..6889c873db560 100644 --- a/test/langtools/tools/javac/patterns/T8317300.out +++ b/test/langtools/tools/javac/patterns/T8317300.out @@ -1,5 +1,3 @@ T8317300.java:13:18: compiler.err.mod.not.allowed.here: final -T8317300.java:20:22: compiler.err.illegal.start.of.expr -T8317300.java:20:31: compiler.err.expected: token.identifier -T8317300.java:20:37: compiler.err.expected: ';' -4 errors +T8317300.java:20:22: compiler.err.mod.not.allowed.here: final +2 errors diff --git a/test/langtools/tools/javac/patterns/T8320145.java b/test/langtools/tools/javac/patterns/T8320145.java new file mode 100644 index 0000000000000..67c851a82aa84 --- /dev/null +++ b/test/langtools/tools/javac/patterns/T8320145.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8320145 + * @summary Compiler should accept final variable in Record Pattern + * @compile T8320145.java + */ +public class T8320145 { + record ARecord(String aComponent) {} + record BRecord(ARecord aComponent) {} + record CRecord(ARecord aComponent1, ARecord aComponent2) {} + + public String match(Object o) { + return switch(o) { + case ARecord(final String s) -> s; + case BRecord(ARecord(final String s)) -> s; + case CRecord(ARecord(String s), ARecord(final String s2)) -> s; + default -> "No match"; + }; + } +} diff --git a/test/langtools/tools/javac/platform/CanHandleClassFilesTest.java b/test/langtools/tools/javac/platform/CanHandleClassFilesTest.java index 0a87f67bbe52f..a8d4747babb2d 100644 --- a/test/langtools/tools/javac/platform/CanHandleClassFilesTest.java +++ b/test/langtools/tools/javac/platform/CanHandleClassFilesTest.java @@ -110,9 +110,11 @@ protected Class findClass(String name) throws ClassNotFoundException { var main = createSymbolsClass.getMethod("main", String[].class); var symbols = targetDir.resolve("symbols"); var modules = targetDir.resolve("modules"); + var modulesList = targetDir.resolve("modules-list"); try (Writer w = Files.newBufferedWriter(symbols)) {} Files.createDirectories(modules); + try (Writer w = Files.newBufferedWriter(modulesList)) {} main.invoke(null, (Object) new String[] {"build-description-incremental", @@ -127,7 +129,8 @@ protected Class findClass(String name) throws ClassNotFoundException { Long.toString(System.currentTimeMillis() / 1000), "" + SourceVersion.latest().ordinal(), "", - modules.toAbsolutePath().toString()}); + modules.toAbsolutePath().toString(), + modulesList.toAbsolutePath().toString()}); } } diff --git a/test/langtools/tools/javac/platform/ModuleVersionTest.java b/test/langtools/tools/javac/platform/ModuleVersionTest.java index 693daef58f900..1b01fc397e84f 100644 --- a/test/langtools/tools/javac/platform/ModuleVersionTest.java +++ b/test/langtools/tools/javac/platform/ModuleVersionTest.java @@ -26,10 +26,8 @@ * @bug 8318913 * @summary Verify correct module versions are recorded when --release is used. * @library /tools/lib + * @enablePreview * @modules - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.platform @@ -43,11 +41,11 @@ import java.nio.file.Paths; import java.util.regex.Matcher; import java.util.regex.Pattern; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.attribute.ModuleAttribute; -import jdk.internal.classfile.attribute.ModuleRequireInfo; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.attribute.ModuleAttribute; +import java.lang.classfile.attribute.ModuleRequireInfo; import org.junit.Test; @@ -102,7 +100,7 @@ public class Test { .writeAll(); Path moduleInfo = classes.resolve("module-info.class"); - ClassModel clazz = Classfile.of().parse(moduleInfo); + ClassModel clazz = ClassFile.of().parse(moduleInfo); assertTrue(clazz.isModuleInfo()); ModuleAttribute module = clazz.findAttribute(Attributes.MODULE).get(); diff --git a/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTestImpl.java b/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTestImpl.java index 17e9e1703abe7..5037561df109f 100644 --- a/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTestImpl.java +++ b/test/langtools/tools/javac/platform/createsymbols/CreateSymbolsTestImpl.java @@ -752,13 +752,15 @@ void doTestComplex(String printClass, new CreateSymbols().createBaseLine(versions, acceptAll, ctSym, new String[0]); Path symbolsDesc = ctSym.resolve("symbols"); Path modules = ctSym.resolve("modules"); + Path modulesList = ctSym.resolve("modules-list"); Files.createDirectories(modules); + try (Writer w = Files.newBufferedWriter(modulesList)) {} Path classesZip = output.resolve("classes.zip"); Path classesDir = output.resolve("classes"); - new CreateSymbols().createSymbols(null, symbolsDesc.toAbsolutePath().toString(), classesZip.toAbsolutePath().toString(), 0, "9", "", modules.toString()); + new CreateSymbols().createSymbols(null, symbolsDesc.toAbsolutePath().toString(), classesZip.toAbsolutePath().toString(), 0, "9", "", modules.toString(), modulesList.toString()); try (JarFile jf = new JarFile(classesZip.toFile())) { Enumeration en = jf.entries(); @@ -835,7 +837,7 @@ void doTestComplex(String printClass, void testExtendsInternalData1() throws Exception { doTestData(""" module name m - header exports api,nonapi[java.base] requires name\\u0020;java.base\\u0020;flags\\u0020;8000\\u0020;version\\u0020;0 flags 8000 + header exports api extraModulePackages nonapi requires name\\u0020;java.base\\u0020;flags\\u0020;8000\\u0020;version\\u0020;0 flags 8000 class name api/Ann header extends java/lang/Object implements java/lang/annotation/Annotation flags 2601 @@ -1038,15 +1040,12 @@ protected boolean includeEffectiveAccess(ClassList classes, ClassDescription cla }.createBaseLine(versions, acceptAll, descDest, new String[0]); Path symbolsDesc = descDest.resolve("symbols"); Path modules = descDest.resolve("modules"); + Path modulesList = descDest.resolve("modules-list"); Files.createDirectories(modules); + try (Writer w = Files.newBufferedWriter(modulesList)) {} - try { - new CreateSymbols().createSymbols(null, symbolsDesc.toAbsolutePath().toString(), classDest, 0, "8", "", modules.toString()); - } catch (Throwable t) { - t.printStackTrace(); - throw t; - } + new CreateSymbols().createSymbols(null, symbolsDesc.toAbsolutePath().toString(), classDest, 0, "8", "", modules.toString(), modulesList.toString()); } void compileAndPack(Path output, Path outputFile, String... code) throws Exception { diff --git a/test/langtools/tools/javac/preview/PreviewAutoSuppress.java b/test/langtools/tools/javac/preview/PreviewAutoSuppress.java index 3a053f9b3349b..d77bd3b22dab0 100644 --- a/test/langtools/tools/javac/preview/PreviewAutoSuppress.java +++ b/test/langtools/tools/javac/preview/PreviewAutoSuppress.java @@ -25,19 +25,15 @@ * @test * @bug 8250768 * @library /tools/lib + * @enablePreview * @modules * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main PreviewAutoSuppress */ -import jdk.internal.classfile.*; +import java.lang.classfile.*; import java.io.InputStream; import java.nio.file.Files; import toolbox.JavacTask; @@ -211,7 +207,7 @@ public static class C extends Outer {} private void checkPreviewClassfile(Path p, boolean preview) throws Exception { try (InputStream in = Files.newInputStream(p)) { - ClassModel cf = Classfile.of().parse(in.readAllBytes()); + ClassModel cf = ClassFile.of().parse(in.readAllBytes()); if (preview && cf.minorVersion() != 65535) { throw new IllegalStateException("Expected preview class, but got: " + cf.minorVersion()); } else if (!preview && cf.minorVersion() != 0) { diff --git a/test/langtools/tools/javac/preview/PreviewErrors.java b/test/langtools/tools/javac/preview/PreviewErrors.java index 2dd84cacdf3df..8c76423c9d248 100644 --- a/test/langtools/tools/javac/preview/PreviewErrors.java +++ b/test/langtools/tools/javac/preview/PreviewErrors.java @@ -26,17 +26,13 @@ * @bug 8226585 8250768 * @summary Verify behavior w.r.t. preview feature API errors and warnings * @library /tools/lib /tools/javac/lib + * @enablePreview * @modules * java.base/jdk.internal.javac * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @build combo.ComboTestHelper @@ -60,8 +56,8 @@ import java.util.stream.Collectors; import javax.tools.Diagnostic; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; import java.io.FileWriter; import java.io.UncheckedIOException; import java.io.Writer; @@ -411,7 +407,7 @@ public void test(Object o) { throw new IllegalStateException("Cannot find Test.class"); } try (InputStream input = testClass.openInputStream()) { - cf = Classfile.of().parse(input.readAllBytes()); + cf = ClassFile.of().parse(input.readAllBytes()); } } catch (IOException ex) { throw new IllegalStateException(ex); diff --git a/test/langtools/tools/javac/preview/PreviewTest.java b/test/langtools/tools/javac/preview/PreviewTest.java index 7bf15c41c0b1f..24cb3d57ddee7 100644 --- a/test/langtools/tools/javac/preview/PreviewTest.java +++ b/test/langtools/tools/javac/preview/PreviewTest.java @@ -25,20 +25,16 @@ * @test * @bug 8282823 * @library /tools/lib + * @enablePreview * @modules * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main PreviewTest */ -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; import java.io.InputStream; import java.nio.file.Files; import toolbox.JavacTask; @@ -481,7 +477,7 @@ private int verifyPreviewClassfiles(Path directory) throws Exception { private void checkPreviewClassfile(Path p, boolean preview) throws Exception { try (InputStream in = Files.newInputStream(p)) { - ClassModel cf = Classfile.of().parse(in.readAllBytes()); + ClassModel cf = ClassFile.of().parse(in.readAllBytes()); if (preview && cf.minorVersion() != 65535) { throw new IllegalStateException("Expected preview class, but got: " + cf.minorVersion() + " for: " + p.toString()); } else if (!preview && cf.minorVersion() != 0) { diff --git a/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out b/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out index 4b31db29d2848..7777e50639b34 100644 --- a/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out +++ b/test/langtools/tools/javac/preview/classReaderTest/Client.nopreview.out @@ -1,2 +1,2 @@ -- compiler.err.preview.feature.disabled.classfile: Bar.class, 22 +- compiler.err.preview.feature.disabled.classfile: Bar.class, 23 1 error diff --git a/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out b/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out index 07b9adf6718ff..cc310daf530ea 100644 --- a/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out +++ b/test/langtools/tools/javac/preview/classReaderTest/Client.preview.out @@ -1,4 +1,4 @@ -- compiler.warn.preview.feature.use.classfile: Bar.class, 22 +- compiler.warn.preview.feature.use.classfile: Bar.class, 23 - compiler.err.warnings.and.werror 1 error 1 warning diff --git a/test/langtools/tools/javac/processing/model/element/TestFileObjectOf.java b/test/langtools/tools/javac/processing/model/element/TestFileObjectOf.java index a9e22804f9ab0..3fef2fe434c25 100644 --- a/test/langtools/tools/javac/processing/model/element/TestFileObjectOf.java +++ b/test/langtools/tools/javac/processing/model/element/TestFileObjectOf.java @@ -26,13 +26,9 @@ * @bug 8224922 * @summary Verify the behavior of the Elements.getFileObjectOf * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask toolbox.TestRunner * @build TestFileObjectOf diff --git a/test/langtools/tools/javac/processing/model/element/TestUnnamedClass.java b/test/langtools/tools/javac/processing/model/element/TestImplicitClass.java similarity index 61% rename from test/langtools/tools/javac/processing/model/element/TestUnnamedClass.java rename to test/langtools/tools/javac/processing/model/element/TestImplicitClass.java index 13ea7e0fa6d85..e6fb81820e2a8 100644 --- a/test/langtools/tools/javac/processing/model/element/TestUnnamedClass.java +++ b/test/langtools/tools/javac/processing/model/element/TestImplicitClass.java @@ -24,19 +24,19 @@ /* * @test * @bug 8306112 8309568 - * @summary Test basic processing of unnamed classes. + * @summary Test basic processing of implicitly declared classes. * @library /tools/javac/lib * @modules java.compiler * jdk.compiler - * @build JavacTestingAbstractProcessor TestUnnamedClass - * @compile -processor TestUnnamedClass --enable-preview --release ${jdk.version} Anonymous.java + * @build JavacTestingAbstractProcessor TestImplicitClass + * @compile -processor TestImplicitClass --enable-preview --release ${jdk.version} Anonymous.java * @clean Nameless.java - * @compile/process -processor TestUnnamedClass -proc:only --enable-preview --release ${jdk.version} -Xprefer:newer -AclassOnly Anonymous Nameless + * @compile/process -processor TestImplicitClass -proc:only --enable-preview --release ${jdk.version} -Xprefer:newer -AclassOnly Anonymous Nameless */ // The first @compile line processes Anonymous.java and a -// Nameless.java class generated using the Filer. Both of those -// unnamed classes are then compiled down to class files. The second +// Nameless.java class generated using the Filer. Both of those implicitly +// declared classes are then compiled down to class files. The second // @compile line, as directed by -Xprefer:newer, builds and checks the // language model objects constructed from those class files, ignoring // any source files for those types. @@ -52,12 +52,12 @@ import javax.tools.JavaFileObject; /** - * Test annotation processing representation of unnamed classes + * Test annotation processing representation of implicitly declared classes * constructed from either a source file or a class file. */ @SuppressWarnings("preview") @SupportedOptions("classOnly") -public class TestUnnamedClass extends JavacTestingAbstractProcessor { +public class TestImplicitClass extends JavacTestingAbstractProcessor { private static int round = 0; private static int checkedClassesCount = 0; @@ -72,14 +72,14 @@ public boolean process(Set annotations, // Don't generate any files if testing pre-existing class files if (!classOnly) { - generateUnnamed(); + generateImplicitClass(); } } else { if (!roundEnv.processingOver()) { // Test generated file(s) checkRoots(roundEnv); } else { // Should have checked at least one class before processing is over if (checkedClassesCount == 0) { - messager.printError("No unnamed classes checked."); + messager.printError("No implicitly declared classes checked."); } } } @@ -95,11 +95,11 @@ private void checkRoots(RoundEnvironment roundEnv) { checkUnnamedClassProperties(type); } if (checks == 0) { - messager.printError("No checking done of any candidate unnamed classes."); + messager.printError("No checking done of any candidate implicitly declared classes."); } } - private void generateUnnamed() { + private void generateImplicitClass() { try { String unnamedSource = """ void main() { @@ -117,12 +117,11 @@ void main() { } /* - * From JEP 445 JLS changes: + * From JEP 463 JLS changes: * - * "An unnamed class compilation unit implicitly declares a class that satisfies the following - * properties: + * "An implicitly declared class compilation unit implicitly declares a class that + * satisfies the following properties: * It is always a top level class. - * It is always an unnamed class (it has no canonical or fully qualified name (6.7)). * It is never abstract (8.1.1.1). * It is always final (8.1.1.2). * It is always a member of an unnamed package (7.4.2) and has package access. @@ -130,8 +129,8 @@ void main() { * It never has any direct superinterface types (8.1.5). * * The body of the class contains every ClassMemberDeclaration - * from the unnamed class compilation unit. It is not possible for - * an unnamed class compilation unit to declare an instance + * from the implicitly declared class compilation unit. It is not possible for + * an implicitly declared class compilation unit to declare an instance * initializer, static initializer, or constructor. * * It has an implicitly declared default constructor (8.8.9). @@ -141,63 +140,55 @@ void main() { * * It is a compile-time error if this class does not declare a candidate main method (12.1.4). */ - void checkUnnamedClassProperties(TypeElement unnamedClass) { + void checkUnnamedClassProperties(TypeElement implicitClass) { checkedClassesCount++; - Name expectedName = unnamedClass.getSimpleName(); + Name expectedName = implicitClass.getSimpleName(); System.out.println("Checking " + expectedName); - if (unnamedClass.getNestingKind() != NestingKind.TOP_LEVEL) { - messager.printError("Unnamed class is not top-level.", unnamedClass); + if (implicitClass.getNestingKind() != NestingKind.TOP_LEVEL) { + messager.printError("Implicitly declared class is not top-level.", implicitClass); } - if (!unnamedClass.isUnnamed()) { - messager.printError("Unnamed class is _not_ indicated as such.", unnamedClass); + if (!implicitClass.getQualifiedName().equals(expectedName)) { + messager.printError("Implicitly declared class qualified name does not match simple name.", implicitClass); } - if (unnamedClass.getSimpleName().isEmpty()) { - messager.printError("Unnamed class has an empty simple name.", unnamedClass); - } - - if (!unnamedClass.getQualifiedName().isEmpty()) { - messager.printError("Unnamed class does _not_ have an empty qualified name.", unnamedClass); - } - - Name binaryName = elements.getBinaryName(unnamedClass); + Name binaryName = elements.getBinaryName(implicitClass); if (!expectedName.equals(binaryName)) { - messager.printError("Unnamed has unexpected binary name" + binaryName + ".", unnamedClass); + messager.printError("Implicitly declared class has unexpected binary name" + binaryName + ".", implicitClass); } - if (unnamedClass.getModifiers().contains(Modifier.ABSTRACT)) { - messager.printError("Unnamed class is abstract.", unnamedClass); + if (implicitClass.getModifiers().contains(Modifier.ABSTRACT)) { + messager.printError("Implicitly declared class is abstract.", implicitClass); } - if (!unnamedClass.getModifiers().contains(Modifier.FINAL)) { - messager.printError("Unnamed class is _not_ final.", unnamedClass); + if (!implicitClass.getModifiers().contains(Modifier.FINAL)) { + messager.printError("Implicitly declared class is _not_ final.", implicitClass); } - if (!elements.getPackageOf(unnamedClass).isUnnamed()) { - messager.printError("Unnamed class is _not_ in an unnamed package.", unnamedClass); + if (!elements.getPackageOf(implicitClass).isUnnamed()) { + messager.printError("Implicitly declared class is _not_ in an unnamed package.", implicitClass); } - if (unnamedClass.getModifiers().contains(Modifier.PUBLIC) || - unnamedClass.getModifiers().contains(Modifier.PRIVATE) || - unnamedClass.getModifiers().contains(Modifier.PROTECTED)) { - messager.printError("Unnamed class does _not_ have package access.", unnamedClass); + if (implicitClass.getModifiers().contains(Modifier.PUBLIC) || + implicitClass.getModifiers().contains(Modifier.PRIVATE) || + implicitClass.getModifiers().contains(Modifier.PROTECTED)) { + messager.printError("Implicitly declared class does _not_ have package access.", implicitClass); } - if ( !types.isSameType(unnamedClass.getSuperclass(), + if ( !types.isSameType(implicitClass.getSuperclass(), elements.getTypeElement("java.lang.Object").asType())) { - messager.printError("Unnamed class does _not_ have java.lang.Object as a superclass.", unnamedClass); + messager.printError("Implicitly declared class does _not_ have java.lang.Object as a superclass.", implicitClass); } - if (!unnamedClass.getInterfaces().isEmpty()) { - messager.printError("Unnamed class has superinterfaces.", unnamedClass); + if (!implicitClass.getInterfaces().isEmpty()) { + messager.printError("Implicitly declared class has superinterfaces.", implicitClass); } - List ctors = constructorsIn(unnamedClass.getEnclosedElements()); + List ctors = constructorsIn(implicitClass.getEnclosedElements()); if (ctors.size() != 1 ) { - messager.printError("Did not find exactly one constructor", unnamedClass); + messager.printError("Did not find exactly one constructor", implicitClass); } if (!classOnly) { @@ -208,7 +199,7 @@ void checkUnnamedClassProperties(TypeElement unnamedClass) { } } - List methods = methodsIn(unnamedClass.getEnclosedElements()); + List methods = methodsIn(implicitClass.getEnclosedElements()); // Just look for a method named "main"; don't check the other details. boolean mainFound = false; Name mainName = elements.getName("main"); @@ -220,7 +211,7 @@ void checkUnnamedClassProperties(TypeElement unnamedClass) { } if (!mainFound) { - messager.printError("No main mehtod found", unnamedClass); + messager.printError("No main method found", implicitClass); } } } diff --git a/test/langtools/tools/javac/processing/model/element/TestOrigin.java b/test/langtools/tools/javac/processing/model/element/TestOrigin.java index d1a1d2479530c..ba4d7ec7ef979 100644 --- a/test/langtools/tools/javac/processing/model/element/TestOrigin.java +++ b/test/langtools/tools/javac/processing/model/element/TestOrigin.java @@ -26,13 +26,9 @@ * @bug 8171355 * @summary Test behavior of javax.lang.model.util.Elements.getOrigin. * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask toolbox.TestRunner * @build TestOrigin @@ -61,8 +57,8 @@ import javax.lang.model.element.ModuleElement.RequiresDirective; import javax.lang.model.util.Elements; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import toolbox.JavacTask; import toolbox.Task; import toolbox.TestRunner; @@ -279,22 +275,22 @@ public void testModuleDirectives(Path base) throws Exception { .writeAll(); Path moduleInfo = classes.resolve("module-info.class"); - ClassModel cf = Classfile.of().parse(moduleInfo); + ClassModel cf = ClassFile.of().parse(moduleInfo); ModuleAttribute module = cf.findAttribute(Attributes.MODULE).orElseThrow(); List newRequires = new ArrayList<>(3); - newRequires.add(ModuleRequireInfo.of(module.requires().get(0).requires(), Classfile.ACC_MANDATED, module.requires().get(0).requiresVersion().orElse(null))); - newRequires.add(ModuleRequireInfo.of(module.requires().get(1).requires(), Classfile.ACC_SYNTHETIC, module.requires().get(1).requiresVersion().orElse(null))); + newRequires.add(ModuleRequireInfo.of(module.requires().get(0).requires(), ClassFile.ACC_MANDATED, module.requires().get(0).requiresVersion().orElse(null))); + newRequires.add(ModuleRequireInfo.of(module.requires().get(1).requires(), ClassFile.ACC_SYNTHETIC, module.requires().get(1).requiresVersion().orElse(null))); newRequires.add(module.requires().get(2)); List newExports = new ArrayList<>(3); - newExports.add(ModuleExportInfo.of(module.exports().get(0).exportedPackage(), Classfile.ACC_MANDATED, module.exports().get(0).exportsTo())); - newExports.add(ModuleExportInfo.of(module.exports().get(1).exportedPackage(), Classfile.ACC_SYNTHETIC, module.exports().get(1).exportsTo())); + newExports.add(ModuleExportInfo.of(module.exports().get(0).exportedPackage(), ClassFile.ACC_MANDATED, module.exports().get(0).exportsTo())); + newExports.add(ModuleExportInfo.of(module.exports().get(1).exportedPackage(), ClassFile.ACC_SYNTHETIC, module.exports().get(1).exportsTo())); newExports.add(module.exports().get(2)); List newOpens = new ArrayList<>(3); - newOpens.add(ModuleOpenInfo.of(module.opens().get(0).openedPackage(), Classfile.ACC_MANDATED, module.opens().get(0).opensTo())); - newOpens.add(ModuleOpenInfo.of(module.opens().get(1).openedPackage(), Classfile.ACC_SYNTHETIC, module.opens().get(1).opensTo())); + newOpens.add(ModuleOpenInfo.of(module.opens().get(0).openedPackage(), ClassFile.ACC_MANDATED, module.opens().get(0).opensTo())); + newOpens.add(ModuleOpenInfo.of(module.opens().get(1).openedPackage(), ClassFile.ACC_SYNTHETIC, module.opens().get(1).opensTo())); newOpens.add(module.opens().get(2)); @@ -306,7 +302,7 @@ public void testModuleDirectives(Path base) throws Exception { newOpens, module.uses(), module.provides()); - byte[] newClassFileBytes = Classfile.of().transform(cf, ClassTransform.dropping(ce -> ce instanceof ModuleAttribute) + byte[] newClassFileBytes = ClassFile.of().transform(cf, ClassTransform.dropping(ce -> ce instanceof ModuleAttribute) .andThen(ClassTransform.endHandler(classBuilder -> classBuilder.with(newModule)))); try (OutputStream out = Files.newOutputStream(moduleInfo)) { out.write(newClassFileBytes); diff --git a/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java b/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java index 9d23707c61890..81efbce05aa20 100644 --- a/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java +++ b/test/langtools/tools/javac/processing/options/TestNoteOnImplicitProcessing.java @@ -23,8 +23,8 @@ /* * @test - * @bug 8310061 8315534 8306819 - * @summary Verify behavior around implicit annotation processing + * @bug 8310061 8315534 + * @summary Verify a note is issued for implicit annotation processing * * @library /tools/lib /tools/javac/lib * @modules @@ -59,27 +59,19 @@ import toolbox.JarTask; /* - * Does not generates a note and the processor does not run: + * Generates note and the processor runs: * $ javac -cp ImplicitProcTestProc.jar HelloWorldTest.java * - * Does _not_ generate a note and the processor does run: + * Does _not_ generate a note and the processor runs: * $ javac -processorpath ImplicitProcTestProc.jar HelloWorldTest.java * $ javac -cp ImplicitProcTestProc.jar -processor ImplicitProcTestProc.jar HelloWorldTest.java * $ javac -cp ImplicitProcTestProc.jar -proc:full HelloWorldTest.java * $ javac -cp ImplicitProcTestProc.jar -proc:only HelloWorldTest.java - * - * Does _not_ generate a note and the processor does _not_run: * $ javac -cp ImplicitProcTestProc.jar -Xlint:-options HelloWorldTest.java * $ javac -cp ImplicitProcTestProc.jar -Xlint:none HelloWorldTest.java * * Does _not_ generate a note and the processor _doesn't_ run. * $ javac -cp ImplicitProcTestProc.jar -proc:none HelloWorldTest.java - * - * (Previously, annotation processing was implicitly enabled and the - * the class path was searched for processors. This test was - * originally written to probe around a note warning of a potential - * future policy change to disable such implicit processing, a policy - * change now implemented and this test has been updated accordingly.) */ public class TestNoteOnImplicitProcessing extends TestRunner { @@ -173,8 +165,8 @@ public void generateWarning(Path base, Path jarFile) { .run(Expect.SUCCESS) .writeAll(); - checkForProcessorMessage(javacResult, false); - checkForCompilerNote(javacResult, false); + checkForProcessorMessage(javacResult, true); + checkForCompilerNote(javacResult, true); } @Test @@ -247,7 +239,7 @@ public void lintOptions(Path base, Path jarFile) { .run(Expect.SUCCESS) .writeAll(); - checkForProcessorMessage(javacResult, false); + checkForProcessorMessage(javacResult, true); checkForCompilerNote(javacResult, false); } @@ -262,7 +254,7 @@ public void lintNone(Path base, Path jarFile) { .run(Expect.SUCCESS) .writeAll(); - checkForProcessorMessage(javacResult, false); + checkForProcessorMessage(javacResult, true); checkForCompilerNote(javacResult, false); } @@ -325,7 +317,7 @@ public void processorsViaAPI(Path base, Path jarFile) throws Exception { task.call(); - verifyMessages(out, compilerOut, false, false); + verifyMessages(out, compilerOut, true); } { @@ -337,7 +329,7 @@ public void processorsViaAPI(Path base, Path jarFile) throws Exception { task.setProcessors(List.of(processor)); task.call(); - verifyMessages(out, compilerOut, false, true); + verifyMessages(out, compilerOut, false); } { @@ -347,7 +339,7 @@ public void processorsViaAPI(Path base, Path jarFile) throws Exception { task.analyze(); - verifyMessages(out, compilerOut, false, false); + verifyMessages(out, compilerOut, true); } { @@ -361,21 +353,16 @@ public void processorsViaAPI(Path base, Path jarFile) throws Exception { task.setProcessors(List.of(processor)); task.analyze(); - verifyMessages(out, compilerOut, false, true); + verifyMessages(out, compilerOut, false); } } finally { System.setOut(oldOut); } } - private void verifyMessages(ByteArrayOutputStream out, StringWriter compilerOut, boolean expectedNotePresent, - boolean processorRunExpected) { - boolean processorRun = out.toString(StandardCharsets.UTF_8).contains("ImplicitProcTestProc run"); - - if (processorRun != processorRunExpected) { - throw new RuntimeException(processorRunExpected ? - "Expected processor message not printed" : - "Unexpected processor message printed"); + private void verifyMessages(ByteArrayOutputStream out, StringWriter compilerOut, boolean expectedNotePresent) { + if (!out.toString(StandardCharsets.UTF_8).contains("ImplicitProcTestProc run")) { + throw new RuntimeException("Expected processor message not printed"); } out.reset(); diff --git a/test/langtools/tools/javac/records/RecordCompilationTests.java b/test/langtools/tools/javac/records/RecordCompilationTests.java index 5a51496ff1973..0436169556ff0 100644 --- a/test/langtools/tools/javac/records/RecordCompilationTests.java +++ b/test/langtools/tools/javac/records/RecordCompilationTests.java @@ -28,15 +28,11 @@ * @bug 8250629 8252307 8247352 8241151 8246774 8259025 8288130 8282714 8289647 8294020 * @summary Negative compilation tests, and positive compilation (smoke) tests for records * @library /lib/combo /tools/lib /tools/javac/lib + * @enablePreview * @modules * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build JavacTestingAbstractProcessor * @run junit/othervm -DuseAP=false RecordCompilationTests @@ -69,11 +65,11 @@ import javax.lang.model.type.ArrayType; import javax.lang.model.type.TypeMirror; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.Opcode; -import jdk.internal.classfile.constantpool.*; -import jdk.internal.classfile.instruction.FieldInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.Opcode; +import java.lang.classfile.constantpool.*; +import java.lang.classfile.instruction.FieldInstruction; import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper; import com.sun.tools.javac.code.Attribute.TypeCompound; @@ -1297,7 +1293,7 @@ record R(int recordComponent) {} int numberOfFieldRefs = 0; for (final File fileEntry : Objects.requireNonNull(dir.listFiles())) { if (fileEntry.getName().endsWith("R.class")) { - ClassModel classFile = Classfile.of().parse(fileEntry.toPath()); + ClassModel classFile = ClassFile.of().parse(fileEntry.toPath()); for (PoolEntry pe : classFile.constantPool()) { if (pe instanceof FieldRefEntry fieldRefEntry) { numberOfFieldRefs++; @@ -1321,7 +1317,7 @@ void testCheckInitializationOrderInCompactConstructor() throws Exception { File dir = assertOK(true, "record R(int i, String s) { R {} }"); for (final File fileEntry : Objects.requireNonNull(dir.listFiles())) { if (fileEntry.getName().equals("R.class")) { - ClassModel classFile = Classfile.of().parse(fileEntry.toPath()); + ClassModel classFile = ClassFile.of().parse(fileEntry.toPath()); for (MethodModel method : classFile.methods()) { if (method.methodName().equalsString("")) { CodeAttribute code_attribute = method.findAttribute(Attributes.CODE).orElseThrow(); @@ -1469,7 +1465,7 @@ record R(@Anno String s) {} File dir = assertOK(true, code); - ClassModel classFile = Classfile.of().parse(findClassFileOrFail(dir, "R.class").toPath()); + ClassModel classFile = ClassFile.of().parse(findClassFileOrFail(dir, "R.class").toPath()); // field first Assert.check(classFile.fields().size() == 1); @@ -1572,7 +1568,7 @@ record R(List<@Anno String> s) {} File dir = assertOK(true, code); - ClassModel classFile = Classfile.of().parse(findClassFileOrFail(dir, "R.class").toPath()); + ClassModel classFile = ClassFile.of().parse(findClassFileOrFail(dir, "R.class").toPath()); // field first Assert.check(classFile.fields().size() == 1); @@ -1788,11 +1784,11 @@ void testMethodsInheritedFromRecordArePublicAndFinal() throws Exception { File dir = assertOK(true, "record R() {}"); for (final File fileEntry : Objects.requireNonNull(dir.listFiles())) { if (fileEntry.getName().equals("R.class")) { - ClassModel classFile = Classfile.of().parse(fileEntry.toPath()); + ClassModel classFile = ClassFile.of().parse(fileEntry.toPath()); for (MethodModel method : classFile.methods()) switch (method.methodName().stringValue()) { case "toString", "equals", "hashCode" -> - Assert.check(((method.flags().flagsMask() & Classfile.ACC_PUBLIC) != 0) && ((method.flags().flagsMask() & Classfile.ACC_FINAL) != 0)); + Assert.check(((method.flags().flagsMask() & ClassFile.ACC_PUBLIC) != 0) && ((method.flags().flagsMask() & ClassFile.ACC_FINAL) != 0)); default -> {} } } @@ -1821,7 +1817,7 @@ void testCanonicalAccessibility() throws Exception { File dir = assertOK(true, "class R {# record RR() {} }", a); for (final File fileEntry : Objects.requireNonNull(dir.listFiles())) { if (fileEntry.getName().equals("R$RR.class")) { - ClassModel classFile = Classfile.of().parse(fileEntry.toPath()); + ClassModel classFile = ClassFile.of().parse(fileEntry.toPath()); for (MethodModel method : classFile.methods()) if (method.methodName().equalsString("")) { Assert.check(method.flags().flagsMask() == accessFlag(a), @@ -1844,9 +1840,9 @@ private int protection(String access) { private int accessFlag(String access) { return switch (access) { - case "private" -> Classfile.ACC_PRIVATE; - case "protected" -> Classfile.ACC_PROTECTED; - case "public" -> Classfile.ACC_PUBLIC; + case "private" -> ClassFile.ACC_PRIVATE; + case "protected" -> ClassFile.ACC_PROTECTED; + case "public" -> ClassFile.ACC_PUBLIC; case "" -> 0; default -> throw new AssertionError(); }; diff --git a/test/langtools/tools/javac/records/RecordsBinaryCompatibilityTests.java b/test/langtools/tools/javac/records/RecordsBinaryCompatibilityTests.java index 1c258ac9d2559..fd1304dfb9e7d 100644 --- a/test/langtools/tools/javac/records/RecordsBinaryCompatibilityTests.java +++ b/test/langtools/tools/javac/records/RecordsBinaryCompatibilityTests.java @@ -25,15 +25,11 @@ * @test * @summary test binary compatibility rules for record classes * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util * jdk.compiler/com.sun.tools.javac.code - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main RecordsBinaryCompatibilityTests diff --git a/test/langtools/tools/javac/records/recordComponent/RecordComponentTypeTest.java b/test/langtools/tools/javac/records/recordComponent/RecordComponentTypeTest.java index e4fcdc6c07a2f..f11c464231f3d 100644 --- a/test/langtools/tools/javac/records/recordComponent/RecordComponentTypeTest.java +++ b/test/langtools/tools/javac/records/recordComponent/RecordComponentTypeTest.java @@ -26,20 +26,16 @@ * @bug 8273408 * @summary The compiler shouldn't crash when record component uses the class generated by the annotation processor. * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @compile GenerateTypeProcessor.java * @run main RecordComponentTypeTest */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.RuntimeVisibleAnnotationsAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute; import java.nio.file.Path; import java.util.Arrays; @@ -143,7 +139,7 @@ public record RecordComponentUsingGeneratedTypeWithAnnotation(@TestAnnotation Ge .options("-processor", "GenerateTypeProcessor") .outdir(curPath) .run(); - cf = Classfile.of().parse(curPath.resolve("RecordComponentUsingGeneratedTypeWithAnnotation.class")); + cf = ClassFile.of().parse(curPath.resolve("RecordComponentUsingGeneratedTypeWithAnnotation.class")); for (FieldModel field : cf.fields()) { if (field.fieldName().equalsString("generatedType")){ diff --git a/test/langtools/tools/javac/recovery/AnnotationRecovery.java b/test/langtools/tools/javac/recovery/AnnotationRecovery.java index 30f1fb3c18274..d9b9854f021f9 100644 --- a/test/langtools/tools/javac/recovery/AnnotationRecovery.java +++ b/test/langtools/tools/javac/recovery/AnnotationRecovery.java @@ -26,13 +26,9 @@ * @bug 8270139 * @summary Verify error recovery w.r.t. annotations * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main AnnotationRecovery diff --git a/test/langtools/tools/javac/recovery/AttrRecovery.java b/test/langtools/tools/javac/recovery/AttrRecovery.java index 67df9f84567cb..607575b291fca 100644 --- a/test/langtools/tools/javac/recovery/AttrRecovery.java +++ b/test/langtools/tools/javac/recovery/AttrRecovery.java @@ -26,13 +26,9 @@ * @bug 8301580 * @summary Verify error recovery w.r.t. Attr * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main AttrRecovery diff --git a/test/langtools/tools/javac/recovery/CrashDueToUnreportedError.java b/test/langtools/tools/javac/recovery/CrashDueToUnreportedError.java new file mode 100644 index 0000000000000..4520a01f7ec88 --- /dev/null +++ b/test/langtools/tools/javac/recovery/CrashDueToUnreportedError.java @@ -0,0 +1,29 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8320948 + * @summary NPE due to unreported compiler error + * @compile/fail/ref=CrashDueToUnreportedError.out -XDrawDiagnostics CrashDueToUnreportedError.java + */ + +import java.util.List; + +public class CrashDueToUnreportedError { + class Builder { + private Builder(Person person, String unused) {} + public Builder withTypes(Entity entities) { + return new Builder(Person.make(Entity.combineAll(entities))); + } + } + + interface Person { + static Person make(List> eventSubtypes) { + return null; + } + } + + class Entity { + public static List> combineAll(Entity subtypes) { + return null; + } + } +} diff --git a/test/langtools/tools/javac/recovery/CrashDueToUnreportedError.out b/test/langtools/tools/javac/recovery/CrashDueToUnreportedError.out new file mode 100644 index 0000000000000..83655eb07baae --- /dev/null +++ b/test/langtools/tools/javac/recovery/CrashDueToUnreportedError.out @@ -0,0 +1,2 @@ +CrashDueToUnreportedError.java:14:43: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: E,compiler.misc.type.captureof: 1, ? extends CrashDueToUnreportedError.Entity,Root, (compiler.misc.inconvertible.types: java.util.List>, java.util.List>)) +1 error diff --git a/test/langtools/tools/javac/recovery/LambdaRecovery.java b/test/langtools/tools/javac/recovery/LambdaRecovery.java index 38151ac70e545..d64ae573aced3 100644 --- a/test/langtools/tools/javac/recovery/LambdaRecovery.java +++ b/test/langtools/tools/javac/recovery/LambdaRecovery.java @@ -26,13 +26,9 @@ * @bug 8297974 * @summary Verify error recovery w.r.t. lambdas * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main LambdaRecovery diff --git a/test/langtools/tools/javac/recovery/MethodModifiers.java b/test/langtools/tools/javac/recovery/MethodModifiers.java index ea12a4a5c3fa1..893c65f8cb04c 100644 --- a/test/langtools/tools/javac/recovery/MethodModifiers.java +++ b/test/langtools/tools/javac/recovery/MethodModifiers.java @@ -26,13 +26,9 @@ * @bug 8292755 * @summary Verify error recovery related to method modifiers. * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main MethodModifiers diff --git a/test/langtools/tools/javac/resolve/NoObjectToString.java b/test/langtools/tools/javac/resolve/NoObjectToString.java index 0d9af699c728a..56f574bbbbe93 100644 --- a/test/langtools/tools/javac/resolve/NoObjectToString.java +++ b/test/langtools/tools/javac/resolve/NoObjectToString.java @@ -25,18 +25,14 @@ * @test * @bug 8272564 * @summary Correct resolution of toString() (and other similar calls) on interfaces - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview * @compile NoObjectToString.java * @run main NoObjectToString */ import java.io.*; -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.*; public class NoObjectToString { public static void main(String... args) throws Exception { @@ -48,7 +44,7 @@ void run(String... args) throws Exception { //Verify there are no references to Object.toString() in a Test: try (InputStream in = NoObjectToString.class.getResourceAsStream("NoObjectToString$Test.class")) { assert in != null; - ClassModel cm = Classfile.of().parse(in.readAllBytes()); + ClassModel cm = ClassFile.of().parse(in.readAllBytes()); for (PoolEntry pe : cm.constantPool()) { if (pe instanceof MethodRefEntry ref) { String methodDesc = ref.owner().name() + "." + ref.nameAndType().name() + ":" + ref.nameAndType().type(); diff --git a/test/langtools/tools/javac/sealed/BinaryCompatibilityTests.java b/test/langtools/tools/javac/sealed/BinaryCompatibilityTests.java index f828a548c07e3..2d3ce1821d2c5 100644 --- a/test/langtools/tools/javac/sealed/BinaryCompatibilityTests.java +++ b/test/langtools/tools/javac/sealed/BinaryCompatibilityTests.java @@ -25,15 +25,11 @@ * @test * @summary test binary compatibility rules for sealed classes * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util * jdk.compiler/com.sun.tools.javac.code - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main BinaryCompatibilityTests diff --git a/test/langtools/tools/javac/sealed/CheckSubtypesOfSealedTest.java b/test/langtools/tools/javac/sealed/CheckSubtypesOfSealedTest.java index c5dd8defe9934..0366d4982ca87 100644 --- a/test/langtools/tools/javac/sealed/CheckSubtypesOfSealedTest.java +++ b/test/langtools/tools/javac/sealed/CheckSubtypesOfSealedTest.java @@ -25,12 +25,8 @@ * @test * @summary check subtypes of sealed classes * @library /tools/lib /tools/javac/lib /tools/javac/classfiles/attributes/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -42,8 +38,8 @@ import java.util.List; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.util.Assert; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.PermittedSubclassesAttribute; +import java.lang.classfile.*; +import java.lang.classfile.attribute.PermittedSubclassesAttribute; public class CheckSubtypesOfSealedTest extends TestBase { diff --git a/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java b/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java index de6d82767031a..0b20fee0b81a3 100644 --- a/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java +++ b/test/langtools/tools/javac/sealed/SealedDiffConfigurationsTest.java @@ -25,15 +25,11 @@ * @test 8247352 8293348 * @summary test different configurations of sealed classes, same compilation unit, diff pkg or mdl, etc * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util * jdk.compiler/com.sun.tools.javac.code - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * @build toolbox.ToolBox toolbox.JavacTask * @run main SealedDiffConfigurationsTest @@ -47,10 +43,10 @@ import java.nio.file.Paths; import java.util.stream.IntStream; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.PermittedSubclassesAttribute; -import jdk.internal.classfile.constantpool.ClassEntry; -import jdk.internal.classfile.constantpool.ConstantPoolException; +import java.lang.classfile.*; +import java.lang.classfile.attribute.PermittedSubclassesAttribute; +import java.lang.classfile.constantpool.ClassEntry; +import java.lang.classfile.constantpool.ConstantPoolException; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.util.Assert; import toolbox.TestRunner; @@ -135,8 +131,8 @@ public void testSameCompilationUnitPos2(Path base) throws Exception { } private void checkSealedClassFile(Path out, String cfName, List expectedSubTypeNames) throws ConstantPoolException, Exception { - ClassModel sealedCF = Classfile.of().parse(out.resolve(cfName)); - Assert.check((sealedCF.flags().flagsMask() & Classfile.ACC_FINAL) == 0, String.format("class at file %s must not be final", cfName)); + ClassModel sealedCF = ClassFile.of().parse(out.resolve(cfName)); + Assert.check((sealedCF.flags().flagsMask() & ClassFile.ACC_FINAL) == 0, String.format("class at file %s must not be final", cfName)); PermittedSubclassesAttribute permittedSubclasses = sealedCF.findAttribute(Attributes.PERMITTED_SUBCLASSES).orElseThrow(); Assert.check(permittedSubclasses.permittedSubclasses().size() == expectedSubTypeNames.size()); List subtypeNames = new ArrayList<>(); @@ -153,9 +149,9 @@ private void checkSealedClassFile(Path out, String cfName, List expected } private void checkSubtypeClassFile(Path out, String cfName, String superClassName, boolean shouldBeFinal) throws Exception { - ClassModel subCF1 = Classfile.of().parse(out.resolve(cfName)); + ClassModel subCF1 = ClassFile.of().parse(out.resolve(cfName)); if (shouldBeFinal) { - Assert.check((subCF1.flags().flagsMask() & Classfile.ACC_FINAL) != 0, String.format("class at file %s must be final", cfName)); + Assert.check((subCF1.flags().flagsMask() & ClassFile.ACC_FINAL) != 0, String.format("class at file %s must be final", cfName)); } Assert.checkNull(subCF1.findAttribute(Attributes.PERMITTED_SUBCLASSES).orElse(null)); Assert.check(subCF1.superclass().orElseThrow().name().equalsString(superClassName)); diff --git a/test/langtools/tools/javac/switchexpr/ExpressionSwitch.java b/test/langtools/tools/javac/switchexpr/ExpressionSwitch.java index b5c94d3ce9479..1c040052e69a2 100644 --- a/test/langtools/tools/javac/switchexpr/ExpressionSwitch.java +++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitch.java @@ -1,12 +1,12 @@ /* * @test /nodynamiccopyright/ - * @bug 8206986 8222169 8224031 8240964 8267119 8268670 + * @bug 8206986 8222169 8224031 8240964 8267119 8268670 8321582 * @summary Check expression switch works. - * @compile/fail/ref=ExpressionSwitch-old.out --release 9 -XDrawDiagnostics ExpressionSwitch.java * @compile ExpressionSwitch.java * @run main ExpressionSwitch */ +// * @compile/fail/ref=ExpressionSwitch-old.out --release 9 -XDrawDiagnostics ExpressionSwitch.java import java.util.Objects; import java.util.function.Supplier; @@ -35,6 +35,16 @@ private void run() { localClass(T.A); assertEquals(castSwitchExpressions(T.A), "A"); testTypeInference(true, 0); + assertEquals(yieldPrimitiveDotClass("byte"), byte.class); + assertEquals(yieldPrimitiveDotClass("char"), char.class); + assertEquals(yieldPrimitiveDotClass("short"), short.class); + assertEquals(yieldPrimitiveDotClass("int"), int.class); + assertEquals(yieldPrimitiveDotClass("long"), long.class); + assertEquals(yieldPrimitiveDotClass("float"), float.class); + assertEquals(yieldPrimitiveDotClass("double"), double.class); + assertEquals(yieldPrimitiveDotClass("void"), void.class); + assertEquals(yieldPrimitiveDotClass("boolean"), boolean.class); + assertEquals(yieldPrimitiveDotClass("other"), null); } private String print(T t) { @@ -140,6 +150,21 @@ private boolean yieldUnaryNotOperator(String s, boolean b) { }; } + private Class yieldPrimitiveDotClass(String s) { + return switch (s) { + case "byte": yield byte.class; + case "char": yield char.class; + case "short": yield short.class; + case "int": yield int.class; + case "long": yield long.class; + case "float": yield float.class; + case "double": yield double.class; + case "void": yield void.class; + case "boolean": yield boolean.class; + default: yield null; + }; + } + private void localClass(T t) { String good = "good"; class L { diff --git a/test/langtools/tools/javac/sym/ElementStructureTest.java b/test/langtools/tools/javac/sym/ElementStructureTest.java index 3513a6347ac03..8e46863279a24 100644 --- a/test/langtools/tools/javac/sym/ElementStructureTest.java +++ b/test/langtools/tools/javac/sym/ElementStructureTest.java @@ -26,16 +26,12 @@ * @bug 8072480 8203814 * @summary Check the platform classpath contains the correct elements. * @library /tools/lib + * @enablePreview * @modules jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.platform * jdk.compiler/com.sun.tools.javac.util - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * java.base/jdk.internal.classfile.impl * jdk.jdeps/com.sun.tools.javap * @build toolbox.ToolBox ElementStructureTest @@ -98,7 +94,7 @@ import javax.tools.ToolProvider; import com.sun.source.util.JavacTask; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.code.Symbol.CompletionFailure; import com.sun.tools.javac.platform.PlatformProvider; @@ -289,7 +285,7 @@ void realClasses(String location, Predicate acceptor, Writer output, Str } JavaFileObject file = new ByteArrayJavaFileObject(data.toByteArray()); try (InputStream in = new ByteArrayInputStream(data.toByteArray())) { - String name = Classfile.of().parse(in.readAllBytes()).thisClass().name().stringValue(); + String name = ClassFile.of().parse(in.readAllBytes()).thisClass().name().stringValue(); className2File.put(name, file); file2ClassName.put(file, name); } catch (IOException ex) { diff --git a/test/langtools/tools/javac/sym/PrintCTSymContent.java b/test/langtools/tools/javac/sym/PrintCTSymContent.java new file mode 100644 index 0000000000000..164edcff3f0fb --- /dev/null +++ b/test/langtools/tools/javac/sym/PrintCTSymContent.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8072480 8203814 + * @summary Check the platform classpath contains the correct elements. + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.code + * jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.platform + * jdk.compiler/com.sun.tools.javac.processing + * jdk.compiler/com.sun.tools.javac.util + * @build toolbox.ToolBox PrintCTSymContent + * @run main PrintCTSymContent + */ + +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import javax.lang.model.element.Element; +import javax.lang.model.element.ModuleElement; +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; + +import com.sun.tools.javac.api.JavacTaskImpl; +import com.sun.tools.javac.processing.PrintingProcessor.PrintingElementVisitor; +import java.util.Comparator; +import javax.lang.model.element.ModuleElement.ExportsDirective; +import javax.lang.model.element.QualifiedNameable; +import javax.lang.model.util.ElementFilter; + +import toolbox.ToolBox; + + +/** + * Dump content of ct.sym for specified releases to a specified directory. + * + * Usage: adjust the `@run main PrintCTSymContent` tag to include the starting and + * ending versions, and a target directory where the API snapshot should be written: + * + * @run main PrintCTSymContent + * + * and run the test. + */ +public class PrintCTSymContent { + + public static void main(String... args) throws Exception { + if (args.length == 0) { + return ; //pass vacuously + } + new PrintCTSymContent().generateCtSymOutput(args); + } + + void generateCtSymOutput(String... args) throws Exception { + int startRelease = Integer.parseInt(args[0]); + int endRelease = Integer.parseInt(args[1]); + String directory = args[2]; + + for (int i = startRelease; i <= endRelease; i++) { + try (Writer content = Files.newBufferedWriter(Paths.get(directory, "ct-sym-content-" + i + ".txt"))) { + run(content, String.valueOf(i)); + } + } + } + + void run(Writer output, String version) throws Exception { + List options = Arrays.asList("--release", version, "-classpath", "", "--add-modules", "ALL-SYSTEM"); + List files = List.of(new ToolBox.JavaSource("Test", "")); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, null, null, options, null, files); + + task.analyze(); + + PrintingElementVisitor target = new PrintingElementVisitor(output, task.getElements()); + Comparator sortByQualifiedName = (me1, me2) -> me1.getQualifiedName().toString().compareTo(me2.getQualifiedName().toString()); + List allModules = task.getElements().getAllModuleElements().stream().sorted(sortByQualifiedName).toList(); + + for (ModuleElement module : allModules) { + if (module.isUnnamed()) { + continue; + } + target.visit(module); + for (ExportsDirective ed : ElementFilter.exportsIn(module.getDirectives())) { + if (ed.getTargetModules() == null) { + for (Element c : ElementFilter.typesIn(ed.getPackage().getEnclosedElements()).stream().sorted(sortByQualifiedName).toList()) { + target.visit(c); + } + } + } + } + } + +} diff --git a/test/langtools/tools/javac/unnamed/UnnamedClassRecovery.out b/test/langtools/tools/javac/unnamed/UnnamedClassRecovery.out deleted file mode 100644 index 0389b156f0193..0000000000000 --- a/test/langtools/tools/javac/unnamed/UnnamedClassRecovery.out +++ /dev/null @@ -1,4 +0,0 @@ -UnnamedClassRecovery.java:7:33: compiler.err.expected: ';' -- compiler.note.preview.filename: UnnamedClassRecovery.java, DEFAULT -- compiler.note.preview.recompile -1 error diff --git a/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01_source10.out b/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01_source10.out index f424f013a957c..a7c5bae106bbc 100644 --- a/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01_source10.out +++ b/test/langtools/tools/javac/var_implicit_lambda/VarInImplicitLambdaNegTest01_source10.out @@ -1,4 +1,4 @@ -- compiler.warn.source.no.system.modules.path: 10 +- compiler.warn.source.no.system.modules.path: 10, (compiler.misc.source.no.system.modules.path: 10) VarInImplicitLambdaNegTest01.java:12:36: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.var.syntax.in.implicit.lambda), 10, 11 VarInImplicitLambdaNegTest01.java:15:28: compiler.err.invalid.lambda.parameter.declaration: (compiler.misc.implicit.and.explicit.not.allowed) VarInImplicitLambdaNegTest01.java:17:52: compiler.err.restricted.type.not.allowed.here: var diff --git a/test/langtools/tools/javac/varargs/6199075/T6199075.java b/test/langtools/tools/javac/varargs/6199075/T6199075.java index 19fe33284eba4..d2eaab364f5e0 100644 --- a/test/langtools/tools/javac/varargs/6199075/T6199075.java +++ b/test/langtools/tools/javac/varargs/6199075/T6199075.java @@ -28,22 +28,18 @@ * @summary Unambiguous varargs method calls flagged as ambiguous * @author mcimadamore * - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.util */ import com.sun.source.util.JavacTask; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.MemberRefEntry; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.MemberRefEntry; +import java.lang.classfile.instruction.InvokeInstruction; import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.util.List; @@ -219,7 +215,7 @@ void verifyBytecode(VarargsMethod selected) { bytecodeCheckCount++; File compiledTest = new File("Test.class"); try { - ClassModel cf = Classfile.of().parse(compiledTest.toPath()); + ClassModel cf = ClassFile.of().parse(compiledTest.toPath()); MethodModel testMethod = null; for (MethodModel m : cf.methods()) { if (m.methodName().equalsString("test")) { diff --git a/test/langtools/tools/javac/varargs/7042566/T7042566.java b/test/langtools/tools/javac/varargs/7042566/T7042566.java index 6126c180f1919..845cab3bdf847 100644 --- a/test/langtools/tools/javac/varargs/7042566/T7042566.java +++ b/test/langtools/tools/javac/varargs/7042566/T7042566.java @@ -27,12 +27,8 @@ * @summary Unambiguous varargs method calls flagged as ambiguous * temporarily workaround combo tests are causing time out in several platforms * @library /tools/javac/lib - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.file * jdk.compiler/com.sun.tools.javac.util @@ -44,11 +40,11 @@ import java.io.InputStream; import javax.tools.JavaFileObject; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.CodeAttribute; -import jdk.internal.classfile.constantpool.MemberRefEntry; -import jdk.internal.classfile.constantpool.MethodRefEntry; -import jdk.internal.classfile.instruction.InvokeInstruction; +import java.lang.classfile.*; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.constantpool.MemberRefEntry; +import java.lang.classfile.constantpool.MethodRefEntry; +import java.lang.classfile.instruction.InvokeInstruction; import com.sun.tools.javac.util.List; import combo.ComboInstance; @@ -274,7 +270,7 @@ void check(Result> res) { void verifyBytecode(Result> res, VarargsMethod selected) { try (InputStream is = res.get().iterator().next().openInputStream()) { - ClassModel cf = Classfile.of().parse(is.readAllBytes()); + ClassModel cf = ClassFile.of().parse(is.readAllBytes()); MethodModel testMethod = null; for (MethodModel m : cf.methods()) { if (m.methodName().equalsString("test")) { diff --git a/test/langtools/tools/javac/versions/Versions.java b/test/langtools/tools/javac/versions/Versions.java index ee9e6f2be06f2..62c7f2fcf9e49 100644 --- a/test/langtools/tools/javac/versions/Versions.java +++ b/test/langtools/tools/javac/versions/Versions.java @@ -25,7 +25,7 @@ * @test * @bug 4981566 5028634 5094412 6304984 7025786 7025789 8001112 8028545 * 8000961 8030610 8028546 8188870 8173382 8173382 8193290 8205619 8028563 - * 8245147 8245586 8257453 8286035 8306586 + * 8245147 8245586 8257453 8286035 8306586 8320806 8306586 * @summary Check interpretation of -target and -source options * @modules java.compiler * jdk.compiler @@ -42,9 +42,7 @@ import javax.tools.StandardJavaFileManager; import java.util.List; import java.util.ArrayList; -import java.util.Arrays; import java.util.Set; -import java.util.function.BiConsumer; import java.util.function.Consumer; /* @@ -73,9 +71,10 @@ public static void main(String... args) throws IOException { public static final Set VALID_SOURCES = Set.of("1.8", "1.9", "1.10", "11", "12", "13", "14", - "15", "16", "17", "18", "19", "20", "21", "22"); + "15", "16", "17", "18", "19", "20", "21", "22", + "23"); - public static final String LATEST_MAJOR_VERSION = "66.0"; + public static final String LATEST_MAJOR_VERSION = "67.0"; static enum SourceTarget { EIGHT(true, "52.0", "8"), @@ -93,6 +92,7 @@ static enum SourceTarget { TWENTY(false, "64.0", "20"), TWENTY_ONE(false,"65.0", "21"), TWENTY_TWO(false,"66.0", "22"), + TWENTY_THREE(false,"67.0", "23"), ; // Reduce code churn when appending new constants private final boolean dotOne; @@ -240,16 +240,8 @@ protected void check(String major) { protected void check(String major, List args) { printargs("check", args); - List jcargs = new ArrayList<>(); - jcargs.add("-Xlint:-options"); - // add in args conforming to List requrements of JavaCompiler - for (String onearg : args) { - String[] fields = onearg.split(" "); - for (String onefield : fields) { - jcargs.add(onefield); - } - } + List jcargs = javaCompilerOptions(args); boolean creturn = compile("Base.java", jcargs); if (!creturn) { @@ -264,6 +256,25 @@ protected void check(String major, List args) { } } + /** + * Create a list of options suitable for use with {@link JavaCompiler} + * @param args a list of space-delimited options, such as "-source 11" + * @return a list of arguments suitable for use with {@link JavaCompiler} + */ + private static List javaCompilerOptions(List args) { + List jcargs = new ArrayList<>(); + jcargs.add("-Xlint:-options"); + + // add in args conforming to List requirements of JavaCompiler + for (String onearg : args) { + String[] fields = onearg.split(" "); + for (String onefield : fields) { + jcargs.add(onefield); + } + } + return jcargs; + } + /** * The BASE source example is expected to compile on all source * levels. Otherwise, an example is expected to compile on its @@ -272,8 +283,8 @@ protected void check(String major, List args) { * the uncommon program that is accepted in one version of the * language and rejected in a later version.) * - * When version of the language get a new, non-preview feature, a - * new source example enum constant should be added. + * When a version of the language gets a new, non-preview feature, + * a new source example enum constant should be added. */ enum SourceExample { BASE(7, "Base.java", "public class Base { }\n"), @@ -311,7 +322,7 @@ void m(String name) { """), SOURCE_14(14, "New14.java", - // New feature in 14: text blocks + // New feature in 14: switch expressions """ public class New14 { static { @@ -375,6 +386,20 @@ public static void main(String... args) { } """), + SOURCE_22(22, "New22.java", + // New feature in 22: Unnamed Variables & Patterns + """ + public class New22 { + public static void main(String... args) { + Object o = new Object(){}; + + System.out.println(switch (o) { + case Integer _ -> "Hello world."; + default -> o.toString(); + }); + } + } + """), ; // Reduce code churn when appending new constants private int sourceLevel; @@ -413,16 +438,7 @@ protected void expectedFail(List args, List fileNames) { protected void pass(List args) { printargs("pass", args); - List jcargs = new ArrayList<>(); - jcargs.add("-Xlint:-options"); - - // add in args conforming to List requrements of JavaCompiler - for (String onearg : args) { - String[] fields = onearg.split(" "); - for (String onefield : fields) { - jcargs.add(onefield); - } - } + List jcargs = javaCompilerOptions(args); // empty list is error if (jcargs.isEmpty()) { @@ -450,16 +466,7 @@ protected void pass(List args) { protected void fail(List args) { printargs("fail", args); - List jcargs = new ArrayList<>(); - jcargs.add("-Xlint:-options"); - - // add in args conforming to List requrements of JavaCompiler - for (String onearg : args) { - String[] fields = onearg.split(" "); - for (String onefield : fields) { - jcargs.add(onefield); - } - } + List jcargs = javaCompilerOptions(args); // empty list is error if (jcargs.isEmpty()) { diff --git a/test/langtools/tools/javap/T6716452.java b/test/langtools/tools/javap/T6716452.java index bba48e9eb03a3..4cc8f4ec41d9c 100644 --- a/test/langtools/tools/javap/T6716452.java +++ b/test/langtools/tools/javap/T6716452.java @@ -24,18 +24,14 @@ /* * @test 6716452 * @summary need a method to get an index of an attribute - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ import java.io.*; import java.nio.file.Files; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; public class T6716452 { public static void main(String[] args) throws Exception { @@ -45,7 +41,7 @@ public static void main(String[] args) throws Exception { public void run() throws Exception { File javaFile = writeTestFile(); File classFile = compileTestFile(javaFile); - ClassModel cm = Classfile.of().parse(classFile.toPath()); + ClassModel cm = ClassFile.of().parse(classFile.toPath()); for (MethodModel mm: cm.methods()) { test(mm); } diff --git a/test/langtools/tools/javap/TestClassNameWarning.java b/test/langtools/tools/javap/TestClassNameWarning.java index 992f4b4c5058c..3412f8d290f49 100644 --- a/test/langtools/tools/javap/TestClassNameWarning.java +++ b/test/langtools/tools/javap/TestClassNameWarning.java @@ -26,15 +26,11 @@ * @bug 8170708 * @summary javap -m cannot read a module-info.class * @library /tools/lib + * @enablePreview * @modules * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.jdeps/com.sun.tools.javap - * java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components * @build toolbox.JavacTask toolbox.JavapTask toolbox.ToolBox toolbox.TestRunner * @run main TestClassNameWarning */ @@ -49,7 +45,7 @@ import java.util.stream.Collectors; -import jdk.internal.classfile.*; +import java.lang.classfile.*; import toolbox.JavacTask; import toolbox.JavapTask; import toolbox.Task; @@ -176,8 +172,8 @@ public void testNoNameClass(Path base) throws Exception { .files(tb.findJavaFiles(src)) .run() .writeAll(); - ClassModel cm = Classfile.of().parse(classes.resolve("A.class")); - Classfile.of().buildTo( + ClassModel cm = ClassFile.of().parse(classes.resolve("A.class")); + ClassFile.of().buildTo( classes.resolve("Z.class"), ClassDesc.of("0"), cb -> { for (ClassElement ce : cm) { diff --git a/test/langtools/tools/javap/classfile/6888367/T6888367.java b/test/langtools/tools/javap/classfile/6888367/T6888367.java index 50a8e67ee3811..05df08b5948d7 100644 --- a/test/langtools/tools/javap/classfile/6888367/T6888367.java +++ b/test/langtools/tools/javap/classfile/6888367/T6888367.java @@ -27,20 +27,16 @@ import java.lang.constant.*; import java.nio.file.Paths; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.*; /* * @test * @bug 6888367 * @summary classfile library parses signature attributes incorrectly - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl + * @enablePreview + * @modules java.base/jdk.internal.classfile.impl */ /* @@ -156,7 +152,7 @@ void test(String name, ConstantDesc desc, AttributedElement m) { ClassModel getClassFile(String name) throws IOException, URISyntaxException { URL rsc = getClass().getResource(name + ".class"); assert rsc != null; - return Classfile.of().parse(Paths.get(rsc.toURI())); + return ClassFile.of().parse(Paths.get(rsc.toURI())); } AnnotValues getDescValue(AttributedElement m) { diff --git a/test/langtools/tools/javap/classfile/T6887895.java b/test/langtools/tools/javap/classfile/T6887895.java index 548752e1e734f..fdc72395cad13 100644 --- a/test/langtools/tools/javap/classfile/T6887895.java +++ b/test/langtools/tools/javap/classfile/T6887895.java @@ -25,19 +25,15 @@ * @test * @bug 6887895 * @summary test getting constantpool elements' basename through asInternalName() API - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ import java.io.*; import java.net.*; import java.nio.file.Paths; import java.util.*; -import jdk.internal.classfile.*; -import jdk.internal.classfile.constantpool.*; +import java.lang.classfile.*; +import java.lang.classfile.constantpool.*; public class T6887895 { public static void main(String[] args) throws Exception { @@ -75,7 +71,7 @@ void run() throws Exception { ClassModel getClassFile(String name) throws IOException, URISyntaxException { URL rsc = getClass().getResource(name); - return Classfile.of().parse(Paths.get(rsc.toURI())); + return ClassFile.of().parse(Paths.get(rsc.toURI())); } class Test { diff --git a/test/langtools/tools/javap/typeAnnotations/JSR175Annotations.java b/test/langtools/tools/javap/typeAnnotations/JSR175Annotations.java index a4ce227d2dd90..1aa3ddbebd8dc 100644 --- a/test/langtools/tools/javap/typeAnnotations/JSR175Annotations.java +++ b/test/langtools/tools/javap/typeAnnotations/JSR175Annotations.java @@ -22,19 +22,15 @@ */ import java.io.*; -import jdk.internal.classfile.*; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.Attributes; +import java.lang.classfile.attribute.*; /* * @test JSR175Annotations * @bug 6843077 * @summary test that only type annotations are recorded as such in classfile - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ public class JSR175Annotations { @@ -46,7 +42,7 @@ public void run() throws Exception { File javaFile = writeTestFile(); File classFile = compileTestFile(javaFile); - ClassModel cm = Classfile.of().parse(classFile.toPath()); + ClassModel cm = ClassFile.of().parse(classFile.toPath()); for (MethodModel mm: cm.methods()) { test(mm); } @@ -67,7 +63,7 @@ void test(AttributedElement m) { } // test the result of AttributedElement.findAttribute according to expectations - > void test(AttributedElement m, AttributeMapper attr_name) { + > void test(AttributedElement m, AttributeMapper attr_name) { Attribute attr_instance = m.findAttribute(attr_name).orElse(null); if (attr_instance != null) { switch (attr_instance) { diff --git a/test/langtools/tools/javap/typeAnnotations/NewArray.java b/test/langtools/tools/javap/typeAnnotations/NewArray.java index e0f6bc08e8506..7a5ca4675ce0a 100644 --- a/test/langtools/tools/javap/typeAnnotations/NewArray.java +++ b/test/langtools/tools/javap/typeAnnotations/NewArray.java @@ -22,18 +22,14 @@ */ import java.io.*; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; /* * @test NewArray * @bug 6843077 * @summary Test type annotations on local array are in method's code attribute. - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ public class NewArray { @@ -45,7 +41,7 @@ public void run() throws Exception { File javaFile = writeTestFile(); File classFile = compileTestFile(javaFile); - ClassModel cm = Classfile.of().parse(classFile.toPath()); + ClassModel cm = ClassFile.of().parse(classFile.toPath()); for (MethodModel mm: cm.methods()) { test(mm); } diff --git a/test/langtools/tools/javap/typeAnnotations/Presence.java b/test/langtools/tools/javap/typeAnnotations/Presence.java index 9d838432bf110..7b144457070b4 100644 --- a/test/langtools/tools/javap/typeAnnotations/Presence.java +++ b/test/langtools/tools/javap/typeAnnotations/Presence.java @@ -23,18 +23,14 @@ import java.io.*; import java.lang.annotation.ElementType; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; /* * @test Presence * @bug 6843077 * @summary test that all type annotations are present in the classfile - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ public class Presence { @@ -46,7 +42,7 @@ public void run() throws Exception { File javaFile = writeTestFile(); File classFile = compileTestFile(javaFile); - ClassModel cm = Classfile.of().parse(classFile.toPath()); + ClassModel cm = ClassFile.of().parse(classFile.toPath()); test(cm); for (FieldModel fm : cm.fields()) { test(fm); diff --git a/test/langtools/tools/javap/typeAnnotations/PresenceInner.java b/test/langtools/tools/javap/typeAnnotations/PresenceInner.java index 94f6ee15e0e24..a47a5ea9f539a 100644 --- a/test/langtools/tools/javap/typeAnnotations/PresenceInner.java +++ b/test/langtools/tools/javap/typeAnnotations/PresenceInner.java @@ -22,18 +22,14 @@ */ import java.io.*; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; /* * @test PresenceInner * @bug 6843077 * @summary test that annotations in inner types count only once - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ public class PresenceInner { @@ -45,7 +41,7 @@ public void run() throws Exception { File javaFile = writeTestFile(); File classFile = compileTestFile(javaFile); - ClassModel cm = Classfile.of().parse(classFile.toPath()); + ClassModel cm = ClassFile.of().parse(classFile.toPath()); test(cm); for (FieldModel fm : cm.fields()) { test(fm); @@ -59,7 +55,7 @@ public void run() throws Exception { // visit inner class File innerFile = new File("Test$1Inner.class"); - ClassModel icm = Classfile.of().parse(innerFile.toPath()); + ClassModel icm = ClassFile.of().parse(innerFile.toPath()); test(icm); for (FieldModel fm : icm.fields()) { test(fm); diff --git a/test/langtools/tools/javap/typeAnnotations/TypeCasts.java b/test/langtools/tools/javap/typeAnnotations/TypeCasts.java index 0382301cae2c0..6d318107c92d1 100644 --- a/test/langtools/tools/javap/typeAnnotations/TypeCasts.java +++ b/test/langtools/tools/javap/typeAnnotations/TypeCasts.java @@ -21,8 +21,8 @@ * questions. */ -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; import java.io.*; /* @@ -30,11 +30,7 @@ * @bug 6843077 * @summary test that typecasts annotation are emitted if only the cast * expression is optimized away - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ public class TypeCasts { @@ -46,7 +42,7 @@ public void run() throws Exception { File javaFile = writeTestFile(); File classFile = compileTestFile(javaFile); - ClassModel cm = Classfile.of().parse(classFile.toPath()); + ClassModel cm = ClassFile.of().parse(classFile.toPath()); for (MethodModel mm: cm.methods()) { test(mm); } diff --git a/test/langtools/tools/javap/typeAnnotations/Visibility.java b/test/langtools/tools/javap/typeAnnotations/Visibility.java index a332ecc228225..d2f16b49d9b71 100644 --- a/test/langtools/tools/javap/typeAnnotations/Visibility.java +++ b/test/langtools/tools/javap/typeAnnotations/Visibility.java @@ -22,19 +22,15 @@ */ import java.io.*; -import jdk.internal.classfile.*; -import jdk.internal.classfile.Attributes; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.Attributes; +import java.lang.classfile.attribute.*; /* * @test Visibility * @bug 6843077 * @summary test that type annotations are recorded in the classfile - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ public class Visibility { @@ -46,7 +42,7 @@ public void run() throws Exception { File javaFile = writeTestFile(); File classFile = compileTestFile(javaFile); - ClassModel cm = Classfile.of().parse(classFile.toPath()); + ClassModel cm = ClassFile.of().parse(classFile.toPath()); for (MethodModel mm: cm.methods()) { test(mm); } diff --git a/test/langtools/tools/javap/typeAnnotations/Wildcards.java b/test/langtools/tools/javap/typeAnnotations/Wildcards.java index bc2cd3d44235d..8ef0bb61e075c 100644 --- a/test/langtools/tools/javap/typeAnnotations/Wildcards.java +++ b/test/langtools/tools/javap/typeAnnotations/Wildcards.java @@ -22,18 +22,14 @@ */ import java.io.*; -import jdk.internal.classfile.*; -import jdk.internal.classfile.attribute.*; +import java.lang.classfile.*; +import java.lang.classfile.attribute.*; /* * @test Wildcards * @bug 6843077 * @summary test that annotations target wildcards get emitted to classfile - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components + * @enablePreview */ public class Wildcards { public static void main(String[] args) throws Exception { @@ -44,7 +40,7 @@ public void run() throws Exception { File javaFile = writeTestFile(); File classFile = compileTestFile(javaFile); - ClassModel cm = Classfile.of().parse(classFile.toPath()); + ClassModel cm = ClassFile.of().parse(classFile.toPath()); test(cm); for (FieldModel fm : cm.fields()) { test(fm); diff --git a/test/langtools/tools/jdeps/listdeps/ListModuleDeps.java b/test/langtools/tools/jdeps/listdeps/ListModuleDeps.java index a9e9f78b28d7b..63814220c039c 100644 --- a/test/langtools/tools/jdeps/listdeps/ListModuleDeps.java +++ b/test/langtools/tools/jdeps/listdeps/ListModuleDeps.java @@ -95,6 +95,7 @@ public Object[][] jdkModules() { "java.base/jdk.internal.javac", "java.base/jdk.internal.jmod", "java.base/jdk.internal.misc", + "java.base/jdk.internal.module", "java.base/sun.reflect.annotation", "java.compiler", "jdk.internal.opt/jdk.internal.opt", diff --git a/test/lib/jdk/test/lib/jfr/EventNames.java b/test/lib/jdk/test/lib/jfr/EventNames.java index 2ce34ed5b5a4a..0d6afe53dafb5 100644 --- a/test/lib/jdk/test/lib/jfr/EventNames.java +++ b/test/lib/jdk/test/lib/jfr/EventNames.java @@ -88,6 +88,7 @@ public class EventNames { public static final String NativeMemoryUsageTotal = PREFIX + "NativeMemoryUsageTotal"; public static final String JavaAgent = PREFIX + "JavaAgent"; public static final String NativeAgent = PREFIX + "NativeAgent"; + public static final String DeprecatedInvocation = PREFIX + "DeprecatedInvocation"; // This event is hard to test public static final String ReservedStackActivation = PREFIX + "ReservedStackActivation"; diff --git a/test/lib/jdk/test/lib/jfr/Events.java b/test/lib/jdk/test/lib/jfr/Events.java index e3e5979817962..5a180659f9fcf 100644 --- a/test/lib/jdk/test/lib/jfr/Events.java +++ b/test/lib/jdk/test/lib/jfr/Events.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -271,7 +271,12 @@ public static boolean isEventType(RecordedEvent event, String typeName) { * @throws IOException if an event set could not be created due to I/O * errors. */ + private static long lastId = -1; public static List fromRecording(Recording recording) throws IOException { + if (recording.getId() == lastId) { + throw new IOException("Recording with id " + lastId + " has already been dumped. Store the results in a List instead of dumping the recording again"); + } + lastId = recording.getId(); return RecordingFile.readAllEvents(makeCopy(recording)); } diff --git a/test/lib/jdk/test/lib/process/OutputAnalyzer.java b/test/lib/jdk/test/lib/process/OutputAnalyzer.java index fab7b99196def..e316248fe8ee5 100644 --- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java +++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java @@ -42,6 +42,8 @@ public final class OutputAnalyzer { private static final String deprecatedmsg = ".* VM warning:.* deprecated.*"; + private static final String FATAL_ERROR_PAT = "# A fatal error has been detected.*"; + private final OutputBuffer buffer; /** * Create an OutputAnalyzer, a utility class for verifying output and exit @@ -621,6 +623,14 @@ public List asLines() { return asLines(getOutput()); } + public List stdoutAsLines() { + return asLines(getStdout()); + } + + public List stderrAsLines() { + return asLines(getStderr()); + } + private List asLines(String buffer) { return Arrays.asList(buffer.split("\\R")); } @@ -786,4 +796,79 @@ private int indexOf(List lines, String regexp, int fromIndex) { return -1; } + private void searchLinesForMultiLinePattern(String[] haystack, String[] needles, boolean verbose) { + + if (needles.length == 0) { + return; + } + + int firstNeedlePos = 0; + for (int i = 0; i < haystack.length; i++) { + if (verbose) { + System.out.println("" + i + ":" + haystack[i]); + } + if (haystack[i].contains(needles[0])) { + if (verbose) { + System.out.println("Matches pattern 0 (\"" + needles[0] + "\")"); + } + firstNeedlePos = i; + break; + } + } + + for (int i = 1; i < needles.length; i++) { + int haystackPos = firstNeedlePos + i; + if (haystackPos < haystack.length) { + if (verbose) { + System.out.println("" + haystackPos + ":" + haystack[haystackPos]); + } + if (haystack[haystackPos].contains(needles[i])) { + if (verbose) { + System.out.println("Matches pattern " + i + "(\"" + needles[i] + "\")"); + } + } else { + String err = "First unmatched pattern: " + i + " (\"" + needles[i] + "\")"; + if (!verbose) { // don't print twice + reportDiagnosticSummary(); + } + throw new RuntimeException(err); + } + } + } + } + + public void stdoutShouldContainMultiLinePattern(String[] needles, boolean verbose) { + String [] stdoutLines = stdoutAsLines().toArray(new String[0]); + searchLinesForMultiLinePattern(stdoutLines, needles, verbose); + } + + public void stdoutShouldContainMultiLinePattern(String... needles) { + stdoutShouldContainMultiLinePattern(needles, true); + } + + public void stderrShouldContainMultiLinePattern(String[] needles, boolean verbose) { + String [] stderrLines = stdoutAsLines().toArray(new String[0]); + searchLinesForMultiLinePattern(stderrLines, needles, verbose); + } + + public void stderrShouldContainMultiLinePattern(String... needles) { + stderrShouldContainMultiLinePattern(needles, true); + } + + public void shouldContainMultiLinePattern(String[] needles, boolean verbose) { + String [] lines = asLines().toArray(new String[0]); + searchLinesForMultiLinePattern(lines, needles, verbose); + } + + public void shouldContainMultiLinePattern(String... needles) { + shouldContainMultiLinePattern(needles, true); + } + + /** + * Assert that we did not crash with a hard VM error (generating an hs_err_pidXXX.log) + */ + public void shouldNotHaveFatalError() { + shouldNotMatch(FATAL_ERROR_PAT); + } + } diff --git a/test/lib/jdk/test/lib/process/OutputBuffer.java b/test/lib/jdk/test/lib/process/OutputBuffer.java index 3741ccbe2ff62..fba2a5f6dcf3f 100644 --- a/test/lib/jdk/test/lib/process/OutputBuffer.java +++ b/test/lib/jdk/test/lib/process/OutputBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -120,6 +120,7 @@ public String get() { private final StreamTask outTask; private final StreamTask errTask; private final Process p; + private volatile Integer exitValue; // null implies we don't yet know private final void logProgress(String state) { System.out.println("[" + Instant.now().toString() + "] " + state @@ -146,14 +147,17 @@ public String getStderr() { @Override public int getExitValue() { + if (exitValue != null) { + return exitValue; + } try { logProgress("Waiting for completion"); boolean aborted = true; try { - int result = p.waitFor(); + exitValue = p.waitFor(); logProgress("Waiting for completion finished"); aborted = false; - return result; + return exitValue; } finally { if (aborted) { logProgress("Waiting for completion FAILED"); diff --git a/test/lib/jdk/test/lib/security/timestamp/TsaSigner.java b/test/lib/jdk/test/lib/security/timestamp/TsaSigner.java index a3647552557d5..22d630f3aa887 100644 --- a/test/lib/jdk/test/lib/security/timestamp/TsaSigner.java +++ b/test/lib/jdk/test/lib/security/timestamp/TsaSigner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -219,7 +219,8 @@ private byte[] createResponse(TsaParam requestParam) throws Exception { new X500Name(issuerName), signerEntry.cert.getSerialNumber(), SignatureUtil.getDigestAlgInPkcs7SignerInfo( - signature, sigAlgo, signerEntry.privateKey, false), + signature, sigAlgo, signerEntry.privateKey, + signerEntry.cert.getPublicKey(), false), AlgorithmId.get(sigAlgo), signature.sign()); diff --git a/test/lib/jdk/test/lib/util/ModuleInfoWriter.java b/test/lib/jdk/test/lib/util/ModuleInfoWriter.java index b241b66555d20..24d7daf35c240 100644 --- a/test/lib/jdk/test/lib/util/ModuleInfoWriter.java +++ b/test/lib/jdk/test/lib/util/ModuleInfoWriter.java @@ -30,17 +30,17 @@ import java.lang.reflect.AccessFlag; import java.nio.ByteBuffer; import java.util.Map; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import java.lang.constant.PackageDesc; -import jdk.internal.classfile.attribute.ModuleAttribute; -import jdk.internal.classfile.attribute.ModuleExportInfo; -import jdk.internal.classfile.attribute.ModuleMainClassAttribute; -import jdk.internal.classfile.attribute.ModuleOpenInfo; -import jdk.internal.classfile.attribute.ModulePackagesAttribute; -import jdk.internal.classfile.attribute.ModuleResolutionAttribute; -import jdk.internal.classfile.attribute.ModuleRequireInfo; -import jdk.internal.classfile.attribute.ModuleTargetAttribute; -import jdk.internal.classfile.constantpool.ModuleEntry; +import java.lang.classfile.attribute.ModuleAttribute; +import java.lang.classfile.attribute.ModuleExportInfo; +import java.lang.classfile.attribute.ModuleMainClassAttribute; +import java.lang.classfile.attribute.ModuleOpenInfo; +import java.lang.classfile.attribute.ModulePackagesAttribute; +import java.lang.classfile.attribute.ModuleResolutionAttribute; +import java.lang.classfile.attribute.ModuleRequireInfo; +import java.lang.classfile.attribute.ModuleTargetAttribute; +import java.lang.classfile.constantpool.ModuleEntry; import jdk.internal.module.ModuleResolution; import jdk.internal.module.ModuleTarget; @@ -52,29 +52,29 @@ public final class ModuleInfoWriter { private static final Map MODULE_MODS_TO_FLAGS = Map.of( - ModuleDescriptor.Modifier.OPEN, Classfile.ACC_OPEN, - ModuleDescriptor.Modifier.SYNTHETIC, Classfile.ACC_SYNTHETIC, - ModuleDescriptor.Modifier.MANDATED, Classfile.ACC_MANDATED + ModuleDescriptor.Modifier.OPEN, ClassFile.ACC_OPEN, + ModuleDescriptor.Modifier.SYNTHETIC, ClassFile.ACC_SYNTHETIC, + ModuleDescriptor.Modifier.MANDATED, ClassFile.ACC_MANDATED ); private static final Map REQUIRES_MODS_TO_FLAGS = Map.of( - ModuleDescriptor.Requires.Modifier.TRANSITIVE, Classfile.ACC_TRANSITIVE, - ModuleDescriptor.Requires.Modifier.STATIC, Classfile.ACC_STATIC_PHASE, - ModuleDescriptor.Requires.Modifier.SYNTHETIC, Classfile.ACC_SYNTHETIC, - ModuleDescriptor.Requires.Modifier.MANDATED, Classfile.ACC_MANDATED + ModuleDescriptor.Requires.Modifier.TRANSITIVE, ClassFile.ACC_TRANSITIVE, + ModuleDescriptor.Requires.Modifier.STATIC, ClassFile.ACC_STATIC_PHASE, + ModuleDescriptor.Requires.Modifier.SYNTHETIC, ClassFile.ACC_SYNTHETIC, + ModuleDescriptor.Requires.Modifier.MANDATED, ClassFile.ACC_MANDATED ); private static final Map EXPORTS_MODS_TO_FLAGS = Map.of( - ModuleDescriptor.Exports.Modifier.SYNTHETIC, Classfile.ACC_SYNTHETIC, - ModuleDescriptor.Exports.Modifier.MANDATED, Classfile.ACC_MANDATED + ModuleDescriptor.Exports.Modifier.SYNTHETIC, ClassFile.ACC_SYNTHETIC, + ModuleDescriptor.Exports.Modifier.MANDATED, ClassFile.ACC_MANDATED ); private static final Map OPENS_MODS_TO_FLAGS = Map.of( - ModuleDescriptor.Opens.Modifier.SYNTHETIC, Classfile.ACC_SYNTHETIC, - ModuleDescriptor.Opens.Modifier.MANDATED, Classfile.ACC_MANDATED + ModuleDescriptor.Opens.Modifier.SYNTHETIC, ClassFile.ACC_SYNTHETIC, + ModuleDescriptor.Opens.Modifier.MANDATED, ClassFile.ACC_MANDATED ); private ModuleInfoWriter() { } @@ -87,7 +87,7 @@ private static byte[] toModuleInfo(ModuleDescriptor md, ModuleResolution mres, ModuleTarget target) { //using low-level module building to avoid validation in ModuleDesc and allow invalid names - return Classfile.of().build(ClassDesc.of("module-info"), clb -> { + return ClassFile.of().build(ClassDesc.of("module-info"), clb -> { clb.withFlags(AccessFlag.MODULE); var cp = clb.constantPool(); clb.with(ModuleAttribute.of(cp.moduleEntry(cp.utf8Entry(md.name())), mb -> { diff --git a/test/lib/jdk/test/whitebox/WhiteBox.java b/test/lib/jdk/test/whitebox/WhiteBox.java index 3743aa506ff94..2d33182331d4f 100644 --- a/test/lib/jdk/test/whitebox/WhiteBox.java +++ b/test/lib/jdk/test/whitebox/WhiteBox.java @@ -522,6 +522,8 @@ public void clearInlineCaches(boolean preserve_static_stubs) { public native long metaspaceCapacityUntilGC(); public native long metaspaceSharedRegionAlignment(); + public native void cleanMetaspaces(); + // Metaspace Arena Tests public native long createMetaspaceTestContext(long commit_limit, long reserve_limit); public native void destroyMetaspaceTestContext(long context); @@ -785,6 +787,10 @@ public native int validateCgroup(String procCgroups, public native void unlockCritical(); + public native void pinObject(Object o); + + public native void unpinObject(Object o); + public native boolean setVirtualThreadsNotifyJvmtiMode(boolean enabled); public native void preTouchMemory(long addr, long size); diff --git a/test/micro/org/openjdk/bench/java/lang/StringConstructor.java b/test/micro/org/openjdk/bench/java/lang/StringConstructor.java index 1509d6b798f0f..e9ed0022edafe 100644 --- a/test/micro/org/openjdk/bench/java/lang/StringConstructor.java +++ b/test/micro/org/openjdk/bench/java/lang/StringConstructor.java @@ -21,11 +21,13 @@ * questions. */ -package micro.org.openjdk.bench.java.lang; +package org.openjdk.bench.java.lang; import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.concurrent.TimeUnit; @State(Scope.Thread) @@ -36,45 +38,115 @@ @Fork(3) public class StringConstructor { - @Param({"7", "64"}) - public int size; - - // Offset to use for ranged newStrings - @Param("1") - public int offset; - private byte[] array; - - @Setup - public void setup() { - if (offset > size) { - offset = size; - } - array = "a".repeat(size).getBytes(StandardCharsets.UTF_8); - } - - @Benchmark - public String newStringFromArray() { - return new String(array); - } - - @Benchmark - public String newStringFromArrayWithCharset() { - return new String(array, StandardCharsets.UTF_8); - } - - @Benchmark - public String newStringFromArrayWithCharsetName() throws Exception { - return new String(array, StandardCharsets.UTF_8.name()); - } - - @Benchmark - public String newStringFromRangedArray() { - return new String(array, offset, array.length - offset); - } - - @Benchmark - public String newStringFromRangedArrayWithCharset() { - return new String(array, offset, array.length - offset, StandardCharsets.UTF_8); - } + private static final char INTEROBANG = 0x2030; + // Fixed offset to use for ranged newStrings + public final int offset = 1; + + @Param({"7", "64"}) + public int size; + + private byte[] array; + private char[] chars; + private char[] charsMixedBegin; + private char[] charsMixedSmall; + private char[] charsMixedEnd; + private int[] codePointsLatin1; + private int[] codePointsMixedBegin; + private int[] codePointsMixedSmall; + + private static int[] intCopyOfChars(char[] chars, int newLength) { + int[] res = new int[newLength]; + for (int i = 0; i < Math.min(chars.length, newLength); i++) + res[i] = chars[i]; + return res; + } + + @Setup + public void setup() { + String s = "a".repeat(size); + array = s.getBytes(StandardCharsets.UTF_8); + chars = s.toCharArray(); + charsMixedBegin = Arrays.copyOf(chars, array.length); + charsMixedBegin[0] = INTEROBANG; + charsMixedSmall = Arrays.copyOf(chars, array.length); + charsMixedSmall[Math.min(charsMixedSmall.length - 1, 7)] = INTEROBANG; + charsMixedEnd = new char[size + 7]; + Arrays.fill(charsMixedEnd, 'a'); + charsMixedEnd[charsMixedEnd.length - 1] = INTEROBANG; + + codePointsLatin1 = intCopyOfChars(chars, array.length); + codePointsMixedBegin = intCopyOfChars(chars, array.length); + codePointsMixedBegin[0] = INTEROBANG; + codePointsMixedSmall = intCopyOfChars(chars, array.length); + codePointsMixedSmall[Math.min(codePointsMixedSmall.length - 1, 7)] = INTEROBANG; + } + + @Benchmark + public String newStringFromBytes() { + return new String(array); + } + + @Benchmark + public String newStringFromBytesRanged() { + return new String(array, offset, array.length - offset); + } + + @Benchmark + public String newStringFromBytesRangedWithCharsetUTF8() { + return new String(array, offset, array.length - offset, StandardCharsets.UTF_8); + } + + @Benchmark + public String newStringFromBytesWithCharsetUTF8() { + return new String(array, StandardCharsets.UTF_8); + } + + @Benchmark + public String newStringFromBytesWithCharsetNameUTF8() throws Exception { + return new String(array, StandardCharsets.UTF_8.name()); + } + + @Benchmark + public String newStringFromCharsLatin1() { + return new String(chars); + } + + @Benchmark + public String newStringFromCharsMixedBegin() { + return new String(charsMixedBegin); + } + + @Benchmark + public String newStringFromCharsMixedSmall() { + return new String(charsMixedSmall); + } + + @Benchmark + public String newStringFromCharsMixedEnd() { + return new String(charsMixedEnd); + } + + @Benchmark + @CompilerControl(CompilerControl.Mode.DONT_INLINE) + public void newStringFromCharsMixedAll(Blackhole bh) { + bh.consume(new String(charsMixedBegin)); + bh.consume(new String(charsMixedSmall)); + bh.consume(new String(chars)); + } + + @Benchmark + public String newStringFromCodePointRangedLatin1() { + return new String(codePointsLatin1, 0, codePointsLatin1.length); + } + + @Benchmark + public String newStringFromCodePointRangedMixedBegin() { + return new String(codePointsMixedBegin, 0, codePointsMixedBegin.length); + } + + @Benchmark + public String newStringFromCodePointRangedMixedSmall() { + return new String(codePointsMixedSmall, 0, codePointsMixedSmall.length); + } } diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/CLayouts.java b/test/micro/org/openjdk/bench/java/lang/foreign/CLayouts.java index 978765c2c79df..bfe5ce61b1c2f 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/CLayouts.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/CLayouts.java @@ -56,7 +56,7 @@ public class CLayouts { /** * The layout for the {@code long long} C type. */ - public static final ValueLayout.OfLong C_LONG_LONG = (ValueLayout.OfLong) LINKER.canonicalLayouts().get("long"); + public static final ValueLayout.OfLong C_LONG_LONG = (ValueLayout.OfLong) LINKER.canonicalLayouts().get("long long"); /** * The layout for the {@code float} C type */ diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/xor/libjnitest.c b/test/micro/org/openjdk/bench/java/lang/foreign/xor/libjnitest.c index 2b74dc9c3d780..2ecea5f2b8324 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/xor/libjnitest.c +++ b/test/micro/org/openjdk/bench/java/lang/foreign/xor/libjnitest.c @@ -1,6 +1,8 @@ #include #include +#include "jlong.h" + JNIEXPORT void xor_op(jbyte *restrict src, jbyte *restrict dst, jint len) { for (int i = 0; i < len; ++i) { dst[i] ^= src[i]; @@ -69,7 +71,7 @@ JNIEXPORT void JNICALL Java_org_openjdk_bench_java_lang_foreign_xor_GetArrayRegi JNIEXPORT void JNICALL Java_org_openjdk_bench_java_lang_foreign_xor_GetArrayUnsafeXorOpImpl_xorOp (JNIEnv *env, jobject obj, jlong src, jlong dst, jint len) { - jbyte *sbuf = (jbyte*)(void*)src; - jbyte *dbuf = (jbyte*)(void*)dst; + jbyte *sbuf = (jbyte*)jlong_to_ptr(src); + jbyte *dbuf = (jbyte*)jlong_to_ptr(dst); xor_op(sbuf, dbuf, len); } diff --git a/test/micro/org/openjdk/bench/java/lang/invoke/LazyStaticColdStart.java b/test/micro/org/openjdk/bench/java/lang/invoke/LazyStaticColdStart.java index 976554a259aa6..45fc67aea25a2 100644 --- a/test/micro/org/openjdk/bench/java/lang/invoke/LazyStaticColdStart.java +++ b/test/micro/org/openjdk/bench/java/lang/invoke/LazyStaticColdStart.java @@ -22,7 +22,7 @@ */ package org.openjdk.bench.java.lang.invoke; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassFile; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; @@ -43,7 +43,7 @@ import java.util.concurrent.TimeUnit; import static java.lang.constant.ConstantDescs.*; -import static jdk.internal.classfile.Classfile.ACC_STATIC; +import static java.lang.classfile.ClassFile.ACC_STATIC; /** * A benchmark ensuring that var and method handle lazy initialization are not @@ -53,11 +53,7 @@ @OutputTimeUnit(TimeUnit.MICROSECONDS) @State(Scope.Thread) @Fork(value = 10, warmups = 5, jvmArgsAppend = { - "--add-exports", "java.base/jdk.internal.classfile=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.attribute=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.instruction=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.components=ALL-UNNAMED" + "--enable-preview" }) public class LazyStaticColdStart { private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); @@ -77,7 +73,7 @@ class Holder { static final MethodTypeDesc MTD_void_long = MethodTypeDesc.of(CD_void, CD_long); static final MethodTypeDesc MTD_ThreadLocalRandom = MethodTypeDesc.of(CD_ThreadLocalRandom); static final MethodTypeDesc MTD_long = MethodTypeDesc.of(CD_long); - static final byte[] classBytes = Classfile.of().build(describedClass, clb -> { + static final byte[] classBytes = ClassFile.of().build(describedClass, clb -> { clb.withField("v", CD_long, ACC_STATIC); clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> { cob.constantInstruction(100L); diff --git a/test/micro/org/openjdk/bench/java/nio/ByteBuffers.java b/test/micro/org/openjdk/bench/java/nio/ByteBuffers.java index 48f75a3ec8117..c2f4e93313c91 100644 --- a/test/micro/org/openjdk/bench/java/nio/ByteBuffers.java +++ b/test/micro/org/openjdk/bench/java/nio/ByteBuffers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -923,4 +923,9 @@ public double testDirectLoopGetDouble() { } return r; } + + @Benchmark + public int testHeapHashCode() { + return heapByteBuffer.hashCode(); + } } diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/BenchmarkGathererImpls.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/BenchmarkGathererImpls.java new file mode 100644 index 0000000000000..623500f16c246 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/BenchmarkGathererImpls.java @@ -0,0 +1,272 @@ +package org.openjdk.bench.java.util.stream.ops.ref; + +import java.util.Objects; +import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Gatherer; +import java.util.stream.Stream; + +// Utility Gatherer and Collector implementations used by Gatherer micro-benchmarks +public final class BenchmarkGathererImpls { + + public static Gatherer filter(Predicate predicate) { + return new FilteringGatherer<>(predicate); + } + + public final static Gatherer map(Function mapper) { + return new MappingGatherer<>(Objects.requireNonNull(mapper)); + } + + public static Gatherer reduce(BinaryOperator reduce) { + Objects.requireNonNull(reduce); + return new ReducingGatherer<>(reduce); + } + + public final static Gatherer takeWhile(Predicate predicate) { + return new TakeWhileGatherer<>(Objects.requireNonNull(predicate)); + } + + @SuppressWarnings("unchecked") + public final static Collector> findFirst() { + return (Collector>)FIND_FIRST; + } + + @SuppressWarnings("unchecked") + public final static Collector> findLast() { + return (Collector>)FIND_LAST; + } + + @SuppressWarnings("rawtypes") + private final static Collector FIND_FIRST = + Collector.,Optional>of( + () -> new Box<>(), + (b,e) -> { + if (!b.hasValue) { + b.value = e; + b.hasValue = true; + } + }, + (l,r) -> l.hasValue ? l : r, + b -> b.hasValue ? Optional.of(b.value) : Optional.empty() + ); + + @SuppressWarnings("rawtypes") + private final static Collector FIND_LAST = + Collector.,Optional>of( + () -> new Box<>(), + (b,e) -> { + b.value = e; + if (!b.hasValue) + b.hasValue = true; + }, + (l,r) -> r.hasValue ? r : l, + b -> b.hasValue ? Optional.of(b.value) : Optional.empty() + ); + + public final static Gatherer flatMap(Function> mapper) { + Objects.requireNonNull(mapper); + + class FlatMappingGatherer implements Gatherer, Gatherer.Integrator, BinaryOperator { + @Override public Integrator integrator() { return this; } + + // Ideal encoding, but performance-wise suboptimal due to cost of allMatch--about factor-10 worse. + /*@Override public boolean integrate(Void state, T element, Gatherer.Downstream downstream) { + try(Stream s = mapper.apply(element)) { + return s != null ? s.sequential().allMatch(downstream::flush) : true; + } + }*/ + + //The version below performs better, but is not nice to maintain or explain. + + private final static RuntimeException SHORT_CIRCUIT = new RuntimeException() { + @Override public synchronized Throwable fillInStackTrace() { return this; } + }; + + @Override public boolean integrate(Void state, T element, Gatherer.Downstream downstream) { + try (Stream s = mapper.apply(element)) { + if (s != null) { + s.sequential().spliterator().forEachRemaining(e -> { + if (!downstream.push(e)) throw SHORT_CIRCUIT; + }); + } + return true; + } catch (RuntimeException e) { + if (e == SHORT_CIRCUIT) + return false; + + throw e; // Rethrow anything else + } + } + + @Override public BinaryOperator combiner() { return this; } + @Override public Void apply(Void unused, Void unused2) { return unused; } + } + + return new FlatMappingGatherer(); + } + + final static class MappingGatherer implements Gatherer, Gatherer.Integrator.Greedy, BinaryOperator { + final Function mapper; + + MappingGatherer(Function mapper) { this.mapper = mapper; } + + @Override public Integrator integrator() { return this; } + @Override public BinaryOperator combiner() { return this; } + @Override public Void apply(Void left, Void right) { return left; } + + @Override + public Gatherer andThen(Gatherer that) { + if (that.getClass() == MappingGatherer.class) { // Implicit null-check of that + @SuppressWarnings("unchecked") + var thatMapper = ((MappingGatherer)that).mapper; + return new MappingGatherer<>(this.mapper.andThen(thatMapper)); + } else + return Gatherer.super.andThen(that); + } + + @Override + public boolean integrate(Void state, T element, Gatherer.Downstream downstream) { + return downstream.push(mapper.apply(element)); + } + } + + + final static class FilteringGatherer implements Gatherer, Gatherer.Integrator.Greedy, BinaryOperator { + final Predicate predicate; + + protected FilteringGatherer(Predicate predicate) { this.predicate = predicate; } + + @Override public Integrator integrator() { return this; } + @Override public BinaryOperator combiner() { return this; } + + @Override public Void apply(Void left, Void right) { return left; } + + @Override + public boolean integrate(Void state, TR element, Gatherer.Downstream downstream) { + return predicate.test(element) ? downstream.push(element) : true; + } + + @Override + @SuppressWarnings("unchecked") + public Gatherer andThen(Gatherer that) { + if (that.getClass() == FilteringGatherer.class) { + var first = predicate; + var second = ((FilteringGatherer) that).predicate; + return (Gatherer) new FilteringGatherer(e -> first.test(e) && second.test(e)); + } else if (that.getClass() == MappingGatherer.class) { + final var thatMapper = (MappingGatherer)that; + return new FilteringMappingGatherer<>(predicate, thatMapper.mapper); + } else if (that.getClass() == FilteringMappingGatherer.class) { + var first = predicate; + var thatFilterMapper = ((FilteringMappingGatherer) that); + var second = thatFilterMapper.predicate; + return new FilteringMappingGatherer<>(e -> first.test(e) && second.test(e), thatFilterMapper.mapper); + } else + return Gatherer.super.andThen(that); + } + } + + final static class FilteringMappingGatherer implements Gatherer, Gatherer.Integrator.Greedy, BinaryOperator { + final Predicate predicate; + final Function mapper; + + FilteringMappingGatherer(Predicate predicate, Function mapper) { + this.predicate = predicate; + this.mapper = mapper; + } + + @Override public Integrator integrator() { return this; } + @Override public BinaryOperator combiner() { return this; } + @Override public Void apply(Void left, Void right) { return left; } + + @Override + public Gatherer andThen(Gatherer that) { + if (that.getClass() == MappingGatherer.class) { // Implicit null-check of that + @SuppressWarnings("unchecked") + var thatMapper = ((MappingGatherer)that).mapper; + return new FilteringMappingGatherer<>(this.predicate, this.mapper.andThen(thatMapper)); + } else + return Gatherer.super.andThen(that); + } + + @Override + public boolean integrate(Void state, T element, Gatherer.Downstream downstream) { + return !predicate.test(element) || downstream.push(mapper.apply(element)); + } + } + + final static class ReducingGatherer implements Gatherer, TR>, + Supplier>, + Gatherer.Integrator.Greedy, TR, TR>, + BinaryOperator>, + BiConsumer, Gatherer.Downstream> { + private final BinaryOperator reduce; + ReducingGatherer(BinaryOperator reduce) { this.reduce = reduce; } + + @Override public Box get() { return new Box<>(); } + + @Override + public boolean integrate(Box state, TR m, Gatherer.Downstream downstream) { + state.value = state.hasValue || !(state.hasValue = true) ? reduce.apply(state.value, m) : m; + return true; + } + + @Override public Box apply(Box left, Box right) { + if (right.hasValue) + integrate(left, right.value, null); + return left; + } + + @Override public void accept(Box box, Gatherer.Downstream downstream) { + if (box.hasValue) + downstream.push(box.value); + } + + @Override public Supplier> initializer() { return this; } + @Override public Integrator, TR, TR> integrator() { return this; } + @Override public BinaryOperator> combiner() { return this; } + @Override public BiConsumer, Gatherer.Downstream> finisher() { return this; } + } + + final static class TakeWhileGatherer implements Gatherer, Gatherer.Integrator, BinaryOperator { + final Predicate predicate; + TakeWhileGatherer(Predicate predicate) { this.predicate = predicate; } + + @Override public Integrator integrator() { return this; } + @Override public BinaryOperator combiner() { return this; } + + @Override public Void apply(Void left, Void right) { return left; } + + @Override public boolean integrate(Void state, TR element, Gatherer.Downstream downstream) { + return predicate.test(element) && downstream.push(element); + } + + @Override + @SuppressWarnings("unchecked") + public final Gatherer andThen(Gatherer that) { + if (that.getClass() == TakeWhileGatherer.class) { + final var thisPredicate = predicate; + final var thatPredicate = ((TakeWhileGatherer)that).predicate; + return (Gatherer)new TakeWhileGatherer(e -> thisPredicate.test(e) && thatPredicate.test(e)); + } + else + return Gatherer.super.andThen(that); + } + } + + final static class Box { + T value; + boolean hasValue; + + Box() {} + } +} \ No newline at end of file diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFMRPar.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFMRPar.java new file mode 100644 index 0000000000000..476299df76e5a --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFMRPar.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util.stream.ops.ref; + +import org.openjdk.bench.java.util.stream.ops.LongAccumulator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.Arrays; +import java.util.stream.Gatherer; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.filter; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.map; + +/** + * Benchmark for filter+map+reduce operations implemented as Gatherer, with the default map implementation of Stream as baseline. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 7, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(jvmArgsAppend = "--enable-preview", value = 1) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class GatherFMRPar { + + @Param({"10","100","1000000"}) + private int size; + + private Function squared; + private Predicate evens; + + private Gatherer gathered; + private Gatherer ga_map_squared; + private Gatherer ga_filter_evens; + + private Long[] cachedInputArray; + + @Setup + public void setup() { + cachedInputArray = new Long[size]; + for(int i = 0;i < size;++i) + cachedInputArray[i] = Long.valueOf(i); + + squared = new Function() { @Override public Long apply(Long l) { return l*l; } }; + evens = new Predicate() { @Override public boolean test(Long l) { + return l % 2 == 0; + } }; + + ga_map_squared = map(squared); + ga_filter_evens = filter(evens); + + gathered = ga_filter_evens.andThen(ga_map_squared); + } + + @Benchmark + public long par_fmr_baseline() { + return Arrays.stream(cachedInputArray) + .parallel() + .filter(evens) + .map(squared) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_fmr_gather() { + return Arrays.stream(cachedInputArray) + .parallel() + .gather(filter(evens)) + .gather(map(squared)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_fmr_gather_preallocated() { + return Arrays.stream(cachedInputArray) + .parallel() + .gather(ga_filter_evens) + .gather(ga_map_squared) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_fmr_gather_composed() { + return Arrays.stream(cachedInputArray) + .parallel() + .gather(filter(evens).andThen(map(squared))) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_fmr_gather_composed_preallocated() { + return Arrays.stream(cachedInputArray) + .parallel() + .gather(filter(evens).andThen(map(squared))) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_fmr_gather_precomposed() { + return Arrays.stream(cachedInputArray) + .parallel() + .gather(gathered) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } +} diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFMRSeq.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFMRSeq.java new file mode 100644 index 0000000000000..05e48e16d075b --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFMRSeq.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util.stream.ops.ref; + +import org.openjdk.bench.java.util.stream.ops.LongAccumulator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.Arrays; +import java.util.stream.Gatherer; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.filter; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.map; + +/** + * Benchmark for filter+map+reduce operations implemented as Gatherer, with the default map implementation of Stream as baseline. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 7, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(jvmArgsAppend = "--enable-preview", value = 1) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class GatherFMRSeq { + + @Param({"10","100","1000000"}) + private int size; + + private Function squared; + private Predicate evens; + + private Gatherer gathered; + private Gatherer ga_map_squared; + private Gatherer ga_filter_evens; + + private Long[] cachedInputArray; + + @Setup + public void setup() { + cachedInputArray = new Long[size]; + for(int i = 0;i < size;++i) + cachedInputArray[i] = Long.valueOf(i); + + squared = new Function() { @Override public Long apply(Long l) { return l*l; } }; + evens = new Predicate() { @Override public boolean test(Long l) { + return l % 2 == 0; + } }; + + ga_map_squared = map(squared); + ga_filter_evens = filter(evens); + + gathered = ga_filter_evens.andThen(ga_map_squared); + } + + @Benchmark + public long seq_fmr_baseline() { + return Arrays.stream(cachedInputArray) + .filter(evens) + .map(squared) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_fmr_gather() { + return Arrays.stream(cachedInputArray) + .gather(filter(evens)) + .gather(map(squared)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_fmr_gather_preallocated() { + return Arrays.stream(cachedInputArray) + .gather(ga_filter_evens) + .gather(ga_map_squared) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_fmr_gather_composed() { + return Arrays.stream(cachedInputArray) + .gather(filter(evens).andThen(map(squared))) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_fmr_gather_composed_preallocated() { + return Arrays.stream(cachedInputArray) + .gather(filter(evens).andThen(map(squared))) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_fmr_gather_precomposed() { + return Arrays.stream(cachedInputArray) + .gather(gathered) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } +} diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFlatMapInfinitySeq.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFlatMapInfinitySeq.java new file mode 100644 index 0000000000000..09c38f8348432 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFlatMapInfinitySeq.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util.stream.ops.ref; + +import org.openjdk.bench.java.util.stream.ops.LongAccumulator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.Arrays; +import java.util.stream.Stream; +import java.util.stream.Gatherer; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.flatMap; + +/** + * Benchmark for map() operation implemented as Gatherer, with the default map implementation of Stream as baseline. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 7, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(jvmArgsAppend = "--enable-preview", value = 1) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class GatherFlatMapInfinitySeq { + + /** + * Implementation notes: + * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison + * - operations are explicit inner classes to untangle unwanted lambda effects + * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink + */ + + @Param({"10", "100", "1000"}) + private int size; + + private Function> funInf; + + private Long[] cachedInputArray; + + private Gatherer gather_flatMap_inf; + + @Setup + public void setup() { + cachedInputArray = new Long[size]; + for(int i = 0;i < size;++i) + cachedInputArray[i] = Long.valueOf(i); + + funInf = new Function>() { @Override public Stream apply(Long l) { + return Stream.generate(() -> l); + } }; + + gather_flatMap_inf = flatMap(funInf); + } + + @Benchmark + public long seq_invoke_baseline() { + return Arrays.stream(cachedInputArray) + .flatMap(funInf) + .limit(size * 5) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_invoke_gather() { + return Arrays.stream(cachedInputArray) + .gather(flatMap(funInf)) + .limit(size * 5) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_invoke_gather_preallocated() { + return Arrays.stream(cachedInputArray) + .gather(gather_flatMap_inf) + .limit(size * 5) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } +} diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFlatMapSeq.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFlatMapSeq.java new file mode 100644 index 0000000000000..a13ee01a8514b --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherFlatMapSeq.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util.stream.ops.ref; + +import org.openjdk.bench.java.util.stream.ops.LongAccumulator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.Arrays; +import java.util.stream.Stream; +import java.util.stream.Gatherer; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.flatMap; + +/** + * Benchmark for map() operation implemented as Gatherer, with the default map implementation of Stream as baseline. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 7, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(jvmArgsAppend = "--enable-preview", value = 1) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class GatherFlatMapSeq { + + /** + * Implementation notes: + * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison + * - operations are explicit inner classes to untangle unwanted lambda effects + * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink + */ + + @Param({"10", "100", "1000"}) + private int size; + + private Function> fun; + + private Gatherer gather_flatMap; + + private Long[] cachedInputArray; + + @Setup + public void setup() { + cachedInputArray = new Long[size]; + for(int i = 0;i < size;++i) + cachedInputArray[i] = Long.valueOf(i); + + fun = new Function>() { @Override public Stream apply(Long l) { + return Arrays.stream(cachedInputArray); + } }; + + gather_flatMap = flatMap(fun); + } + + @Benchmark + public long seq_invoke_baseline() { + return Arrays.stream(cachedInputArray) + .flatMap(fun) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_invoke_gather() { + return Arrays.stream(cachedInputArray) + .gather(flatMap(fun)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_invoke_gather_preallocated() { + return Arrays.stream(cachedInputArray) + .gather(gather_flatMap) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } +} diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMapPar.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMapPar.java new file mode 100644 index 0000000000000..62c2d03b1b1af --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMapPar.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util.stream.ops.ref; + +import org.openjdk.bench.java.util.stream.ops.LongAccumulator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.stream.Stream; +import java.util.stream.Gatherer; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.map; + +/** + * Benchmark for map() operation implemented as Gatherer, with the default map implementation of Stream as baseline. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 7, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(jvmArgsAppend = "--enable-preview", value = 1) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class GatherMapPar { + + /** + * Implementation notes: + * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison + * - operations are explicit inner classes to untangle unwanted lambda effects + * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink + */ + @Param({"10","100","1000000"}) + private int size; + + private Function m1, m2, m3; + + private Gatherer gather_m1, gather_m2, gather_m3, gather_all, gather_m1_111; + + private Long[] cachedInputArray; + + @Setup + public void setup() { + cachedInputArray = new Long[size]; + for(int i = 0;i < size;++i) + cachedInputArray[i] = Long.valueOf(i); + + m1 = new Function() { @Override public Long apply(Long l) { return l*2; } }; + m2 = new Function() { @Override public Long apply(Long l) { return l*2; } }; + m3 = new Function() { @Override public Long apply(Long l) { return l*2; } }; + gather_m1 = map(m1); + gather_m2 = map(m2); + gather_m3 = map(m3); + gather_all = gather_m1.andThen(gather_m2.andThen(gather_m3)); + gather_m1_111 = gather_m1.andThen(gather_m1.andThen(gather_m1)); + } + + @Benchmark + public long par_invoke_baseline() { + return Arrays.stream(cachedInputArray).parallel() + .map(m1) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_invoke_gather() { + return Arrays.stream(cachedInputArray).parallel() + .gather(map(m1)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_invoke_gather_preallocated() { + return Arrays.stream(cachedInputArray).parallel() + .gather(gather_m1) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_chain_111_baseline() { + return Arrays.stream(cachedInputArray).parallel() + .map(m1) + .map(m1) + .map(m1) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_chain_111_gather_separate() { + return Arrays.stream(cachedInputArray).parallel() + .gather(map(m1)) + .gather(map(m1)) + .gather(map(m1)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_chain_111_gather_composed() { + return Arrays.stream(cachedInputArray).parallel() + .gather(gather_m1.andThen(gather_m1).andThen(gather_m1)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_chain_111_gather_precomposed() { + return Arrays.stream(cachedInputArray).parallel() + .gather(gather_m1_111) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_chain_123_baseline() { + return Arrays.stream(cachedInputArray).parallel() + .map(m1) + .map(m2) + .map(m3) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_chain_123_gather_separate() { + return Arrays.stream(cachedInputArray).parallel() + .gather(map(m1)) + .gather(map(m2)) + .gather(map(m3)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_chain_123_gather_composed() { + return Arrays.stream(cachedInputArray).parallel() + .gather(map(m1).andThen(map(m2).andThen(map(m3)))) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_chain_123_gather_precomposed() { + return Arrays.stream(cachedInputArray).parallel() + .gather(gather_all) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } +} diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMapSeq.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMapSeq.java new file mode 100644 index 0000000000000..1e842c0c09e7d --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMapSeq.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util.stream.ops.ref; + +import org.openjdk.bench.java.util.stream.ops.LongAccumulator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.Arrays; +import java.util.stream.Collector; +import java.util.stream.Gatherer; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.map; + +/** + * Benchmark for map() operation implemented as Gatherer, with the default map implementation of Stream as baseline. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 7, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(jvmArgsAppend = "--enable-preview", value = 1) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class GatherMapSeq { + + /** + * Implementation notes: + * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison + * - operations are explicit inner classes to untangle unwanted lambda effects + * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink + */ + + @Param({"10", "100", "1000000"}) + private int size; + + private Function m1, m2, m3; + + private Gatherer gather_m1, gather_m2, gather_m3, gather_all, gather_m1_111; + + private Long[] cachedInputArray; + + private final static Collector accumulate = + Collector.of(LongAccumulator::new, + LongAccumulator::add, + (l,r) -> { l.merge(r); return l; }, + LongAccumulator::get); + + @Setup + public void setup() { + cachedInputArray = new Long[size]; + for(int i = 0;i < size;++i) + cachedInputArray[i] = Long.valueOf(i); + m1 = new Function() { @Override public Long apply(Long l) { + return l*2; + } }; + m2 = new Function() { @Override public Long apply(Long l) { + return l*2; + } }; + m3 = new Function() { @Override public Long apply(Long l) { + return l*2; + } }; + gather_m1 = map(m1); + gather_m2 = map(m2); + gather_m3 = map(m3); + gather_all = gather_m1.andThen(gather_m2.andThen(gather_m3)); + gather_m1_111 = gather_m1.andThen(gather_m1.andThen(gather_m1)); + } + + @Benchmark + public long seq_invoke_baseline() { + return Arrays.stream(cachedInputArray) + .map(m1) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_invoke_gather() { + return Arrays.stream(cachedInputArray) + .gather(map(m1)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_invoke_gather_preallocated() { + return Arrays.stream(cachedInputArray) + .gather(gather_m1) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_chain_111_baseline() { + return Arrays.stream(cachedInputArray) + .map(m1) + .map(m1) + .map(m1) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_chain_111_gather_separate() { + return Arrays.stream(cachedInputArray) + .gather(map(m1)) + .gather(map(m1)) + .gather(map(m1)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_chain_111_gather_composed() { + return Arrays.stream(cachedInputArray) + .gather(map(m1).andThen(map(m1)).andThen(map(m1))) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_chain_111_gather_precomposed() { + return Arrays.stream(cachedInputArray) + .gather(gather_m1_111) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_chain_123_baseline() { + return Arrays.stream(cachedInputArray) + .map(m1) + .map(m2) + .map(m3) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_chain_123_gather_separate() { + return Arrays.stream(cachedInputArray) + .gather(map(m1)) + .gather(map(m2)) + .gather(map(m3)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_chain_123_gather_composed() { + return Arrays.stream(cachedInputArray) + .gather(map(m1).andThen(map(m2)).andThen(map(m3))) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_chain_123_gather_precomposed() { + return Arrays.stream(cachedInputArray) + .gather(gather_all) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } +} diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMiscPar.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMiscPar.java new file mode 100644 index 0000000000000..578e470ec5cb3 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMiscPar.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util.stream.ops.ref; + +import org.openjdk.bench.java.util.stream.ops.LongAccumulator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.Arrays; +import java.util.stream.Gatherer; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.filter; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.map; + +/** + * Benchmark for misc operations implemented as Gatherer, with the default map implementation of Stream as baseline. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 7, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(jvmArgsAppend = "--enable-preview", value = 1) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class GatherMiscPar { + + /** + * Implementation notes: + * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison + * - operations are explicit inner classes to untangle unwanted lambda effects + * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink + */ + + @Param({"10","100","1000000"}) + private int size; + + private Function timesTwo, halved; + private Predicate evens, odds; + + private Gatherer gathered; + + private Long[] cachedInputArray; + + @Setup + public void setup() { + cachedInputArray = new Long[size]; + for(int i = 0;i < size;++i) + cachedInputArray[i] = Long.valueOf(i); + + timesTwo = new Function() { @Override public Long apply(Long l) { + return l*2; + } }; + halved = new Function() { @Override public Long apply(Long l) { return l/2; } }; + + evens = new Predicate() { @Override public boolean test(Long l) { + return l % 2 == 0; + } }; + odds = new Predicate() { @Override public boolean test(Long l) { + return l % 2 != 0; + } }; + + gathered = filter(odds) + .andThen(map(timesTwo)) + .andThen(map(halved)) + .andThen(filter(evens)); + } + + @Benchmark + public long par_misc_baseline() { + return Arrays.stream(cachedInputArray) + .parallel() + .filter(odds) + .map(timesTwo) + .map(halved) + .filter(evens) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_misc_gather() { + return Arrays.stream(cachedInputArray) + .parallel() + .gather(filter(odds)) + .gather(map(timesTwo)) + .gather(map(halved)) + .gather(filter(evens)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_misc_gather_precomposed() { + return Arrays.stream(cachedInputArray) + .parallel() + .gather(gathered) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } +} diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMiscSeq.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMiscSeq.java new file mode 100644 index 0000000000000..0d7d9bdef9f49 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherMiscSeq.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util.stream.ops.ref; + +import org.openjdk.bench.java.util.stream.ops.LongAccumulator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Gatherer; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.filter; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.findLast; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.map; + +/** + * Benchmark for misc operations implemented as Gatherer, with the default map implementation of Stream as baseline. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 7, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(jvmArgsAppend = "--enable-preview", value = 1) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class GatherMiscSeq { + + /** + * Implementation notes: + * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison + * - operations are explicit inner classes to untangle unwanted lambda effects + * - the result of applying consecutive operations is the same, in order to have the same number of elements in sink + */ + + @Param({"10","100","1000000"}) + private int size; + + private Function timesTwo, squared; + private Predicate evens, odds; + + private Gatherer gathered; + private Gatherer ga_filter_odds; + private Gatherer ga_map_timesTwo; + private Gatherer ga_map_squared; + private Gatherer ga_filter_evens; + + private Long[] cachedInputArray; + + @Setup + public void setup() { + cachedInputArray = new Long[size]; + for(int i = 0;i < size;++i) + cachedInputArray[i] = Long.valueOf(i); + + timesTwo = new Function() { @Override public Long apply(Long l) { + return l*2; + } }; + squared = new Function() { @Override public Long apply(Long l) { return l*l; } }; + + evens = new Predicate() { @Override public boolean test(Long l) { + return l % 2 == 0; + } }; + odds = new Predicate() { @Override public boolean test(Long l) { + return l % 2 != 0; + } }; + + ga_filter_odds = filter(odds); + ga_map_timesTwo = map(timesTwo); + ga_map_squared = map(squared); + ga_filter_evens = filter(evens); + + gathered = ga_filter_odds.andThen(ga_map_timesTwo).andThen(ga_map_squared).andThen(ga_filter_evens); + } + + @Benchmark + public long seq_misc_baseline() { + return Arrays.stream(cachedInputArray) + .filter(odds) + .map(timesTwo) + .map(squared) + .filter(evens) + .collect(findLast()).get(); + } + + @Benchmark + public long seq_misc_gather() { + return Arrays.stream(cachedInputArray) + .gather(filter(odds)) + .gather(map(timesTwo)) + .gather(map(squared)) + .gather(filter(evens)) + .collect(findLast()).get(); + } + + @Benchmark + public long seq_misc_gather_preallocated() { + return Arrays.stream(cachedInputArray) + .gather(ga_filter_odds) + .gather(ga_map_timesTwo) + .gather(ga_map_squared) + .gather(ga_filter_evens) + .collect(findLast()).get(); + } + + @Benchmark + public long seq_misc_gather_composed() { + return Arrays.stream(cachedInputArray) + .gather(filter(odds) + .andThen(map(timesTwo)) + .andThen(map(squared)) + .andThen(filter(evens)) + ) + .collect(findLast()).get(); + } + + @Benchmark + public long seq_misc_gather_composed_preallocated() { + return Arrays.stream(cachedInputArray) + .gather(ga_filter_odds + .andThen(ga_map_timesTwo) + .andThen(ga_map_squared) + .andThen(ga_filter_evens) + ) + .collect(findLast()).get(); + } + + @Benchmark + public long seq_misc_gather_precomposed() { + return Arrays.stream(cachedInputArray) + .gather(gathered) + .collect(findLast()).get(); + } +} diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherReducePar.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherReducePar.java new file mode 100644 index 0000000000000..2f2d0b06bd7a6 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherReducePar.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util.stream.ops.ref; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import java.util.function.BinaryOperator; +import java.util.Arrays; +import java.util.stream.Collector; +import java.util.stream.Gatherer; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.findFirst; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.reduce; + +/** + * Benchmark for comparing the built-in reduce() operation with the Gatherer-based reduce-operation. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 7, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(jvmArgsAppend = "--enable-preview", value = 1) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class GatherReducePar { + + /** + * Implementation notes: + * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison + * - operations are explicit inner classes to untangle unwanted lambda effects + */ + + @Param({"100000"}) + private int size; + + private BinaryOperator op1; + + private Gatherer gather_op1; + + private Long[] cachedInputArray; + + @Setup + public void setup() { + cachedInputArray = new Long[size]; + for(int i = 0;i < size;++i) + cachedInputArray[i] = Long.valueOf(i); + + op1 = new BinaryOperator() { + @Override public Long apply(Long l, Long r) { + return (l < r) ? r : l; + } + }; + } + + @Benchmark + public long par_invoke_baseline() { + return Arrays.stream(cachedInputArray).parallel().reduce(op1).get(); + } + + @Benchmark + public long par_invoke_gather() { + return Arrays.stream(cachedInputArray).parallel().gather(reduce(op1)).collect(findFirst()).get(); + } +} diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherReduceSeq.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherReduceSeq.java new file mode 100644 index 0000000000000..7d8540d0ed46d --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherReduceSeq.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util.stream.ops.ref; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; +import java.util.function.BinaryOperator; +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Gatherer; +import java.util.stream.Collector; +import java.util.stream.Stream; + +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.findFirst; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.reduce; + +/** + * Benchmark for comparing the built-in reduce() operation with the Gatherer-based reduce-operation. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 7, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(jvmArgsAppend = "--enable-preview", value = 1) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class GatherReduceSeq { + + /** + * Implementation notes: + * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison + * - operations are explicit inner classes to untangle unwanted lambda effects + */ + + @Param({"100", "100000"}) + private int size; + + private BinaryOperator op1; + + private Gatherer gather_op1; + + private Long[] cachedInputArray; + + @Setup + public void setup() { + cachedInputArray = new Long[size]; + for(int i = 0;i < size;++i) + cachedInputArray[i] = Long.valueOf(i); + + op1 = new BinaryOperator() { + @Override + public Long apply(Long l, Long r) { + return (l < r) ? r : l; + } + }; + + gather_op1 = reduce(op1); + } + + @Benchmark + public long seq_invoke_baseline() { + return Arrays.stream(cachedInputArray).reduce(op1).get(); + } + + @Benchmark + public long seq_invoke_gather() { + return Arrays.stream(cachedInputArray).gather(reduce(op1)).collect(findFirst()).get(); + } + + @Benchmark + public long seq_invoke_gather_preallocated() { + return Arrays.stream(cachedInputArray).gather(gather_op1).collect(findFirst()).get(); + } +} diff --git a/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherWhileOrdered.java b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherWhileOrdered.java new file mode 100644 index 0000000000000..6e9e5fec1faf8 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/util/stream/ops/ref/GatherWhileOrdered.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.java.util.stream.ops.ref; + +import org.openjdk.bench.java.util.stream.ops.LongAccumulator; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.util.concurrent.TimeUnit; +import java.util.function.BinaryOperator; +import java.util.function.Predicate; +import java.util.Objects; +import java.util.Arrays; +import java.util.stream.Gatherer; +import static org.openjdk.bench.java.util.stream.ops.ref.BenchmarkGathererImpls.takeWhile; + +/** + * Benchmark for comparing the built-in takeWhile-operation with the Gatherer-based takeWhile-operation for ordered streams. + */ +@BenchmarkMode(Mode.Throughput) +@Warmup(iterations = 4, time = 5, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 7, time = 5, timeUnit = TimeUnit.SECONDS) +@Fork(jvmArgsAppend = "--enable-preview", value = 1) +@OutputTimeUnit(TimeUnit.SECONDS) +@State(Scope.Thread) +public class GatherWhileOrdered { + + /** + * Implementation notes: + * - parallel version requires thread-safe sink, we use the same for sequential version for better comparison + * - operations are explicit inner classes to untangle unwanted lambda effects + */ + + @Param("100000") + private int size; + + @Param({"0", "49999", "99999"}) + private int find; + + private Predicate predicate; + + private Gatherer gather_takeWhile; + + private Long[] cachedInputArray; + + @Setup + public void setup() { + final int limit = find; + + cachedInputArray = new Long[size]; + for(int i = 0;i < size;++i) + cachedInputArray[i] = Long.valueOf(i); + + predicate = new Predicate() { + @Override + public boolean test(Long v) { + return v < limit; + } + }; + + gather_takeWhile = takeWhile(predicate); + } + + @Benchmark + public long seq_invoke_baseline() { + return Arrays.stream(cachedInputArray).takeWhile(predicate) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_invoke_gather() { + return Arrays.stream(cachedInputArray).gather(takeWhile(predicate)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long seq_invoke_gather_preallocated() { + return Arrays.stream(cachedInputArray).gather(gather_takeWhile) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_invoke_baseline() { + return Arrays.stream(cachedInputArray).parallel().takeWhile(predicate) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_invoke_gather() { + return Arrays.stream(cachedInputArray).parallel().gather(takeWhile(predicate)) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } + + @Benchmark + public long par_invoke_gather_preallocated() { + return Arrays.stream(cachedInputArray).parallel().gather(gather_takeWhile) + .collect(LongAccumulator::new, LongAccumulator::add, LongAccumulator::merge).get(); + } +} diff --git a/test/micro/org/openjdk/bench/javax/crypto/full/AESGCMBench.java b/test/micro/org/openjdk/bench/javax/crypto/full/AESGCMBench.java index 9e5d4d8ad0320..e46f50678ef81 100644 --- a/test/micro/org/openjdk/bench/javax/crypto/full/AESGCMBench.java +++ b/test/micro/org/openjdk/bench/javax/crypto/full/AESGCMBench.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,107 +22,31 @@ */ package org.openjdk.bench.javax.crypto.full; -import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Setup; -import javax.crypto.Cipher; +import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.GCMParameterSpec; -import javax.crypto.spec.SecretKeySpec; /** - * This performance tests runs AES/GCM encryption and decryption using byte[] - * as input and output buffers for single and multi-part testing. - * - * This test rotates the IV and creates a new GCMParameterSpec for each encrypt - * benchmark operation + * This performance tests runs AES/GCM encryption and decryption + * using input and output byte[] buffers with single and multi-part testing. */ -public class AESGCMBench extends CryptoBase { +public class AESGCMBench extends BenchBase { @Param({"128"}) - private int keyLength; - - @Param({"1024", "1500", "4096", "16384"}) - private int dataSize; + int keyLength; - byte[] encryptedData; - byte[] in, out; - private Cipher encryptCipher; - private Cipher decryptCipher; - SecretKeySpec ks; - GCMParameterSpec gcm_spec; - byte[] iv; + public static final int IV_MODULO = 16; - private static final int IV_BUFFER_SIZE = 32; - private static final int IV_MODULO = IV_BUFFER_SIZE - 16; - int iv_index = 0; - int updateLen = 0; - - private int next_iv_index() { - int r = iv_index; + public AlgorithmParameterSpec getNewSpec() { iv_index = (iv_index + 1) % IV_MODULO; - return r; + return new GCMParameterSpec(128, iv, iv_index, IV_MODULO); } @Setup public void setup() throws Exception { - setupProvider(); - - // Setup key material - byte[] keystring = fillSecureRandom(new byte[keyLength / 8]); - ks = new SecretKeySpec(keystring, "AES"); - iv = fillSecureRandom(new byte[IV_BUFFER_SIZE]); - gcm_spec = new GCMParameterSpec(96, iv, next_iv_index(), 16); - - // Setup Cipher classes - encryptCipher = makeCipher(prov, "AES/GCM/NoPadding"); - encryptCipher.init(Cipher.ENCRYPT_MODE, ks, gcm_spec); - decryptCipher = makeCipher(prov, "AES/GCM/NoPadding"); - decryptCipher.init(Cipher.DECRYPT_MODE, ks, - encryptCipher.getParameters(). - getParameterSpec(GCMParameterSpec.class)); - - // Setup input/output buffers - in = fillRandom(new byte[dataSize]); - encryptedData = new byte[encryptCipher.getOutputSize(in.length)]; - out = new byte[encryptedData.length]; - encryptCipher.doFinal(in, 0, in.length, encryptedData, 0); - updateLen = in.length / 2; - - } - - @Benchmark - public void encrypt() throws Exception { - gcm_spec = new GCMParameterSpec(96, iv, next_iv_index(), 16); - encryptCipher.init(Cipher.ENCRYPT_MODE, ks, gcm_spec); - encryptCipher.doFinal(in, 0, in.length, out, 0); - } - - @Benchmark - public void encryptMultiPart() throws Exception { - gcm_spec = new GCMParameterSpec(96, iv, next_iv_index(), 16); - encryptCipher.init(Cipher.ENCRYPT_MODE, ks, gcm_spec); - int outOfs = encryptCipher.update(in, 0, updateLen, out, 0); - encryptCipher.doFinal(in, updateLen, in.length - updateLen, - out, outOfs); - } - - @Benchmark - public void decrypt() throws Exception { - decryptCipher.init(Cipher.DECRYPT_MODE, ks, - encryptCipher.getParameters(). - getParameterSpec(GCMParameterSpec.class)); - decryptCipher.doFinal(encryptedData, 0, encryptedData.length, out, 0); - } - - @Benchmark - public void decryptMultiPart() throws Exception { - decryptCipher.init(Cipher.DECRYPT_MODE, ks, - encryptCipher.getParameters(). - getParameterSpec(GCMParameterSpec.class)); - decryptCipher.update(encryptedData, 0, updateLen, out, 0); - decryptCipher.doFinal(encryptedData, updateLen, - encryptedData.length - updateLen, out, 0); + init("AES/GCM/NoPadding", keyLength); } } diff --git a/test/micro/org/openjdk/bench/javax/crypto/full/AESGCMByteBuffer.java b/test/micro/org/openjdk/bench/javax/crypto/full/AESGCMByteBuffer.java index 3e07c6b691028..ce5e7e8358c9b 100644 --- a/test/micro/org/openjdk/bench/javax/crypto/full/AESGCMByteBuffer.java +++ b/test/micro/org/openjdk/bench/javax/crypto/full/AESGCMByteBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,140 +22,32 @@ */ package org.openjdk.bench.javax.crypto.full; -import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Setup; -import javax.crypto.Cipher; +import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.GCMParameterSpec; -import javax.crypto.spec.SecretKeySpec; -import java.nio.ByteBuffer; /** * This performance tests runs AES/GCM encryption and decryption using heap and * direct ByteBuffers as input and output buffers for single and multi-part * operations. - * - * This test rotates the IV and creates a new GCMParameterSpec for each encrypt - * benchmark operation */ -public class AESGCMByteBuffer extends CryptoBase { +public class AESGCMByteBuffer extends ByteBufferBase { @Param({"128"}) - private int keyLength; - - @Param({"1024", "1500", "4096", "16384"}) - private int dataSize; - - @Param({"direct", "heap"}) - private String dataMethod; + int keyLength; - byte[] data; - ByteBuffer encryptedData; - ByteBuffer in, out; - private Cipher encryptCipher; - private Cipher decryptCipher; - SecretKeySpec ks; - GCMParameterSpec gcm_spec; - byte[] iv; + public static final int IV_MODULO = 16; - private static final int IV_BUFFER_SIZE = 32; - private static final int IV_MODULO = IV_BUFFER_SIZE - 16; - int iv_index = 0; - int updateLen = 0; - - private int next_iv_index() { - int r = iv_index; + public AlgorithmParameterSpec getNewSpec() { iv_index = (iv_index + 1) % IV_MODULO; - return r; + return new GCMParameterSpec(128, iv, iv_index, IV_MODULO); } @Setup public void setup() throws Exception { - setupProvider(); - - // Setup key material - byte[] keystring = fillSecureRandom(new byte[keyLength / 8]); - ks = new SecretKeySpec(keystring, "AES"); - iv = fillSecureRandom(new byte[IV_BUFFER_SIZE]); - gcm_spec = new GCMParameterSpec(96, iv, next_iv_index(), 16); - - // Setup Cipher classes - encryptCipher = makeCipher(prov, "AES/GCM/NoPadding"); - encryptCipher.init(Cipher.ENCRYPT_MODE, ks, gcm_spec); - decryptCipher = makeCipher(prov, "AES/GCM/NoPadding"); - decryptCipher.init(Cipher.DECRYPT_MODE, ks, - encryptCipher.getParameters(). - getParameterSpec(GCMParameterSpec.class)); - - // Setup input/output buffers - data = fillRandom(new byte[dataSize]); - if (dataMethod.equalsIgnoreCase("direct")) { - in = ByteBuffer.allocateDirect(data.length); - in.put(data); - in.flip(); - encryptedData = ByteBuffer.allocateDirect( - encryptCipher.getOutputSize(data.length)); - out = ByteBuffer.allocateDirect(encryptedData.capacity()); - } else if (dataMethod.equalsIgnoreCase("heap")) { - in = ByteBuffer.wrap(data); - encryptedData = ByteBuffer.allocate( - encryptCipher.getOutputSize(data.length)); - out = ByteBuffer.allocate(encryptedData.capacity()); - } - - encryptCipher.doFinal(in, encryptedData); - encryptedData.flip(); - in.flip(); - updateLen = in.remaining() / 2; - } - - @Benchmark - public void encrypt() throws Exception { - gcm_spec = new GCMParameterSpec(96, iv, next_iv_index(), 16); - encryptCipher.init(Cipher.ENCRYPT_MODE, ks, gcm_spec); - encryptCipher.doFinal(in, out); - out.flip(); - in.flip(); + init("AES/GCM/NoPadding", keyLength); } - - @Benchmark - public void encryptMultiPart() throws Exception { - gcm_spec = new GCMParameterSpec(96, iv, next_iv_index(), 16); - encryptCipher.init(Cipher.ENCRYPT_MODE, ks, gcm_spec); - in.limit(updateLen); - encryptCipher.update(in, out); - in.limit(in.capacity()); - encryptCipher.doFinal(in, out); - out.flip(); - in.flip(); - } - - @Benchmark - public void decrypt() throws Exception { - decryptCipher.init(Cipher.DECRYPT_MODE, ks, - encryptCipher.getParameters(). - getParameterSpec(GCMParameterSpec.class)); - decryptCipher.doFinal(encryptedData, out); - encryptedData.flip(); - out.flip(); - } - - @Benchmark - public void decryptMultiPart() throws Exception { - decryptCipher.init(Cipher.DECRYPT_MODE, ks, - encryptCipher.getParameters(). - getParameterSpec(GCMParameterSpec.class)); - - int len = encryptedData.remaining(); - encryptedData.limit(updateLen); - decryptCipher.update(encryptedData, out); - encryptedData.limit(len); - - decryptCipher.doFinal(encryptedData, out); - encryptedData.flip(); - out.flip(); - } - } diff --git a/test/micro/org/openjdk/bench/javax/crypto/full/BenchBase.java b/test/micro/org/openjdk/bench/javax/crypto/full/BenchBase.java new file mode 100644 index 0000000000000..0c5df20d9cb64 --- /dev/null +++ b/test/micro/org/openjdk/bench/javax/crypto/full/BenchBase.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.javax.crypto.full; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Setup; + +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + +/** + * This is the common code for the AES/GCM and ChaCha20-Poly1305 performance + * tests. Encryption and decryption use byte[] as input and output buffers for + * single and multi-part testing. + * + * The IV rotates through a set buffer and creates a new AlgorithmParameterSpec + * for each encrypt benchmark operation. + */ + +public abstract class BenchBase extends CryptoBase { + // Defined by the test + String algorithm; + int keyLength = 256; + + // Default data sizes for full tests + @Param({"1024", "1500", "4096", "16384"}) + int dataSize; + + static final int IV_BUFFER_SIZE = 36; + public byte[] iv; + public int iv_index = 0; + private int updateLen = 0; + + private Cipher encryptCipher, decryptCipher; + private byte[] encryptedData, in, out; + private SecretKeySpec ks; + // Used for decryption to avoid repeated getParameter() calls + private AlgorithmParameterSpec spec; + + abstract AlgorithmParameterSpec getNewSpec(); + + // Configure setup with particular test parameters + public void init(String algorithm, int keyLength) throws Exception { + this.algorithm = algorithm; + this.keyLength = keyLength; + init(); + } + + // Configure setup with particular test parameters + public void init(String algorithm, int keyLength, int dataSize) + throws Exception { + this.dataSize = dataSize; + init(algorithm, keyLength); + } + + // Initalize test setup + private void init() throws Exception { + setupProvider(); + + // Setup key material + iv = fillSecureRandom(new byte[IV_BUFFER_SIZE]); + spec = getNewSpec(); + // CC20 doesn't care about the algorithm name on the key, but AES does. + ks = new SecretKeySpec(fillSecureRandom(new byte[keyLength / 8]), + "AES"); + + // Setup Cipher classes + encryptCipher = makeCipher(prov, algorithm); + encryptCipher.init(Cipher.ENCRYPT_MODE, ks, spec); + decryptCipher = makeCipher(prov, algorithm); + decryptCipher.init(Cipher.DECRYPT_MODE, ks, spec); + + // Setup input/output buffers + in = fillRandom(new byte[dataSize]); + encryptedData = new byte[encryptCipher.getOutputSize(in.length)]; + out = new byte[encryptedData.length]; + encryptCipher.doFinal(in, 0, in.length, encryptedData, 0); + updateLen = in.length / 2; + + } + + @Benchmark + public void encrypt() throws Exception { + encryptCipher.init(Cipher.ENCRYPT_MODE, ks, getNewSpec()); + encryptCipher.doFinal(in, 0, in.length, out, 0); + } + + @Benchmark + public void encryptMultiPart() throws Exception { + encryptCipher.init(Cipher.ENCRYPT_MODE, ks, getNewSpec()); + int outOfs = encryptCipher.update(in, 0, updateLen, out, 0); + encryptCipher.doFinal(in, updateLen, in.length - updateLen, + out, outOfs); + } + + @Benchmark + public void decrypt() throws Exception { + decryptCipher.init(Cipher.DECRYPT_MODE, ks, spec); + decryptCipher.doFinal(encryptedData, 0, encryptedData.length, out, 0); + } + + @Benchmark + public void decryptMultiPart() throws Exception { + decryptCipher.init(Cipher.DECRYPT_MODE, ks, spec); + decryptCipher.update(encryptedData, 0, updateLen, out, 0); + decryptCipher.doFinal(encryptedData, updateLen, + encryptedData.length - updateLen, out, 0); + } +} diff --git a/test/micro/org/openjdk/bench/javax/crypto/full/ByteBufferBase.java b/test/micro/org/openjdk/bench/javax/crypto/full/ByteBufferBase.java new file mode 100644 index 0000000000000..79fa2bcbab300 --- /dev/null +++ b/test/micro/org/openjdk/bench/javax/crypto/full/ByteBufferBase.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.javax.crypto.full; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Setup; + +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; +import java.nio.ByteBuffer; + +/** + * This is the common code for the AES/GCM and ChaCha20-Poly1305 performance + * tests. Encryption and decryption are run with input and output + * ByteBuffers, direct and heap, for single and multi-part testing. + * + * The IV rotates through a set buffer and creates a new AlgorithmParameterSpec + * for each encrypt benchmark operation. + */ + +public abstract class ByteBufferBase extends CryptoBase { + // Defined by the test + String algorithm; + int keyLength = 256; + + @Param({"1024", "1500", "4096", "16384"}) + int dataSize; + + @Param({"direct", "heap"}) + String dataMethod; + + static final int IV_BUFFER_SIZE = 36; + public byte[] iv; + public int iv_index = 0; + private int updateLen = 0; + + private Cipher encryptCipher, decryptCipher; + private ByteBuffer encryptedData, in, out; + private SecretKeySpec ks; + // Used for decryption to avoid repeated getParameter() calls + private AlgorithmParameterSpec spec; + + abstract AlgorithmParameterSpec getNewSpec(); + + // Configure setup with particular test parameters + public void init(String algorithm, int keyLength) throws Exception { + this.algorithm = algorithm; + this.keyLength = keyLength; + init(); + } + + // Configure setup with particular test parameters + public void init(String algorithm, int keyLength, int dataSize) + throws Exception { + this.dataSize = dataSize; + init(algorithm, keyLength); + } + + // Initalize test setup + private void init() throws Exception { + setupProvider(); + + // Setup key material + iv = fillSecureRandom(new byte[IV_BUFFER_SIZE]); + spec = getNewSpec(); + // CC20 doesn't care about the algorithm name on the key, but AES does. + ks = new SecretKeySpec(fillSecureRandom(new byte[keyLength / 8]), + "AES"); + + // Setup Cipher classes + encryptCipher = makeCipher(prov, algorithm); + encryptCipher.init(Cipher.ENCRYPT_MODE, ks, spec); + decryptCipher = makeCipher(prov, algorithm); + decryptCipher.init(Cipher.DECRYPT_MODE, ks, spec); + + // Setup input/output buffers + byte[] data = fillRandom(new byte[dataSize]); + if (dataMethod.equalsIgnoreCase("direct")) { + in = ByteBuffer.allocateDirect(data.length); + in.put(data); + in.flip(); + encryptedData = ByteBuffer.allocateDirect( + encryptCipher.getOutputSize(data.length)); + out = ByteBuffer.allocateDirect(encryptedData.capacity()); + } else if (dataMethod.equalsIgnoreCase("heap")) { + in = ByteBuffer.wrap(data); + encryptedData = ByteBuffer.allocate( + encryptCipher.getOutputSize(data.length)); + out = ByteBuffer.allocate(encryptedData.capacity()); + } + + encryptCipher.doFinal(in, encryptedData); + encryptedData.flip(); + in.flip(); + updateLen = in.remaining() / 2; + } + + @Benchmark + public void encrypt() throws Exception { + encryptCipher.init(Cipher.ENCRYPT_MODE, ks, getNewSpec()); + encryptCipher.doFinal(in, out); + out.flip(); + in.flip(); + } + + @Benchmark + public void encryptMultiPart() throws Exception { + encryptCipher.init(Cipher.ENCRYPT_MODE, ks, getNewSpec()); + in.limit(updateLen); + encryptCipher.update(in, out); + in.limit(in.capacity()); + encryptCipher.doFinal(in, out); + out.flip(); + in.flip(); + } + + @Benchmark + public void decrypt() throws Exception { + decryptCipher.init(Cipher.DECRYPT_MODE, ks, spec); + decryptCipher.doFinal(encryptedData, out); + encryptedData.flip(); + out.flip(); + } + + @Benchmark + public void decryptMultiPart() throws Exception { + decryptCipher.init(Cipher.DECRYPT_MODE, ks, spec); + + int len = encryptedData.remaining(); + encryptedData.limit(updateLen); + decryptCipher.update(encryptedData, out); + encryptedData.limit(len); + + decryptCipher.doFinal(encryptedData, out); + encryptedData.flip(); + out.flip(); + } +} diff --git a/test/micro/org/openjdk/bench/javax/crypto/full/CC20P1305Bench.java b/test/micro/org/openjdk/bench/javax/crypto/full/CC20P1305Bench.java new file mode 100644 index 0000000000000..f6bc5c1052d55 --- /dev/null +++ b/test/micro/org/openjdk/bench/javax/crypto/full/CC20P1305Bench.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.javax.crypto.full; + +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Setup; + +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.spec.IvParameterSpec; + +/** + * This performance tests runs ChaCha20-Poly1305 encryption and decryption + * using input and output byte[] buffers with single and multi-part testing. + */ + +public class CC20P1305Bench extends BenchBase { + + public static final int IV_MODULO = 12; + + public AlgorithmParameterSpec getNewSpec() { + iv_index = (iv_index + 1) % IV_MODULO; + return new IvParameterSpec(iv, iv_index, IV_MODULO); + } + + @Setup + public void setup() throws Exception { + init("ChaCha20-Poly1305/None/NoPadding", keyLength); + } +} diff --git a/test/micro/org/openjdk/bench/javax/crypto/full/CC20P1305ByteBuffer.java b/test/micro/org/openjdk/bench/javax/crypto/full/CC20P1305ByteBuffer.java new file mode 100644 index 0000000000000..326e2a6766d1e --- /dev/null +++ b/test/micro/org/openjdk/bench/javax/crypto/full/CC20P1305ByteBuffer.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.javax.crypto.full; + +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Setup; + +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.spec.IvParameterSpec; + +/** + * This performance tests runs ChaCha20-Poly1305 encryption and decryption + * using heap and direct ByteBuffers for input and output buffers with single + * and multi-part operations. + */ + +public class CC20P1305ByteBuffer extends ByteBufferBase { + + public static final int IV_MODULO = 12; + + public AlgorithmParameterSpec getNewSpec() { + iv_index = (iv_index + 1) % IV_MODULO; + return new IvParameterSpec(iv, iv_index, IV_MODULO); + } + + @Setup + public void setup() throws Exception { + init("ChaCha20-Poly1305/None/NoPadding", keyLength); + } +} diff --git a/test/micro/org/openjdk/bench/javax/crypto/small/AESGCMBench.java b/test/micro/org/openjdk/bench/javax/crypto/small/AESGCMBench.java index cfdc53ac70458..49d64c7ca4af8 100644 --- a/test/micro/org/openjdk/bench/javax/crypto/small/AESGCMBench.java +++ b/test/micro/org/openjdk/bench/javax/crypto/small/AESGCMBench.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,14 +23,28 @@ package org.openjdk.bench.javax.crypto.small; import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Setup; + +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.spec.GCMParameterSpec; + +/** + * This small performance tests runs AES/GCM encryption and decryption + * using input and output byte[] buffers with single and multi-part testing. + * Only 1024 plaintext data length is tested. + */ public class AESGCMBench extends org.openjdk.bench.javax.crypto.full.AESGCMBench { @Param({"128"}) - private int keyLength; + int keyLength; @Param({"1024"}) - private int dataSize; + int dataSize; + @Setup + public void setup() throws Exception { + init("AES/GCM/NoPadding", keyLength, dataSize); + } } diff --git a/test/micro/org/openjdk/bench/javax/crypto/small/AESGCMByteBuffer.java b/test/micro/org/openjdk/bench/javax/crypto/small/AESGCMByteBuffer.java index 19fdab85bbbb4..baa41cd4ec83b 100644 --- a/test/micro/org/openjdk/bench/javax/crypto/small/AESGCMByteBuffer.java +++ b/test/micro/org/openjdk/bench/javax/crypto/small/AESGCMByteBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,14 +23,28 @@ package org.openjdk.bench.javax.crypto.small; import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Setup; + +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.spec.GCMParameterSpec; + +/** + * This small performance tests runs AES/GCM encryption and decryption + * using heap and direct ByteBuffers for input and output buffers with single + * and multi-part operations. Only 1024 plaintext data length is tested. + */ public class AESGCMByteBuffer extends org.openjdk.bench.javax.crypto.full.AESGCMByteBuffer { @Param({"128"}) - private int keyLength; + int keyLength; @Param({"1024"}) - private int dataSize; + int dataSize; + @Setup + public void setup() throws Exception { + init("AES/GCM/NoPadding", keyLength, dataSize); + } } \ No newline at end of file diff --git a/test/micro/org/openjdk/bench/javax/crypto/small/CC20P1305Bench.java b/test/micro/org/openjdk/bench/javax/crypto/small/CC20P1305Bench.java new file mode 100644 index 0000000000000..b8b3d45fbc1f9 --- /dev/null +++ b/test/micro/org/openjdk/bench/javax/crypto/small/CC20P1305Bench.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.javax.crypto.small; + +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Setup; + +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.spec.IvParameterSpec; + +/** + * This small performance tests runs ChaCha20-Poly1305 encryption and decryption + * using input and output byte[] buffers with single and multi-part testing. + * Only 1024 plaintext data length is tested. + */ + +public class CC20P1305Bench extends + org.openjdk.bench.javax.crypto.full.CC20P1305Bench { + + @Param({"1024"}) + int dataSize; + + @Setup + public void setup() throws Exception { + init("ChaCha20-Poly1305/None/NoPadding", 256, dataSize); + } + +} diff --git a/test/micro/org/openjdk/bench/javax/crypto/small/CC20P1305ByteBuffer.java b/test/micro/org/openjdk/bench/javax/crypto/small/CC20P1305ByteBuffer.java new file mode 100644 index 0000000000000..827b09c2f36b2 --- /dev/null +++ b/test/micro/org/openjdk/bench/javax/crypto/small/CC20P1305ByteBuffer.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.javax.crypto.small; + +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Setup; + +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.spec.IvParameterSpec; + +/** + * This small performance tests runs ChaCha20-Poly1305 encryption and decryption + * using heap and direct ByteBuffers for input and output buffers with single + * and multi-part operations. Only 1024 plaintext data length is tested. + */ + +public class CC20P1305ByteBuffer extends + org.openjdk.bench.javax.crypto.full.CC20P1305ByteBuffer { + + @Param({"1024"}) + int dataSize; + + @Setup + public void setup() throws Exception { + init("ChaCha20-Poly1305/None/NoPadding", 256, dataSize); + } + +} diff --git a/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java b/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java index 36e1ecd571d14..b714f1c5ff961 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/AbstractCorpusBenchmark.java @@ -46,11 +46,7 @@ @Fork(value = 1, jvmArgsAppend = { "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.attribute=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.instruction=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.components=ALL-UNNAMED", + "--enable-preview", "--add-exports", "java.base/jdk.internal.classfile.impl=ALL-UNNAMED"}) @State(Scope.Benchmark) public class AbstractCorpusBenchmark { diff --git a/test/micro/org/openjdk/bench/jdk/classfile/AdHocAdapt.java b/test/micro/org/openjdk/bench/jdk/classfile/AdHocAdapt.java index 7b0a2f4aa8f75..99ef450851e9c 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/AdHocAdapt.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/AdHocAdapt.java @@ -22,9 +22,9 @@ */ package org.openjdk.bench.jdk.classfile; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeTransform; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeTransform; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; @@ -55,7 +55,7 @@ public enum X { @Benchmark @BenchmarkMode(Mode.Throughput) public void transform(Blackhole bh) { - var cc = Classfile.of(); + var cc = ClassFile.of(); for (byte[] bytes : classes) bh.consume(cc.transform(cc.parse(bytes), transform.transform)); } diff --git a/test/micro/org/openjdk/bench/jdk/classfile/ClassfileBenchmark.java b/test/micro/org/openjdk/bench/jdk/classfile/ClassfileBenchmark.java index d68122896d576..05dd4b1758351 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/ClassfileBenchmark.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/ClassfileBenchmark.java @@ -26,13 +26,13 @@ import java.net.URI; import java.nio.file.FileSystems; import java.nio.file.Files; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeBuilder; -import jdk.internal.classfile.CodeElement; -import jdk.internal.classfile.CodeTransform; -import jdk.internal.classfile.CompoundElement; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.CodeElement; +import java.lang.classfile.CodeTransform; +import java.lang.classfile.CompoundElement; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; @@ -46,18 +46,18 @@ import org.openjdk.jmh.infra.Blackhole; /** - * ClassfileBenchmark + * ClassFileBenchmark */ @Warmup(iterations = 3) @Measurement(iterations = 5) @Fork(value = 1, jvmArgsAppend = { - "--add-exports", "java.base/jdk.internal.classfile=ALL-UNNAMED"}) + "--enable-preview"}) @State(Scope.Benchmark) public class ClassfileBenchmark { private byte[] benchBytes; private ClassModel benchModel; - private Classfile sharedCP, newCP; + private ClassFile sharedCP, newCP; private ClassTransform threeLevelNoop; private ClassTransform addNOP; @@ -66,9 +66,9 @@ public void setup() throws IOException { benchBytes = Files.readAllBytes( FileSystems.getFileSystem(URI.create("jrt:/")) .getPath("modules/java.base/java/util/AbstractMap.class")); - sharedCP = Classfile.of(); - newCP = Classfile.of(Classfile.ConstantPoolSharingOption.NEW_POOL); - benchModel = Classfile.of().parse(benchBytes); + sharedCP = ClassFile.of(); + newCP = ClassFile.of(ClassFile.ConstantPoolSharingOption.NEW_POOL); + benchModel = ClassFile.of().parse(benchBytes); threeLevelNoop = ClassTransform.transformingMethodBodies(CodeTransform.ACCEPT_ALL); addNOP = ClassTransform.transformingMethodBodies(new CodeTransform() { @Override diff --git a/test/micro/org/openjdk/bench/jdk/classfile/GenerateStackMaps.java b/test/micro/org/openjdk/bench/jdk/classfile/GenerateStackMaps.java index e9a284feb79b8..6fcf801c2cf4b 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/GenerateStackMaps.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/GenerateStackMaps.java @@ -32,13 +32,13 @@ import java.util.Iterator; import java.util.ArrayList; import java.util.List; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.ClassReader; -import jdk.internal.classfile.constantpool.ConstantPoolBuilder; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassReader; +import java.lang.classfile.constantpool.ConstantPoolBuilder; import jdk.internal.classfile.impl.AbstractPseudoInstruction; import jdk.internal.classfile.impl.CodeImpl; import jdk.internal.classfile.impl.LabelContext; -import jdk.internal.classfile.impl.ClassfileImpl; +import jdk.internal.classfile.impl.ClassFileImpl; import jdk.internal.classfile.impl.SplitConstantPool; import jdk.internal.classfile.impl.StackMapGenerator; import org.openjdk.jmh.annotations.Benchmark; @@ -55,11 +55,7 @@ @BenchmarkMode(Mode.Throughput) @State(Scope.Benchmark) @Fork(value = 1, jvmArgsAppend = { - "--add-exports", "java.base/jdk.internal.classfile=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.attribute=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.instruction=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.components=ALL-UNNAMED", + "--enable-preview", "--add-exports", "java.base/jdk.internal.classfile.impl=ALL-UNNAMED"}) @Warmup(iterations = 2) @Measurement(iterations = 10) @@ -77,11 +73,11 @@ record GenData(LabelContext labelContext, List data; Iterator it; GenData d; - Classfile cc; + ClassFile cc; @Setup(Level.Trial) public void setup() throws IOException { - cc = Classfile.of(); + cc = ClassFile.of(); data = new ArrayList<>(); Files.walk(FileSystems.getFileSystem(URI.create("jrt:/")).getPath("modules/java.base/java")).forEach(p -> { if (Files.isRegularFile(p) && p.toString().endsWith(".class")) try { @@ -96,7 +92,7 @@ public void setup() throws IOException { thisCls, m.methodName().stringValue(), m.methodTypeSymbol(), - (m.flags().flagsMask() & Classfile.ACC_STATIC) != 0, + (m.flags().flagsMask() & ClassFile.ACC_STATIC) != 0, bb.slice(8, bb.getInt(4)), cp, com.exceptionHandlers().stream().map(eh -> (AbstractPseudoInstruction.ExceptionCatchImpl)eh).toList())); @@ -121,7 +117,7 @@ public void benchmark() { d.isStatic(), d.bytecode().rewind(), (SplitConstantPool)d.constantPool(), - (ClassfileImpl)cc, + (ClassFileImpl)cc, d.handlers()); } } diff --git a/test/micro/org/openjdk/bench/jdk/classfile/ParseOptions.java b/test/micro/org/openjdk/bench/jdk/classfile/ParseOptions.java index 7ce8fd5052692..ed5e0f150acdc 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/ParseOptions.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/ParseOptions.java @@ -22,8 +22,8 @@ */ package org.openjdk.bench.jdk.classfile; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Mode; @@ -39,7 +39,7 @@ public class ParseOptions extends AbstractCorpusBenchmark { @Benchmark @BenchmarkMode(Mode.Throughput) public void transformNoDebug(Blackhole bh) { - var cc = Classfile.of(Classfile.DebugElementsOption.DROP_DEBUG); + var cc = ClassFile.of(ClassFile.DebugElementsOption.DROP_DEBUG); for (byte[] aClass : classes) { ClassModel cm = cc.parse(aClass); bh.consume(cc.transform(cm, threeLevelNoop)); @@ -49,7 +49,7 @@ public void transformNoDebug(Blackhole bh) { @Benchmark @BenchmarkMode(Mode.Throughput) public void transformNoStackmap(Blackhole bh) { - var cc = Classfile.of(Classfile.StackMapsOption.DROP_STACK_MAPS); + var cc = ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS); for (byte[] aClass : classes) { ClassModel cm = cc.parse(aClass); bh.consume(cc.transform(cm, threeLevelNoop)); @@ -59,7 +59,7 @@ public void transformNoStackmap(Blackhole bh) { @Benchmark @BenchmarkMode(Mode.Throughput) public void transformNoLineNumbers(Blackhole bh) { - var cc = Classfile.of(Classfile.LineNumbersOption.DROP_LINE_NUMBERS); + var cc = ClassFile.of(ClassFile.LineNumbersOption.DROP_LINE_NUMBERS); for (byte[] aClass : classes) { ClassModel cm = cc.parse(aClass); bh.consume(cc.transform(cm, threeLevelNoop)); diff --git a/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java b/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java index affcc964fde33..2f5e2cfbe1eda 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/ReadDeep.java @@ -22,13 +22,13 @@ */ package org.openjdk.bench.jdk.classfile; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.ClassfileElement; -import jdk.internal.classfile.CodeModel; -import jdk.internal.classfile.CompoundElement; -import jdk.internal.classfile.MethodModel; -import jdk.internal.classfile.instruction.LoadInstruction; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassFileElement; +import java.lang.classfile.CodeModel; +import java.lang.classfile.CompoundElement; +import java.lang.classfile.MethodModel; +import java.lang.classfile.instruction.LoadInstruction; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassVisitor; import jdk.internal.org.objectweb.asm.MethodVisitor; @@ -97,7 +97,7 @@ public void visitVarInsn(int opcode, int var) { @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkElementsCountLoads(Blackhole bh) { - var cc = Classfile.of(); + var cc = ClassFile.of(); for (byte[] bytes : classes) { int[] count = new int[1]; ClassModel cm = cc.parse(bytes); @@ -121,15 +121,15 @@ public void jdkElementsCountLoads(Blackhole bh) { @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkElementsDeepIterate(Blackhole bh) { - var cc = Classfile.of(); + var cc = ClassFile.of(); for (byte[] bytes : classes) { ClassModel cm = cc.parse(bytes); bh.consume(iterateAll(cm)); } } - private static ClassfileElement iterateAll(CompoundElement model) { - ClassfileElement last = null; + private static ClassFileElement iterateAll(CompoundElement model) { + ClassFileElement last = null; for (var e : model) { if (e instanceof CompoundElement cm) { last = iterateAll(cm); diff --git a/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java b/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java index e83fb4b62418d..08b1b6312b1c0 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/ReadMetadata.java @@ -23,10 +23,10 @@ package org.openjdk.bench.jdk.classfile; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.ClassElement; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.FieldModel; +import java.lang.classfile.ClassElement; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.FieldModel; import jdk.internal.org.objectweb.asm.*; import jdk.internal.org.objectweb.asm.tree.*; import org.openjdk.jmh.annotations.*; @@ -66,7 +66,7 @@ public void asmTreeReadName(Blackhole bh) { @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkReadName(Blackhole bh) { - var cc = Classfile.of(); + var cc = ClassFile.of(); for (byte[] bytes : classes) { bh.consume(cc.parse(bytes).thisClass().asInternalName()); } @@ -75,7 +75,7 @@ public void jdkReadName(Blackhole bh) { @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkReadMemberNames(Blackhole bh) { - var cc = Classfile.of(); + var cc = ClassFile.of(); for (byte[] bytes : classes) { var cm = cc.parse(bytes); bh.consume(cm.thisClass().asInternalName()); @@ -130,7 +130,7 @@ public void asmTreeCountFields(Blackhole bh) { @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkTreeCountFields(Blackhole bh) { - var cc = Classfile.of(); + var cc = ClassFile.of(); for (byte[] bytes : classes) { int count = 0; ClassModel cm = cc.parse(bytes); @@ -145,7 +145,7 @@ public void jdkTreeCountFields(Blackhole bh) { @Benchmark @BenchmarkMode(Mode.Throughput) public void jdkCountFields(Blackhole bh) { - var cc = Classfile.of(); + var cc = ClassFile.of(); for (byte[] bytes : classes) { int count = 0; ClassModel cm = cc.parse(bytes); diff --git a/test/micro/org/openjdk/bench/jdk/classfile/RebuildMethodBodies.java b/test/micro/org/openjdk/bench/jdk/classfile/RebuildMethodBodies.java index cf9c887552e37..4c657b961b191 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/RebuildMethodBodies.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/RebuildMethodBodies.java @@ -29,36 +29,34 @@ import java.util.Iterator; import java.util.ArrayList; import java.util.List; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.instruction.*; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.instruction.*; import org.openjdk.jmh.annotations.*; @BenchmarkMode(Mode.Throughput) @State(Scope.Benchmark) @Fork(value = 1, jvmArgsAppend = { - "--add-exports", "java.base/jdk.internal.classfile=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.instruction=ALL-UNNAMED"}) + "--enable-preview"}) @Warmup(iterations = 2) @Measurement(iterations = 4) public class RebuildMethodBodies { - Classfile shared, unshared; + ClassFile shared, unshared; List models; Iterator it; @Setup(Level.Trial) public void setup() throws IOException { - shared = Classfile.of( - Classfile.ConstantPoolSharingOption.SHARED_POOL, - Classfile.DebugElementsOption.DROP_DEBUG, - Classfile.LineNumbersOption.DROP_LINE_NUMBERS); - unshared = Classfile.of( - Classfile.ConstantPoolSharingOption.NEW_POOL, - Classfile.DebugElementsOption.DROP_DEBUG, - Classfile.LineNumbersOption.DROP_LINE_NUMBERS); + shared = ClassFile.of( + ClassFile.ConstantPoolSharingOption.SHARED_POOL, + ClassFile.DebugElementsOption.DROP_DEBUG, + ClassFile.LineNumbersOption.DROP_LINE_NUMBERS); + unshared = ClassFile.of( + ClassFile.ConstantPoolSharingOption.NEW_POOL, + ClassFile.DebugElementsOption.DROP_DEBUG, + ClassFile.LineNumbersOption.DROP_LINE_NUMBERS); models = new ArrayList<>(); Files.walk(FileSystems.getFileSystem(URI.create("jrt:/")).getPath("modules/java.base/java")).forEach(p -> { if (Files.isRegularFile(p) && p.toString().endsWith(".class")) try { @@ -89,7 +87,7 @@ public void unshared() { transform(unshared, it.next()); } - private static void transform(Classfile cc, ClassModel clm) { + private static void transform(ClassFile cc, ClassModel clm) { cc.transform(clm, ClassTransform.transformingMethodBodies((cob, coe) -> { switch (coe) { case FieldInstruction i -> diff --git a/test/micro/org/openjdk/bench/jdk/classfile/RepeatedModelTraversal.java b/test/micro/org/openjdk/bench/jdk/classfile/RepeatedModelTraversal.java index 58ece0671a7fd..45fcbe0f5a52b 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/RepeatedModelTraversal.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/RepeatedModelTraversal.java @@ -29,16 +29,15 @@ import java.util.Iterator; import java.util.ArrayList; import java.util.List; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.components.ClassPrinter; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassFile; +import java.lang.classfile.components.ClassPrinter; import org.openjdk.jmh.annotations.*; @BenchmarkMode(Mode.Throughput) @State(Scope.Benchmark) @Fork(value = 1, jvmArgsAppend = { - "--add-exports", "java.base/jdk.internal.classfile=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.components=ALL-UNNAMED"}) + "--enable-preview"}) @Warmup(iterations = 3) @Measurement(iterations = 4) public class RepeatedModelTraversal { @@ -49,7 +48,7 @@ public class RepeatedModelTraversal { @Setup(Level.Trial) public void setup() throws IOException { models = new ArrayList<>(); - var cc = Classfile.of(); + var cc = ClassFile.of(); Files.walk(FileSystems.getFileSystem(URI.create("jrt:/")).getPath("modules/java.base/java/util")).forEach(p -> { if (Files.isRegularFile(p) && p.toString().endsWith(".class")) try { var clm = cc.parse(p); diff --git a/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java b/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java index 887463dc2e6f4..b5582bcf52e5d 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/Transforms.java @@ -33,17 +33,17 @@ import java.lang.constant.ConstantDescs; import java.util.stream.Stream; -import jdk.internal.classfile.ClassBuilder; -import jdk.internal.classfile.ClassElement; -import jdk.internal.classfile.ClassModel; -import jdk.internal.classfile.ClassTransform; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.CodeElement; -import jdk.internal.classfile.CodeModel; -import jdk.internal.classfile.CodeTransform; -import jdk.internal.classfile.MethodModel; -import jdk.internal.classfile.MethodTransform; -import jdk.internal.classfile.components.ClassRemapper; +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.ClassElement; +import java.lang.classfile.ClassModel; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.ClassFile; +import java.lang.classfile.CodeElement; +import java.lang.classfile.CodeModel; +import java.lang.classfile.CodeTransform; +import java.lang.classfile.MethodModel; +import java.lang.classfile.MethodTransform; +import java.lang.classfile.components.ClassRemapper; import jdk.internal.org.objectweb.asm.AnnotationVisitor; import jdk.internal.org.objectweb.asm.Attribute; import jdk.internal.org.objectweb.asm.ClassReader; @@ -124,8 +124,8 @@ public enum NoOpTransform { UNSHARED_1(false, oneLevelNoop), UNSHARED_2(false, twoLevelNoop), UNSHARED_3(false, threeLevelNoop), - SHARED_3_NO_STACKMAP(true, threeLevelNoop, Classfile.StackMapsOption.DROP_STACK_MAPS), - SHARED_3_NO_DEBUG(true, threeLevelNoop, Classfile.DebugElementsOption.DROP_DEBUG, Classfile.LineNumbersOption.DROP_LINE_NUMBERS), + SHARED_3_NO_STACKMAP(true, threeLevelNoop, ClassFile.StackMapsOption.DROP_STACK_MAPS), + SHARED_3_NO_DEBUG(true, threeLevelNoop, ClassFile.DebugElementsOption.DROP_DEBUG, ClassFile.LineNumbersOption.DROP_LINE_NUMBERS), ASM_1(bytes -> { ClassReader cr = new ClassReader(bytes); jdk.internal.org.objectweb.asm.ClassWriter cw = new jdk.internal.org.objectweb.asm.ClassWriter(cr, jdk.internal.org.objectweb.asm.ClassWriter.COMPUTE_FRAMES); @@ -159,31 +159,31 @@ public enum NoOpTransform { return cw.toByteArray(); }), CLASS_REMAPPER(bytes -> - ClassRemapper.of(Map.of()).remapClass(Classfile.of(), Classfile.of().parse(bytes))); + ClassRemapper.of(Map.of()).remapClass(ClassFile.of(), ClassFile.of().parse(bytes))); // Need ASM, LOW_UNSHARED public final UnaryOperator transform; public final boolean shared; public final ClassTransform classTransform; - public final Classfile cc; + public final ClassFile cc; NoOpTransform(UnaryOperator transform) { this.transform = transform; classTransform = null; shared = false; - cc = Classfile.of(); + cc = ClassFile.of(); } NoOpTransform(boolean shared, ClassTransform classTransform, - Classfile.Option... options) { + ClassFile.Option... options) { this.shared = shared; this.classTransform = classTransform; - this.cc = Classfile.of( + this.cc = ClassFile.of( shared ? options - : Stream.concat(Stream.of(options), Stream.of(Classfile.ConstantPoolSharingOption.NEW_POOL)).toArray(Classfile.Option[]::new)); + : Stream.concat(Stream.of(options), Stream.of(ClassFile.ConstantPoolSharingOption.NEW_POOL)).toArray(ClassFile.Option[]::new)); this.transform = bytes -> cc.transform(cc.parse(bytes), classTransform); } } @@ -196,7 +196,7 @@ public enum InjectNopTransform { return cw.toByteArray(); }), NOP_SHARED(bytes -> { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); return cc.transform(cm, (cb, ce) -> { if (ce instanceof MethodModel mm) { @@ -237,7 +237,7 @@ public enum SimpleTransform { return cw.toByteArray(); }), HIGH_SHARED_ADD_FIELD(bytes -> { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); return cc.transform(cm, new ClassTransform() { @Override @@ -252,7 +252,7 @@ public void atEnd(ClassBuilder builder) { }); }), HIGH_UNSHARED_ADD_FIELD(bytes -> { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); return cc.build(cm.thisClass().asSymbol(), cb -> { @@ -275,7 +275,7 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str return cw.toByteArray(); }), HIGH_SHARED_DEL_METHOD(bytes -> { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); return cc.transform(cm, (builder, element) -> { if (!(element instanceof MethodModel mm)) @@ -283,7 +283,7 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str }); }), HIGH_UNSHARED_DEL_METHOD(bytes -> { - var cc = Classfile.of(); + var cc = ClassFile.of(); ClassModel cm = cc.parse(bytes); return cc.build(cm.thisClass().asSymbol(), cb -> { diff --git a/test/micro/org/openjdk/bench/jdk/classfile/Write.java b/test/micro/org/openjdk/bench/jdk/classfile/Write.java index a4158b4fbbfe0..96aafb6f38e8f 100644 --- a/test/micro/org/openjdk/bench/jdk/classfile/Write.java +++ b/test/micro/org/openjdk/bench/jdk/classfile/Write.java @@ -22,11 +22,11 @@ */ package org.openjdk.bench.jdk.classfile; -import jdk.internal.classfile.AccessFlags; +import java.lang.classfile.AccessFlags; import java.lang.reflect.AccessFlag; -import jdk.internal.classfile.Classfile; -import jdk.internal.classfile.TypeKind; -import jdk.internal.classfile.attribute.SourceFileAttribute; +import java.lang.classfile.ClassFile; +import java.lang.classfile.TypeKind; +import java.lang.classfile.attribute.SourceFileAttribute; import jdk.internal.org.objectweb.asm.*; import org.openjdk.jmh.annotations.*; import java.io.FileOutputStream; @@ -35,8 +35,8 @@ import java.nio.file.Files; import java.nio.file.Paths; -import static jdk.internal.classfile.Opcode.*; -import static jdk.internal.classfile.TypeKind.*; +import static java.lang.classfile.Opcode.*; +import static java.lang.classfile.TypeKind.*; import static org.openjdk.bench.jdk.classfile.TestConstants.*; /** @@ -59,11 +59,7 @@ @Fork(value = 1, jvmArgsAppend = { "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", "--add-exports", "java.base/jdk.internal.org.objectweb.asm.tree=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.attribute=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.constantpool=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.instruction=ALL-UNNAMED", - "--add-exports", "java.base/jdk.internal.classfile.components=ALL-UNNAMED", + "--enable-preview", "--add-exports", "java.base/jdk.internal.classfile.impl=ALL-UNNAMED"}) public class Write { static String checkFileAsm = "/tmp/asw/MyClass.class"; @@ -140,7 +136,7 @@ public byte[] asmStream() { @BenchmarkMode(Mode.Throughput) public byte[] jdkTree() { - byte[] bytes = Classfile.of().build(CD_MyClass, cb -> { + byte[] bytes = ClassFile.of().build(CD_MyClass, cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withVersion(52, 0); cb.with(SourceFileAttribute.of(cb.constantPool().utf8Entry(("MyClass.java")))) @@ -154,8 +150,8 @@ public byte[] jdkTree() { cb.withMethod("main" + ((xi == 0) ? "" : "" + xi), MTD_void_StringArray, AccessFlags.ofMethod(AccessFlag.STATIC, AccessFlag.PUBLIC).flagsMask(), mb -> mb.withCode(c0 -> { - jdk.internal.classfile.Label loopTop = c0.newLabel(); - jdk.internal.classfile.Label loopEnd = c0.newLabel(); + java.lang.classfile.Label loopTop = c0.newLabel(); + java.lang.classfile.Label loopEnd = c0.newLabel(); int vFac = 1; int vI = 2; c0.constantInstruction(ICONST_1, 1) // 0 @@ -188,7 +184,7 @@ public byte[] jdkTree() { @BenchmarkMode(Mode.Throughput) public byte[] jdkTreePrimitive() { - byte[] bytes = Classfile.of().build(CD_MyClass, cb -> { + byte[] bytes = ClassFile.of().build(CD_MyClass, cb -> { cb.withFlags(AccessFlag.PUBLIC); cb.withVersion(52, 0); cb.with(SourceFileAttribute.of(cb.constantPool().utf8Entry(("MyClass.java")))) @@ -202,8 +198,8 @@ public byte[] jdkTreePrimitive() { cb.withMethod("main" + ((xi == 0) ? "" : "" + xi), MTD_void_StringArray, AccessFlags.ofMethod(AccessFlag.STATIC, AccessFlag.PUBLIC).flagsMask(), mb -> mb.withCode(c0 -> { - jdk.internal.classfile.Label loopTop = c0.newLabel(); - jdk.internal.classfile.Label loopEnd = c0.newLabel(); + java.lang.classfile.Label loopTop = c0.newLabel(); + java.lang.classfile.Label loopEnd = c0.newLabel(); int vFac = 1; int vI = 2; c0.constantInstruction(ICONST_1, 1) // 0 diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/TestLoadSegmentVarious.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/TestLoadSegmentVarious.java index 58cd93f3c5166..5ec17c26ca5dd 100644 --- a/test/micro/org/openjdk/bench/jdk/incubator/vector/TestLoadSegmentVarious.java +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/TestLoadSegmentVarious.java @@ -55,6 +55,9 @@ public class TestLoadSegmentVarious { private static final VectorSpecies INTEGER_SPECIES = VectorSpecies.ofLargestShape(int.class); private static final VectorSpecies DOUBLE_SPECIES = VectorSpecies.ofLargestShape(double.class); + private static final VectorMask INTEGER_MASK = VectorMask.fromLong(INTEGER_SPECIES, (1 << (INTEGER_SPECIES.length() / 2)) - 1); + private static final VectorMask DOUBLE_MASK = VectorMask.fromLong(DOUBLE_SPECIES, (1 << (DOUBLE_SPECIES.length() / 2)) - 1); + // Must be evenly dividable by Double.BYTES @Param("1024") private int size; @@ -253,4 +256,27 @@ public void doubleVectorFromDoubleBackedSegment(Blackhole bh) { } } + @Benchmark + public void intVectorFromIntBackedSegmentMasked(Blackhole bh) { + for (int i = 0; i < INTEGER_SPECIES.loopBound(intSrcArray.length); i += INTEGER_SPECIES.vectorByteSize()) { + var v = IntVector.fromMemorySegment(INTEGER_SPECIES, doubleSegment, i, ByteOrder.nativeOrder(), INTEGER_MASK); + bh.consume(v); + } + } + + @Benchmark + public void intVectorFromDoubleBackedSegmentMasked(Blackhole bh) { + for (int i = 0; i < INTEGER_SPECIES.loopBound(intSrcArray.length); i += INTEGER_SPECIES.vectorByteSize()) { + var v = IntVector.fromMemorySegment(INTEGER_SPECIES, doubleSegment, i, ByteOrder.nativeOrder(), INTEGER_MASK); + bh.consume(v); + } + } + + @Benchmark + public void doubleVectorFromIntBackedSegmentMasked(Blackhole bh) { + for (int i = 0; i < DOUBLE_SPECIES.loopBound(doubleSrcArray.length); i += DOUBLE_SPECIES.vectorByteSize()) { + var v = DoubleVector.fromMemorySegment(DOUBLE_SPECIES, intSegment, i, ByteOrder.nativeOrder(), DOUBLE_MASK); + bh.consume(v); + } + } } diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorZeroExtend.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorZeroExtend.java new file mode 100644 index 0000000000000..503d80356da96 --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorZeroExtend.java @@ -0,0 +1,115 @@ +// +// Copyright (c) 2023, Arm Limited. All rights reserved. +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +// +// This code is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License version 2 only, as +// published by the Free Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// version 2 for more details (a copy is included in the LICENSE file that +// accompanied this code). +// +// You should have received a copy of the GNU General Public License version +// 2 along with this work; if not, write to the Free Software Foundation, +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +// or visit www.oracle.com if you need additional information or have any +// questions. +// +// +package org.openjdk.bench.jdk.incubator.vector; + +import java.util.concurrent.TimeUnit; +import java.util.Random; +import jdk.incubator.vector.*; +import org.openjdk.jmh.annotations.*; + +import static jdk.incubator.vector.VectorOperators.*; + +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Thread) +@Fork(jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"}) +public class VectorZeroExtend { + private static final VectorSpecies B_SPECIES = ByteVector.SPECIES_PREFERRED; + private static final VectorSpecies S_SPECIES = ShortVector.SPECIES_PREFERRED; + private static final VectorSpecies I_SPECIES = IntVector.SPECIES_PREFERRED; + private static final VectorSpecies L_SPECIES = LongVector.SPECIES_PREFERRED; + private static final int LENGTH = 128; + private static final Random RD = new Random(); + private static byte[] ba; + private static short[] sa; + private static int[] ia; + private static long[] la; + + static { + ba = new byte[LENGTH]; + sa = new short[LENGTH]; + ia = new int[LENGTH]; + la = new long[LENGTH]; + + for (int i = 0; i < LENGTH; i++) { + ba[i] = (byte) RD.nextInt(); + sa[i] = (short) RD.nextInt(); + ia[i] = RD.nextInt(); + la[i] = RD.nextLong(); + } + } + + @Benchmark + public void byte2Short() { + for (int i = 0; i < B_SPECIES.loopBound(LENGTH); i += B_SPECIES.length()) { + ByteVector va = ByteVector.fromArray(B_SPECIES, ba, i); + ShortVector vb = (ShortVector) va.convertShape(ZERO_EXTEND_B2S, S_SPECIES, 0); + vb.intoArray(sa, 0); + } + } + + @Benchmark + public void byte2Int() { + for (int i = 0; i < B_SPECIES.loopBound(LENGTH); i += B_SPECIES.length()) { + ByteVector va = ByteVector.fromArray(B_SPECIES, ba, i); + IntVector vb = (IntVector) va.convertShape(ZERO_EXTEND_B2I, I_SPECIES, 0); + vb.intoArray(ia, 0); + } + } + + @Benchmark + public void byte2Long() { + for (int i = 0; i < B_SPECIES.loopBound(LENGTH); i += B_SPECIES.length()) { + ByteVector va = ByteVector.fromArray(B_SPECIES, ba, i); + LongVector vb = (LongVector) va.convertShape(ZERO_EXTEND_B2L, L_SPECIES, 0); + vb.intoArray(la, 0); + } + } + + @Benchmark + public void short2Int() { + for (int i = 0; i < S_SPECIES.loopBound(LENGTH); i += S_SPECIES.length()) { + ShortVector va = ShortVector.fromArray(S_SPECIES, sa, i); + IntVector vb = (IntVector) va.convertShape(ZERO_EXTEND_S2I, I_SPECIES, 0); + vb.intoArray(ia, 0); + } + } + + @Benchmark + public void short2Long() { + for (int i = 0; i < S_SPECIES.loopBound(LENGTH); i += S_SPECIES.length()) { + ShortVector va = ShortVector.fromArray(S_SPECIES, sa, i); + LongVector vb = (LongVector) va.convertShape(ZERO_EXTEND_S2L, L_SPECIES, 0); + vb.intoArray(la, 0); + } + } + + @Benchmark + public void int2Long() { + for (int i = 0; i < I_SPECIES.loopBound(LENGTH); i += I_SPECIES.length()) { + IntVector va = IntVector.fromArray(I_SPECIES, ia, i); + LongVector vb = (LongVector) va.convertShape(ZERO_EXTEND_I2L, L_SPECIES, 0); + vb.intoArray(la, 0); + } + } +}