diff --git a/.github/workflows/submit.yml b/.github/workflows/submit.yml index c509994321e..1ddc157a55b 100644 --- a/.github/workflows/submit.yml +++ b/.github/workflows/submit.yml @@ -365,8 +365,8 @@ jobs: "$HOME/linux-x64${{ matrix.artifact }}_testsupport_${{ env.logsuffix }}.zip" . -i *.jtr - -i hs_err* - -i replay* + -i */hs_err*.log + -i */replay*.log continue-on-error: true - name: Persist test results @@ -682,8 +682,8 @@ jobs: "$HOME/windows-x64${{ matrix.artifact }}_testsupport_${{ env.logsuffix }}.zip" . -i *.jtr - -i hs_err* - -i replay* + -i */hs_err*.log + -i */replay*.log continue-on-error: true - name: Persist test results @@ -964,8 +964,8 @@ jobs: "$HOME/macos-x64${{ matrix.artifact }}_testsupport_${{ env.logsuffix }}.zip" . -i *.jtr - -i hs_err* - -i replay* + -i */hs_err*.log + -i */replay*.log continue-on-error: true - name: Persist test results diff --git a/make/CompileJavaModules.gmk b/make/CompileJavaModules.gmk index de462291b09..e8997e0da83 100644 --- a/make/CompileJavaModules.gmk +++ b/make/CompileJavaModules.gmk @@ -184,10 +184,6 @@ ifeq ($(call isTargetOs, windows), true) java.desktop_EXCLUDES += com/sun/java/swing/plaf/gtk endif -ifdef BUILD_HEADLESS_ONLY - java.desktop_EXCLUDES += sun/applet -endif - ifeq ($(call isTargetOs, windows macosx), false) java.desktop_EXCLUDE_FILES += sun/awt/AWTCharset.java endif @@ -389,11 +385,11 @@ endif ################################################################################ -jdk.incubator.jpackage_COPY += .gif .png .txt .spec .script .prerm .preinst \ +jdk.jpackage_COPY += .gif .png .txt .spec .script .prerm .preinst \ .postrm .postinst .list .sh .desktop .copyright .control .plist .template \ .icns .scpt .wxs .wxl .wxi .ico .bmp .tiff -jdk.incubator.jpackage_CLEAN += .properties +jdk.jpackage_CLEAN += .properties ################################################################################ diff --git a/make/Main.gmk b/make/Main.gmk index 31eedcd1f9d..cdb4be67c56 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -338,7 +338,7 @@ $(eval $(call SetupTarget, test-image-demos-jdk, \ $(eval $(call SetupTarget, generate-summary, \ MAKEFILE := GenerateModuleSummary, \ - DEPS := jmods buildtools-modules, \ + DEPS := jmods buildtools-modules runnable-buildjdk, \ )) ################################################################################ @@ -468,7 +468,7 @@ $(eval $(call SetupTarget, docs-jdk-api-javadoc, \ $(eval $(call SetupTarget, docs-jdk-api-modulegraph, \ MAKEFILE := Docs, \ TARGET := docs-jdk-api-modulegraph, \ - DEPS := buildtools-modules, \ + DEPS := buildtools-modules runnable-buildjdk, \ )) $(eval $(call SetupTarget, docs-javase-api-javadoc, \ @@ -479,7 +479,7 @@ $(eval $(call SetupTarget, docs-javase-api-javadoc, \ $(eval $(call SetupTarget, docs-javase-api-modulegraph, \ MAKEFILE := Docs, \ TARGET := docs-javase-api-modulegraph, \ - DEPS := buildtools-modules, \ + DEPS := buildtools-modules runnable-buildjdk, \ )) $(eval $(call SetupTarget, docs-reference-api-javadoc, \ @@ -490,7 +490,7 @@ $(eval $(call SetupTarget, docs-reference-api-javadoc, \ $(eval $(call SetupTarget, docs-reference-api-modulegraph, \ MAKEFILE := Docs, \ TARGET := docs-reference-api-modulegraph, \ - DEPS := buildtools-modules, \ + DEPS := buildtools-modules runnable-buildjdk, \ )) # The gensrc steps for jdk.jdi create html spec files. @@ -1083,6 +1083,18 @@ ifneq ($(COMPILE_TYPE), cross) exploded-image: exploded-image-optimize endif +# The runnable-buildjdk target guarantees that the buildjdk is done +# building and ready to be used. The exact set of dependencies it needs +# depends on what kind of buildjdk is used for the current configuration. +runnable-buildjdk: +ifeq ($(CREATE_BUILDJDK), true) + ifneq ($(CREATING_BUILDJDK), true) + runnable-buildjdk: create-buildjdk + endif +else ifeq ($(EXTERNAL_BUILDJDK), false) + runnable-buildjdk: exploded-image +endif + create-buildjdk: create-buildjdk-interim-image docs-jdk-api: docs-jdk-api-javadoc @@ -1186,7 +1198,7 @@ all-bundles: product-bundles test-bundles docs-bundles static-libs-bundles ALL_TARGETS += buildtools hotspot hotspot-libs hotspot-gensrc gensrc gendata \ copy java libs static-libs launchers jmods \ jdk.jdwp.agent-gensrc $(ALL_MODULES) demos \ - exploded-image-base exploded-image \ + exploded-image-base exploded-image runnable-buildjdk \ create-buildjdk docs-jdk-api docs-javase-api docs-reference-api docs-jdk \ docs-javase docs-reference docs-javadoc mac-bundles product-images legacy-images \ docs-image docs-javase-image docs-reference-image all-docs-images \ diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index eeab75cde90..d4738ad6837 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -663,16 +663,10 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], $1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -DARCH='\"$FLAGS_CPU_LEGACY\"' \ -D$FLAGS_CPU_LEGACY" - if test "x$FLAGS_CPU_BITS" = x64; then - # -D_LP64=1 is only set on linux and mac. Setting on windows causes diff in - # unpack200.exe. - if test "x$FLAGS_OS" = xlinux || test "x$FLAGS_OS" = xmacosx; then - $1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -D_LP64=1" - fi - if test "x$FLAGS_OS" != xaix; then - # xlc on AIX defines _LP64=1 by default and issues a warning if we redefine it. - $1_DEFINES_CPU_JVM="${$1_DEFINES_CPU_JVM} -D_LP64=1" - fi + if test "x$FLAGS_CPU_BITS" = x64 && test "x$FLAGS_OS" != xaix; then + # xlc on AIX defines _LP64=1 by default and issues a warning if we redefine it. + $1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -D_LP64=1" + $1_DEFINES_CPU_JVM="${$1_DEFINES_CPU_JVM} -D_LP64=1" fi # toolchain dependend, per-cpu diff --git a/make/autoconf/jvm-features.m4 b/make/autoconf/jvm-features.m4 index 04ca7b4e909..5ad791795a7 100644 --- a/make/autoconf/jvm-features.m4 +++ b/make/autoconf/jvm-features.m4 @@ -306,7 +306,7 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_GRAAL], # Graal is only available where JVMCI is available since it requires JVMCI. if test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then AC_MSG_RESULT([yes]) - elif test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64"; then + elif test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU]) @@ -340,7 +340,7 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_JVMCI], AC_MSG_CHECKING([if platform is supported by JVMCI]) if test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then AC_MSG_RESULT([yes]) - elif test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64"; then + elif test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU]) diff --git a/make/autoconf/libraries.m4 b/make/autoconf/libraries.m4 index 5120918aed2..e6aafe01550 100644 --- a/make/autoconf/libraries.m4 +++ b/make/autoconf/libraries.m4 @@ -43,9 +43,11 @@ AC_DEFUN_ONCE([LIB_DETERMINE_DEPENDENCIES], if test "x$OPENJDK_TARGET_OS" = xwindows || test "x$OPENJDK_TARGET_OS" = xmacosx; then # No X11 support on windows or macosx NEEDS_LIB_X11=false + elif test "x$ENABLE_HEADLESS_ONLY" = xtrue; then + # No X11 support needed when building headless only + NEEDS_LIB_X11=false else - # All other instances need X11, even if building headless only, libawt still - # needs X11 headers. + # All other instances need X11 NEEDS_LIB_X11=true fi diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in index 339d9f0ac5f..63dc9a5767d 100644 --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in @@ -759,7 +759,6 @@ TAR_SUPPORTS_TRANSFORM:=@TAR_SUPPORTS_TRANSFORM@ # Build setup ENABLE_AOT:=@ENABLE_AOT@ -ENABLE_INTREE_EC:=@ENABLE_INTREE_EC@ USE_EXTERNAL_LIBJPEG:=@USE_EXTERNAL_LIBJPEG@ USE_EXTERNAL_LIBGIF:=@USE_EXTERNAL_LIBGIF@ USE_EXTERNAL_LIBZ:=@USE_EXTERNAL_LIBZ@ diff --git a/make/common/JavaCompilation.gmk b/make/common/JavaCompilation.gmk index 444ded0fc06..bedb971115b 100644 --- a/make/common/JavaCompilation.gmk +++ b/make/common/JavaCompilation.gmk @@ -311,9 +311,11 @@ define SetupJavaCompilationBody ifneq ($$($1_KEEP_DUPS), true) # Remove duplicate source files by keeping the first found of each duplicate. # This allows for automatic overrides with custom or platform specific versions - # source files. + # source files. Need to call DoubleDollar as we have java classes with '$' in + # their names. $1_SRCS := $$(strip $$(foreach s, $$($1_SRCS), \ - $$(eval relative_src := $$(call remove-prefixes, $$($1_SRC), $$(s))) \ + $$(eval relative_src := $$(call remove-prefixes, $$($1_SRC), \ + $$(call DoubleDollar, $$(s)))) \ $$(if $$($1_$$(relative_src)), \ , \ $$(eval $1_$$(relative_src) := 1) $$(s)))) diff --git a/make/common/JdkNativeCompilation.gmk b/make/common/JdkNativeCompilation.gmk index 21134966dc0..6a963ac2c49 100644 --- a/make/common/JdkNativeCompilation.gmk +++ b/make/common/JdkNativeCompilation.gmk @@ -77,8 +77,10 @@ ifeq ($(STATIC_LIBS), true) FindStaticLib = endif +# Returns the module specific java header dir if it exists. +# Param 1 - module name GetJavaHeaderDir = \ - $(wildcard $(SUPPORT_OUTPUTDIR)/headers/$(strip $1)) + $(if $(strip $1),$(wildcard $(SUPPORT_OUTPUTDIR)/headers/$(strip $1))) # Process a dir description such as "java.base:headers" into a set of proper absolute paths. ProcessDir = \ @@ -123,15 +125,27 @@ JDK_RCFLAGS=$(RCFLAGS) \ SetupJdkLibrary = $(NamedParamsMacroTemplate) define SetupJdkLibraryBody ifeq ($$($1_OUTPUT_DIR), ) - $1_OUTPUT_DIR := $$(call FindLibDirForModule, $$(MODULE)) + ifneq ($$(MODULE), ) + $1_OUTPUT_DIR := $$(call FindLibDirForModule, $$(MODULE)) + else + $$(error Must specify OUTPUT_DIR in a MODULE free context) + endif endif ifeq ($$($1_OBJECT_DIR), ) - $1_OBJECT_DIR := $$(SUPPORT_OUTPUTDIR)/native/$$(MODULE)/lib$$($1_NAME) + ifneq ($$(MODULE), ) + $1_OBJECT_DIR := $$(SUPPORT_OUTPUTDIR)/native/$$(MODULE)/lib$$($1_NAME) + else + $$(error Must specify OBJECT_DIR in a MODULE free context) + endif endif ifeq ($$($1_SRC), ) - $1_SRC := $$(call FindSrcDirsForLib, $$(MODULE), $$($1_NAME)) + ifneq ($$(MODULE), ) + $1_SRC := $$(call FindSrcDirsForLib, $$(MODULE), $$($1_NAME)) + else + $$(error Must specify SRC in a MODULE free context) + endif else $1_SRC := $$(foreach dir, $$($1_SRC), $$(call ProcessDir, $$(dir))) endif @@ -165,7 +179,8 @@ define SetupJdkLibraryBody ifneq ($$($1_HEADERS_FROM_SRC), false) $1_SRC_HEADER_FLAGS := $$(addprefix -I, $$(wildcard $$($1_SRC))) endif - # Always add the java header dir + + # Add the module specific java header dir $1_SRC_HEADER_FLAGS += $$(addprefix -I, $$(call GetJavaHeaderDir, $$(MODULE))) ifneq ($$($1_EXTRA_HEADER_DIRS), ) @@ -203,11 +218,19 @@ define SetupJdkExecutableBody $1_TYPE := EXECUTABLE ifeq ($$($1_OUTPUT_DIR), ) - $1_OUTPUT_DIR := $$(call FindExecutableDirForModule, $$(MODULE)) + ifneq ($$(MODULE), ) + $1_OUTPUT_DIR := $$(call FindExecutableDirForModule, $$(MODULE)) + else + $$(error Must specify OUTPUT_DIR in a MODULE free context) + endif endif ifeq ($$($1_OBJECT_DIR), ) - $1_OBJECT_DIR := $$(SUPPORT_OUTPUTDIR)/native/$$(MODULE)/$$($1_NAME) + ifneq ($$(MODULE), ) + $1_OBJECT_DIR := $$(SUPPORT_OUTPUTDIR)/native/$$(MODULE)/$$($1_NAME) + else + $$(error Must specify OBJECT_DIR in a MODULE free context) + endif endif ifeq ($$($1_VERSIONINFO_RESOURCE), ) diff --git a/make/common/Modules.gmk b/make/common/Modules.gmk index 62272edd34a..10aacff4726 100644 --- a/make/common/Modules.gmk +++ b/make/common/Modules.gmk @@ -125,7 +125,7 @@ endif JRE_TOOL_MODULES += \ jdk.jdwp.agent \ - jdk.incubator.jpackage \ + jdk.jpackage \ # ################################################################################ @@ -145,7 +145,7 @@ DOCS_MODULES += \ jdk.editpad \ jdk.hotspot.agent \ jdk.httpserver \ - jdk.incubator.jpackage \ + jdk.jpackage \ jdk.incubator.vector \ jdk.jartool \ jdk.javadoc \ @@ -228,7 +228,7 @@ endif # jpackage is only on windows, macosx, and linux ifeq ($(call isTargetOs, windows macosx linux), false) - MODULES_FILTER += jdk.incubator.jpackage + MODULES_FILTER += jdk.jpackage endif ################################################################################ diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index 7db9aa42b19..2a2581e745c 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -251,6 +251,8 @@ var getJibProfilesCommon = function (input, data) { configure_args: concat("--enable-jtreg-failure-handler", "--with-exclude-translations=de,es,fr,it,ko,pt_BR,sv,ca,tr,cs,sk,ja_JP_A,ja_JP_HA,ja_JP_HI,ja_JP_I,zh_TW,zh_HK", "--disable-manpages", + "--disable-jvm-feature-aot", + "--disable-jvm-feature-graal", "--disable-jvm-feature-shenandoahgc", versionArgs(input, common)) }; @@ -404,9 +406,9 @@ var getJibProfilesProfiles = function (input, common, data) { "linux-x64": { target_os: "linux", target_cpu: "x64", - dependencies: ["devkit", "gtest", "graphviz", "pandoc", "graalunit_lib"], + dependencies: ["devkit", "gtest", "graphviz", "pandoc"], configure_args: concat(common.configure_args_64bit, - "--with-zlib=system", + "--with-zlib=system", "--disable-dtrace", (isWsl(input) ? [ "--host=x86_64-unknown-linux-gnu", "--build=x86_64-unknown-linux-gnu" ] : [])), }, @@ -423,7 +425,7 @@ var getJibProfilesProfiles = function (input, common, data) { "macosx-x64": { target_os: "macosx", target_cpu: "x64", - dependencies: ["devkit", "gtest", "pandoc", "graalunit_lib"], + dependencies: ["devkit", "gtest", "pandoc"], configure_args: concat(common.configure_args_64bit, "--with-zlib=system", "--with-macosx-version-max=10.9.0", // Use system SetFile instead of the one in the devkit as the @@ -434,7 +436,7 @@ var getJibProfilesProfiles = function (input, common, data) { "windows-x64": { target_os: "windows", target_cpu: "x64", - dependencies: ["devkit", "gtest", "pandoc", "graalunit_lib"], + dependencies: ["devkit", "gtest", "pandoc"], configure_args: concat(common.configure_args_64bit), }, @@ -454,8 +456,6 @@ var getJibProfilesProfiles = function (input, common, data) { configure_args: [ "--openjdk-target=aarch64-linux-gnu", "--disable-jvm-feature-jvmci", - "--disable-jvm-feature-graal", - "--disable-jvm-feature-aot", ], }, @@ -687,11 +687,12 @@ var getJibProfilesProfiles = function (input, common, data) { dependencies: [ "boot_jdk", "devkit", "graphviz", "pandoc", buildJdkDep, ], - configure_args: [ + configure_args: concat( "--enable-full-docs", + versionArgs(input, common), "--with-build-jdk=" + input.get(buildJdkDep, "home_path") + (input.build_os == "macosx" ? "/Contents/Home" : "") - ], + ), default_make_targets: ["all-docs-bundles"], artifacts: { doc_api_spec: { @@ -1151,15 +1152,6 @@ var getJibProfilesDependencies = function (input, common) { configure_args: "", }, - graalunit_lib: { - organization: common.organization, - ext: "zip", - revision: "619_Apr_12_2018", - module: "graalunit-lib", - configure_args: "--with-graalunit-lib=" + input.get("graalunit_lib", "install_path"), - environment_name: "GRAALUNIT_LIB" - }, - gtest: { organization: common.organization, ext: "tar.gz", diff --git a/make/hotspot/lib/CompileJvm.gmk b/make/hotspot/lib/CompileJvm.gmk index 441c09a3853..65edd047571 100644 --- a/make/hotspot/lib/CompileJvm.gmk +++ b/make/hotspot/lib/CompileJvm.gmk @@ -91,11 +91,11 @@ DISABLED_WARNINGS_clang := tautological-compare \ undefined-var-template sometimes-uninitialized unknown-pragmas \ delete-non-virtual-dtor missing-braces char-subscripts \ ignored-qualifiers missing-field-initializers mismatched-tags \ - shift-negative-value + shift-negative-value misleading-indentation DISABLED_WARNINGS_xlc := tautological-compare shift-negative-value -DISABLED_WARNINGS_microsoft := 4100 4127 4201 4244 4291 4351 \ +DISABLED_WARNINGS_microsoft := 4100 4127 4146 4201 4244 4291 4351 \ 4511 4512 4514 4624 4996 ################################################################################ diff --git a/make/hotspot/symbols/symbols-unix b/make/hotspot/symbols/symbols-unix index 7504ed52c32..1781d84ab94 100644 --- a/make/hotspot/symbols/symbols-unix +++ b/make/hotspot/symbols/symbols-unix @@ -171,11 +171,13 @@ JVM_NativePath JVM_NewArray JVM_NewInstanceFromConstructor JVM_NewMultiArray +JVM_PhantomReferenceRefersTo JVM_RaiseSignal JVM_RawMonitorCreate JVM_RawMonitorDestroy JVM_RawMonitorEnter JVM_RawMonitorExit +JVM_ReferenceRefersTo JVM_RegisterLambdaProxyClassForArchiving JVM_RegisterSignal JVM_ReleaseUTF diff --git a/make/modules/java.base/lib/CoreLibraries.gmk b/make/modules/java.base/lib/CoreLibraries.gmk index f2b94fe717e..1d5fede2aa8 100644 --- a/make/modules/java.base/lib/CoreLibraries.gmk +++ b/make/modules/java.base/lib/CoreLibraries.gmk @@ -49,7 +49,7 @@ $(eval $(call SetupNativeCompilation, BUILD_LIBFDLIBM, \ CFLAGS_windows_debug := -DLOGGING, \ CFLAGS_aix := -qfloat=nomaf, \ DISABLED_WARNINGS_gcc := sign-compare misleading-indentation array-bounds, \ - DISABLED_WARNINGS_clang := sign-compare, \ + DISABLED_WARNINGS_clang := sign-compare misleading-indentation, \ DISABLED_WARNINGS_microsoft := 4146 4244 4018, \ ARFLAGS := $(ARFLAGS), \ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libfdlibm, \ diff --git a/make/modules/jdk.crypto.ec/Lib.gmk b/make/modules/jdk.crypto.ec/Lib.gmk deleted file mode 100644 index eb1baccc930..00000000000 --- a/make/modules/jdk.crypto.ec/Lib.gmk +++ /dev/null @@ -1,49 +0,0 @@ -# -# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -include LibCommon.gmk - -################################################################################ - -ifeq ($(ENABLE_INTREE_EC), true) - $(eval $(call SetupJdkLibrary, BUILD_LIBSUNEC, \ - NAME := sunec, \ - TOOLCHAIN := TOOLCHAIN_LINK_CXX, \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -DMP_API_COMPATIBLE -DNSS_ECC_MORE_THAN_SUITE_B, \ - CXXFLAGS := $(CXXFLAGS_JDKLIB), \ - DISABLED_WARNINGS_gcc := sign-compare implicit-fallthrough unused-value, \ - DISABLED_WARNINGS_clang := sign-compare, \ - DISABLED_WARNINGS_microsoft := 4101 4244 4146 4018, \ - LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK), \ - LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_ORIGIN), \ - LIBS := $(LIBCXX), \ - )) - - TARGETS += $(BUILD_LIBSUNEC) -endif - -################################################################################ diff --git a/make/modules/jdk.javadoc/Gendata.gmk b/make/modules/jdk.javadoc/Gendata.gmk index 5b4485808c7..0ee146a1e21 100644 --- a/make/modules/jdk.javadoc/Gendata.gmk +++ b/make/modules/jdk.javadoc/Gendata.gmk @@ -54,7 +54,7 @@ $(eval $(call SetupJavaCompilation, COMPILE_CREATE_SYMBOLS, \ SRC := $(TOPDIR)/make/langtools/src/classes \ $(TOPDIR)/src/jdk.jdeps/share/classes, \ INCLUDES := build/tools/symbolgenerator com/sun/tools/classfile, \ - BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols, \ + BIN := $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc, \ DISABLED_WARNINGS := options, \ JAVAC_FLAGS := \ $(INTERIM_LANGTOOLS_ARGS) \ @@ -71,7 +71,7 @@ $(SUPPORT_OUTPUTDIR)/javadoc-symbols/symbols: \ $(ECHO) Creating javadoc element list $(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \ $(COMPILECREATESYMBOLS_ADD_EXPORTS) \ - -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols \ + -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc \ build.tools.symbolgenerator.CreateSymbols \ build-javadoc-data \ $(CT_DATA_DESCRIPTION) \ @@ -79,7 +79,7 @@ $(SUPPORT_OUTPUTDIR)/javadoc-symbols/symbols: \ 11 $(JAVA_SMALL) $(INTERIM_LANGTOOLS_ARGS) \ $(COMPILECREATESYMBOLS_ADD_EXPORTS) \ - -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols \ + -classpath $(BUILDTOOLS_OUTPUTDIR)/create_symbols_javadoc \ build.tools.symbolgenerator.JavadocElementList \ $(JDK_OUTPUTDIR)/modules/jdk.javadoc/jdk/javadoc/internal/doclets/toolkit/resources/releases/element-list-$(JDK_SOURCE_TARGET_VERSION).txt \ $(JAVADOC_MODULESOURCEPATH) \ diff --git a/make/modules/jdk.incubator.jpackage/Gensrc.gmk b/make/modules/jdk.jpackage/Gensrc.gmk similarity index 93% rename from make/modules/jdk.incubator.jpackage/Gensrc.gmk rename to make/modules/jdk.jpackage/Gensrc.gmk index 5948a80f120..6f3e8b08119 100644 --- a/make/modules/jdk.incubator.jpackage/Gensrc.gmk +++ b/make/modules/jdk.jpackage/Gensrc.gmk @@ -31,7 +31,7 @@ include GensrcCommonJdk.gmk ifeq ($(call isTargetOs, macosx), true) ENTITLEMENTS_SRC_FILE := $(TOPDIR)/make/data/macosxsigning/java.plist ENTITLEMENTS_TARGET_FILE := \ - $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/jdk/incubator/jpackage/internal/resources/entitlements.plist + $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/jdk/jpackage/internal/resources/entitlements.plist $(ENTITLEMENTS_TARGET_FILE): $(ENTITLEMENTS_SRC_FILE) $(call install-file) diff --git a/make/modules/jdk.incubator.jpackage/Launcher.gmk b/make/modules/jdk.jpackage/Launcher.gmk similarity index 95% rename from make/modules/jdk.incubator.jpackage/Launcher.gmk rename to make/modules/jdk.jpackage/Launcher.gmk index 7a25dae733c..8d553d5c107 100644 --- a/make/modules/jdk.incubator.jpackage/Launcher.gmk +++ b/make/modules/jdk.jpackage/Launcher.gmk @@ -26,5 +26,5 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jpackage, \ - MAIN_CLASS := jdk.incubator.jpackage.main.Main, \ + MAIN_CLASS := jdk.jpackage.main.Main, \ )) diff --git a/make/modules/jdk.incubator.jpackage/Lib.gmk b/make/modules/jdk.jpackage/Lib.gmk similarity index 91% rename from make/modules/jdk.incubator.jpackage/Lib.gmk rename to make/modules/jdk.jpackage/Lib.gmk index 7ffef99afe4..7dfb70be5a6 100644 --- a/make/modules/jdk.incubator.jpackage/Lib.gmk +++ b/make/modules/jdk.jpackage/Lib.gmk @@ -29,8 +29,8 @@ include LibCommon.gmk JPACKAGE_APPLAUNCHER_SRC := \ - $(call FindSrcDirsForComponent, jdk.incubator.jpackage, applauncher) \ - $(call FindSrcDirsForComponent, jdk.incubator.jpackage, common) + $(call FindSrcDirsForComponent, jdk.jpackage, applauncher) \ + $(call FindSrcDirsForComponent, jdk.jpackage, common) ifeq ($(call isTargetOs, windows), true) @@ -42,7 +42,7 @@ else endif -JPACKAGE_OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/incubator/jpackage/internal/resources +JPACKAGE_OUTPUT_DIR := $(JDK_OUTPUTDIR)/modules/$(MODULE)/jdk/jpackage/internal/resources JPACKAGE_CXXFLAGS_windows := -EHsc -DUNICODE -D_UNICODE # Output app launcher executable in resources dir, and symbols in the object dir @@ -73,7 +73,7 @@ ifeq ($(call isTargetOs, windows), true) $(eval $(call SetupJdkLibrary, BUILD_LIB_JPACKAGE, \ NAME := jpackage, \ OPTIMIZATION := LOW, \ - EXTRA_SRC := jdk.incubator.jpackage:common, \ + EXTRA_SRC := jdk.jpackage:common, \ CXXFLAGS := $(CXXFLAGS_JDKLIB) $(JPACKAGE_CXXFLAGS_windows), \ LDFLAGS := $(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ @@ -99,8 +99,8 @@ ifeq ($(call isTargetOs, windows), true) TARGETS += $(BUILD_LIB_WIXHELPER) JPACKAGE_MSIWRAPPER_SRC := \ - $(call FindSrcDirsForComponent, jdk.incubator.jpackage, msiwrapper) \ - $(call FindSrcDirsForComponent, jdk.incubator.jpackage, common) + $(call FindSrcDirsForComponent, jdk.jpackage, msiwrapper) \ + $(call FindSrcDirsForComponent, jdk.jpackage, common) # Build exe installer wrapper for msi installer $(eval $(call SetupJdkExecutable, BUILD_JPACKAGE_MSIWRAPPER, \ diff --git a/make/scripts/compare.sh b/make/scripts/compare.sh index 25630199a21..5d0e846e755 100644 --- a/make/scripts/compare.sh +++ b/make/scripts/compare.sh @@ -696,7 +696,7 @@ compare_bin_file() { # pdb files. PDB_DIRS="$(ls -d \ {$OTHER,$THIS}/support/modules_{cmds,libs}/{*,*/*} \ - {$OTHER,$THIS}/support/native/jdk.incubator.jpackage/* \ + {$OTHER,$THIS}/support/native/jdk.jpackage/* \ )" export _NT_SYMBOL_PATH="$(echo $PDB_DIRS | tr ' ' ';')" fi diff --git a/src/demo/share/jfc/Notepad/Notepad.java b/src/demo/share/jfc/Notepad/Notepad.java index 3ebe3f07d22..cb4552f94cf 100644 --- a/src/demo/share/jfc/Notepad/Notepad.java +++ b/src/demo/share/jfc/Notepad/Notepad.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -60,7 +60,7 @@ * @author Timothy Prinzing */ @SuppressWarnings("serial") -class Notepad extends JPanel { +public class Notepad extends JPanel { protected static Properties properties; private static ResourceBundle resources; diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp index 75b4451450d..ba352461e4a 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp @@ -217,7 +217,7 @@ class Instruction_aarch64 { static void patch(address a, int msb, int lsb, uint64_t val) { int nbits = msb - lsb + 1; - guarantee(val < (1U << nbits), "Field too big for insn"); + guarantee(val < (1ULL << nbits), "Field too big for insn"); assert_cond(msb >= lsb); unsigned mask = (1U << nbits) - 1; val <<= lsb; @@ -445,8 +445,8 @@ class Address { } Register base() const { - guarantee((_mode == base_plus_offset | _mode == base_plus_offset_reg - | _mode == post | _mode == post_reg), + guarantee((_mode == base_plus_offset || _mode == base_plus_offset_reg + || _mode == post || _mode == post_reg), "wrong mode"); return _base; } diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.cpp b/src/hotspot/cpu/aarch64/frame_aarch64.cpp index ff5136364c5..72a9598daac 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp @@ -663,11 +663,12 @@ intptr_t* frame::real_fp() const { #undef DESCRIBE_FP_OFFSET -#define DESCRIBE_FP_OFFSET(name) \ - { \ - uintptr_t *p = (uintptr_t *)fp; \ - printf("0x%016lx 0x%016lx %s\n", (uintptr_t)(p + frame::name##_offset), \ - p[frame::name##_offset], #name); \ +#define DESCRIBE_FP_OFFSET(name) \ + { \ + uintptr_t *p = (uintptr_t *)fp; \ + printf(INTPTR_FORMAT " " INTPTR_FORMAT " %s\n", \ + (uintptr_t)(p + frame::name##_offset), \ + p[frame::name##_offset], #name); \ } static THREAD_LOCAL uintptr_t nextfp; diff --git a/src/hotspot/cpu/aarch64/gc/shenandoah/c1/shenandoahBarrierSetC1_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shenandoah/c1/shenandoahBarrierSetC1_aarch64.cpp index b3530509b03..db9c7577e60 100644 --- a/src/hotspot/cpu/aarch64/gc/shenandoah/c1/shenandoahBarrierSetC1_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/c1/shenandoahBarrierSetC1_aarch64.cpp @@ -109,7 +109,7 @@ LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRIt __ xchg(access.resolved_addr(), value_opr, result, tmp); if (access.is_oop()) { - result = load_reference_barrier(access.gen(), result, LIR_OprFact::addressConst(0), false); + result = load_reference_barrier(access.gen(), result, LIR_OprFact::addressConst(0), ShenandoahBarrierSet::AccessKind::NORMAL); LIR_Opr tmp = gen->new_register(type); __ move(result, tmp); result = tmp; diff --git a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp index 5d9f191bba8..840464b251f 100644 --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp @@ -43,8 +43,6 @@ #define __ masm-> -address ShenandoahBarrierSetAssembler::_shenandoah_lrb = NULL; - void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, Register src, Register dst, Register count, RegSet saved_regs) { if (is_oop) { @@ -227,18 +225,18 @@ void ShenandoahBarrierSetAssembler::resolve_forward_pointer_not_null(MacroAssemb } } -void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Address load_addr) { +void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst, Address load_addr, ShenandoahBarrierSet::AccessKind kind) { assert(ShenandoahLoadRefBarrier, "Should be enabled"); assert(dst != rscratch2, "need rscratch2"); assert_different_registers(load_addr.base(), load_addr.index(), rscratch1, rscratch2); - Label done; + Label heap_stable, not_cset; __ enter(); Address gc_state(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); __ ldrb(rscratch2, gc_state); // Check for heap stability - __ tbz(rscratch2, ShenandoahHeap::HAS_FORWARDED_BITPOS, done); + __ tbz(rscratch2, ShenandoahHeap::HAS_FORWARDED_BITPOS, heap_stable); // use r1 for load address Register result_dst = dst; @@ -253,51 +251,48 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembl __ lea(r1, load_addr); __ mov(r0, dst); - __ far_call(RuntimeAddress(CAST_FROM_FN_PTR(address, ShenandoahBarrierSetAssembler::shenandoah_lrb()))); - - __ mov(result_dst, r0); - __ pop(to_save, sp); - - __ bind(done); - __ leave(); -} - -void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Address load_addr) { - if (!ShenandoahLoadRefBarrier) { - return; + // Test for in-cset + if (kind == ShenandoahBarrierSet::AccessKind::NORMAL) { + __ mov(rscratch2, ShenandoahHeap::in_cset_fast_test_addr()); + __ lsr(rscratch1, r0, ShenandoahHeapRegion::region_size_bytes_shift_jint()); + __ ldrb(rscratch2, Address(rscratch2, rscratch1)); + __ tbz(rscratch2, 0, not_cset); } - assert(dst != rscratch2, "need rscratch2"); - - Label is_null; - Label done; - - __ block_comment("load_reference_barrier_native { "); - - __ cbz(dst, is_null); - - __ enter(); - - Address gc_state(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); - __ ldrb(rscratch2, gc_state); - - // Check for heap in evacuation phase - __ tbz(rscratch2, ShenandoahHeap::HAS_FORWARDED_BITPOS, done); - - __ mov(rscratch2, dst); __ push_call_clobbered_registers(); - __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)); - __ lea(r1, load_addr); - __ mov(r0, rscratch2); + switch (kind) { + case ShenandoahBarrierSet::AccessKind::NORMAL: + if (UseCompressedOops) { + __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow)); + } else { + __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier)); + } + break; + case ShenandoahBarrierSet::AccessKind::WEAK: + if (UseCompressedOops) { + __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak_narrow)); + } else { + __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak)); + } + break; + case ShenandoahBarrierSet::AccessKind::NATIVE: + __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak)); + break; + default: + ShouldNotReachHere(); + } __ blr(lr); - __ mov(rscratch2, r0); + __ mov(rscratch1, r0); __ pop_call_clobbered_registers(); - __ mov(dst, rscratch2); + __ mov(r0, rscratch1); - __ bind(done); + __ bind(not_cset); + + __ mov(result_dst, r0); + __ pop(to_save, sp); + + __ bind(heap_stable); __ leave(); - __ bind(is_null); - __ block_comment("} load_reference_barrier_native"); } void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) { @@ -308,15 +303,6 @@ void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Regis } } -void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst, Address load_addr) { - if (ShenandoahLoadRefBarrier) { - Label is_null; - __ cbz(dst, is_null); - load_reference_barrier_not_null(masm, dst, load_addr); - __ bind(is_null); - } -} - // // Arguments: // @@ -352,11 +338,8 @@ void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet d BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); - if (ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type)) { - load_reference_barrier_native(masm, dst, src); - } else { - load_reference_barrier(masm, dst, src); - } + ShenandoahBarrierSet::AccessKind kind = ShenandoahBarrierSet::access_kind(decorators, type); + load_reference_barrier(masm, dst, src, kind); if (dst != result_dst) { __ mov(result_dst, dst); @@ -477,7 +460,8 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, bool is_narrow = UseCompressedOops; Assembler::operand_size size = is_narrow ? Assembler::word : Assembler::xword; - assert_different_registers(addr, expected, new_val, tmp1, tmp2); + assert_different_registers(addr, expected, tmp1, tmp2); + assert_different_registers(addr, new_val, tmp1, tmp2); Label step4, done; @@ -669,10 +653,18 @@ void ShenandoahBarrierSetAssembler::gen_load_reference_barrier_stub(LIR_Assemble __ bind(slow_path); ce->store_parameter(res, 0); ce->store_parameter(addr, 1); - if (stub->is_native()) { - __ far_call(RuntimeAddress(bs->load_reference_barrier_native_rt_code_blob()->code_begin())); - } else { - __ far_call(RuntimeAddress(bs->load_reference_barrier_rt_code_blob()->code_begin())); + switch (stub->kind()) { + case ShenandoahBarrierSet::AccessKind::NORMAL: + __ far_call(RuntimeAddress(bs->load_reference_barrier_normal_rt_code_blob()->code_begin())); + break; + case ShenandoahBarrierSet::AccessKind::WEAK: + __ far_call(RuntimeAddress(bs->load_reference_barrier_weak_rt_code_blob()->code_begin())); + break; + case ShenandoahBarrierSet::AccessKind::NATIVE: + __ far_call(RuntimeAddress(bs->load_reference_barrier_native_rt_code_blob()->code_begin())); + break; + default: + ShouldNotReachHere(); } __ b(*stub->continuation()); @@ -728,19 +720,33 @@ void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAss __ epilogue(); } -void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_native) { +void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, ShenandoahBarrierSet::AccessKind kind) { __ prologue("shenandoah_load_reference_barrier", false); // arg0 : object to be resolved __ push_call_clobbered_registers(); __ load_parameter(0, r0); __ load_parameter(1, r1); - if (is_native) { - __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)); - } else if (UseCompressedOops) { - __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow)); - } else { - __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier)); + switch (kind) { + case ShenandoahBarrierSet::AccessKind::NORMAL: + if (UseCompressedOops) { + __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow)); + } else { + __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier)); + } + break; + case ShenandoahBarrierSet::AccessKind::WEAK: + if (UseCompressedOops) { + __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak_narrow)); + } else { + __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak)); + } + break; + case ShenandoahBarrierSet::AccessKind::NATIVE: + __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak)); + break; + default: + ShouldNotReachHere(); } __ blr(lr); __ mov(rscratch1, r0); @@ -753,67 +759,3 @@ void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_s #undef __ #endif // COMPILER1 - -address ShenandoahBarrierSetAssembler::shenandoah_lrb() { - assert(_shenandoah_lrb != NULL, "need load reference barrier stub"); - return _shenandoah_lrb; -} - -#define __ cgen->assembler()-> - -// Shenandoah load reference barrier. -// -// Input: -// r0: OOP to evacuate. Not null. -// r1: load address -// -// Output: -// r0: Pointer to evacuated OOP. -// -// Trash rscratch1, rscratch2. Preserve everything else. -address ShenandoahBarrierSetAssembler::generate_shenandoah_lrb(StubCodeGenerator* cgen) { - - __ align(6); - StubCodeMark mark(cgen, "StubRoutines", "shenandoah_lrb"); - address start = __ pc(); - - Label slow_path; - __ mov(rscratch2, ShenandoahHeap::in_cset_fast_test_addr()); - __ lsr(rscratch1, r0, ShenandoahHeapRegion::region_size_bytes_shift_jint()); - __ ldrb(rscratch2, Address(rscratch2, rscratch1)); - __ tbnz(rscratch2, 0, slow_path); - __ ret(lr); - - __ bind(slow_path); - __ enter(); // required for proper stackwalking of RuntimeStub frame - - __ push_call_clobbered_registers(); - - if (UseCompressedOops) { - __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow)); - } else { - __ mov(lr, CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier)); - } - __ blr(lr); - __ mov(rscratch1, r0); - __ pop_call_clobbered_registers(); - __ mov(r0, rscratch1); - - __ leave(); // required for proper stackwalking of RuntimeStub frame - __ ret(lr); - - return start; -} - -#undef __ - -void ShenandoahBarrierSetAssembler::barrier_stubs_init() { - if (ShenandoahLoadRefBarrier) { - int stub_code_size = 2048; - ResourceMark rm; - BufferBlob* bb = BufferBlob::create("shenandoah_barrier_stubs", stub_code_size); - CodeBuffer buf(bb); - StubCodeGenerator cgen(&buf); - _shenandoah_lrb = generate_shenandoah_lrb(&cgen); - } -} diff --git a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp index 88aa9a2b95f..60303725fd8 100644 --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp @@ -27,6 +27,7 @@ #include "asm/macroAssembler.hpp" #include "gc/shared/barrierSetAssembler.hpp" +#include "gc/shenandoah/shenandoahBarrierSet.hpp" #ifdef COMPILER1 class LIR_Assembler; class ShenandoahPreBarrierStub; @@ -38,8 +39,6 @@ class StubCodeGenerator; class ShenandoahBarrierSetAssembler: public BarrierSetAssembler { private: - static address _shenandoah_lrb; - void satb_write_barrier_pre(MacroAssembler* masm, Register obj, Register pre_val, @@ -57,14 +56,9 @@ class ShenandoahBarrierSetAssembler: public BarrierSetAssembler { void resolve_forward_pointer(MacroAssembler* masm, Register dst, Register tmp = noreg); void resolve_forward_pointer_not_null(MacroAssembler* masm, Register dst, Register tmp = noreg); - void load_reference_barrier(MacroAssembler* masm, Register dst, Address load_addr); - void load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Address load_addr); - void load_reference_barrier_native(MacroAssembler* masm, Register dst, Address load_addr); - - address generate_shenandoah_lrb(StubCodeGenerator* cgen); + void load_reference_barrier(MacroAssembler* masm, Register dst, Address load_addr, ShenandoahBarrierSet::AccessKind kind); public: - static address shenandoah_lrb(); void storeval_barrier(MacroAssembler* masm, Register dst, Register tmp); @@ -72,7 +66,7 @@ class ShenandoahBarrierSetAssembler: public BarrierSetAssembler { void gen_pre_barrier_stub(LIR_Assembler* ce, ShenandoahPreBarrierStub* stub); void gen_load_reference_barrier_stub(LIR_Assembler* ce, ShenandoahLoadReferenceBarrierStub* stub); void generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm); - void generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_native); + void generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, ShenandoahBarrierSet::AccessKind kind); #endif virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, bool is_oop, @@ -85,8 +79,6 @@ class ShenandoahBarrierSetAssembler: public BarrierSetAssembler { Register obj, Register tmp, Label& slowpath); void cmpxchg_oop(MacroAssembler* masm, Register addr, Register expected, Register new_val, bool acquire, bool release, bool is_cae, Register result); - - virtual void barrier_stubs_init(); }; #endif // CPU_AARCH64_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp index 3156b4b8e83..f41d79e1021 100644 --- a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp @@ -21,8 +21,9 @@ * questions. */ - #include "jvmci/jvmci.hpp" - #include "jvmci/jvmciCodeInstaller.hpp" +#include "precompiled.hpp" +#include "jvmci/jvmci.hpp" +#include "jvmci/jvmciCodeInstaller.hpp" #include "jvmci/jvmciRuntime.hpp" #include "jvmci/jvmciCompilerToVM.hpp" #include "jvmci/jvmciJavaClasses.hpp" diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 6c547254213..1e5de08315e 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -1876,7 +1876,7 @@ bool MacroAssembler::try_merge_ldst(Register rt, const Address &adr, size_t size return true; } else { assert(size_in_bytes == 8 || size_in_bytes == 4, "only 8 bytes or 4 bytes load/store is supported."); - const unsigned mask = size_in_bytes - 1; + const uint64_t mask = size_in_bytes - 1; if (adr.getMode() == Address::base_plus_offset && (adr.offset() & mask) == 0) { // only supports base_plus_offset. code()->set_last_insn(pc()); @@ -2940,7 +2940,7 @@ void MacroAssembler::merge_ldst(Register rt, // Overwrite previous generated binary. code_section()->set_end(prev); - const int sz = prev_ldst->size_in_bytes(); + const size_t sz = prev_ldst->size_in_bytes(); assert(sz == 8 || sz == 4, "only supports 64/32bit merging."); if (!is_store) { BLOCK_COMMENT("merged ldr pair"); diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp index d40c533a82c..dcf87913a88 100644 --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp @@ -655,7 +655,7 @@ class NativeLdSt : public NativeInstruction { return 0; } } - size_t size_in_bytes() { return 1 << size(); } + size_t size_in_bytes() { return 1ULL << size(); } bool is_not_pre_post_index() { return (is_ldst_ur() || is_ldst_unsigned_offset()); } bool is_load() { assert(Instruction_aarch64::extract(uint_at(0), 23, 22) == 0b01 || diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index 82ad56183d9..2d6bbc0e2ab 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -1765,7 +1765,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, // Generate stack overflow check if (UseStackBanging) { - __ bang_stack_with_offset(StackOverflow::stack_shadow_zone_size()); + __ bang_stack_with_offset(checked_cast(StackOverflow::stack_shadow_zone_size())); } else { Unimplemented(); } @@ -2714,7 +2714,7 @@ void SharedRuntime::generate_deopt_blob() { __ sub(sp, sp, r19); // Push interpreter frames in a loop - __ mov(rscratch1, (address)0xDEADDEAD); // Make a recognizable pattern + __ mov(rscratch1, (uint64_t)0xDEADDEAD); // Make a recognizable pattern __ mov(rscratch2, rscratch1); Label loop; __ bind(loop); diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index 0e74d3e4da7..b1e95074942 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -1320,14 +1320,14 @@ class StubGenerator: public StubCodeGenerator { // Scan over array at a for count oops, verifying each one. // Preserves a and count, clobbers rscratch1 and rscratch2. - void verify_oop_array (size_t size, Register a, Register count, Register temp) { + void verify_oop_array (int size, Register a, Register count, Register temp) { Label loop, end; __ mov(rscratch1, a); __ mov(rscratch2, zr); __ bind(loop); __ cmp(rscratch2, count); __ br(Assembler::HS, end); - if (size == (size_t)wordSize) { + if (size == wordSize) { __ ldr(temp, Address(a, rscratch2, Address::lsl(exact_log2(size)))); __ verify_oop(temp); } else { @@ -1358,7 +1358,7 @@ class StubGenerator: public StubCodeGenerator { // disjoint_int_copy_entry is set to the no-overlap entry point // used by generate_conjoint_int_oop_copy(). // - address generate_disjoint_copy(size_t size, bool aligned, bool is_oop, address *entry, + address generate_disjoint_copy(int size, bool aligned, bool is_oop, address *entry, const char *name, bool dest_uninitialized = false) { Register s = c_rarg0, d = c_rarg1, count = c_rarg2; RegSet saved_reg = RegSet::of(s, d, count); @@ -1424,7 +1424,7 @@ class StubGenerator: public StubCodeGenerator { // the hardware handle it. The two dwords within qwords that span // cache line boundaries will still be loaded and stored atomicly. // - address generate_conjoint_copy(size_t size, bool aligned, bool is_oop, address nooverlap_target, + address generate_conjoint_copy(int size, bool aligned, bool is_oop, address nooverlap_target, address *entry, const char *name, bool dest_uninitialized = false) { Register s = c_rarg0, d = c_rarg1, count = c_rarg2; @@ -1675,7 +1675,7 @@ class StubGenerator: public StubCodeGenerator { address generate_disjoint_oop_copy(bool aligned, address *entry, const char *name, bool dest_uninitialized) { const bool is_oop = true; - const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + const int size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); return generate_disjoint_copy(size, aligned, is_oop, entry, name, dest_uninitialized); } @@ -1693,7 +1693,7 @@ class StubGenerator: public StubCodeGenerator { address nooverlap_target, address *entry, const char *name, bool dest_uninitialized) { const bool is_oop = true; - const size_t size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); + const int size = UseCompressedOops ? sizeof (jint) : sizeof (jlong); return generate_conjoint_copy(size, aligned, is_oop, nooverlap_target, entry, name, dest_uninitialized); } diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index 51b83b2454d..de2a3a02e62 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -1127,7 +1127,7 @@ void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) { // an interpreter frame with greater than a page of locals, so each page // needs to be checked. Only true for non-native. if (UseStackBanging) { - const int n_shadow_pages = StackOverflow::stack_shadow_zone_size() / os::vm_page_size(); + const int n_shadow_pages = (int)(StackOverflow::stack_shadow_zone_size() / os::vm_page_size()); const int start_page = native_call ? n_shadow_pages : 1; const int page_size = os::vm_page_size(); for (int pages = start_page; pages <= n_shadow_pages ; pages++) { diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index 1f6b196d3ce..3933bac000f 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -9803,7 +9803,7 @@ void Assembler::cmpq(Register dst, int32_t imm32) { void Assembler::cmpq(Address dst, Register src) { InstructionMark im(this); - emit_int16(get_prefixq(dst, src), 0x3B); + emit_int16(get_prefixq(dst, src), 0x39); emit_operand(src, dst); } diff --git a/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp b/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp index 34428f234a3..73512adb6e7 100644 --- a/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp +++ b/src/hotspot/cpu/x86/c1_CodeStubs_x86.cpp @@ -81,19 +81,29 @@ void ConversionStub::emit_code(LIR_Assembler* ce) { #endif // !_LP64 void C1SafepointPollStub::emit_code(LIR_Assembler* ce) { -#ifdef _LP64 __ bind(_entry); InternalAddress safepoint_pc(ce->masm()->pc() - ce->masm()->offset() + safepoint_offset()); +#ifdef _LP64 __ lea(rscratch1, safepoint_pc); __ movptr(Address(r15_thread, JavaThread::saved_exception_pc_offset()), rscratch1); +#else + const Register tmp1 = rcx; + const Register tmp2 = rdx; + __ push(tmp1); + __ push(tmp2); + + __ lea(tmp1, safepoint_pc); + __ get_thread(tmp2); + __ movptr(Address(tmp2, JavaThread::saved_exception_pc_offset()), tmp1); + __ pop(tmp2); + __ pop(tmp1); +#endif /* _LP64 */ assert(SharedRuntime::polling_page_return_handler_blob() != NULL, "polling page return stub not created yet"); + address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point(); __ jump(RuntimeAddress(stub)); -#else - ShouldNotReachHere(); -#endif /* _LP64 */ } void CounterOverflowStub::emit_code(LIR_Assembler* ce) { diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp index f34f2dfab72..401501a6631 100644 --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp @@ -556,17 +556,14 @@ void LIR_Assembler::return_op(LIR_Opr result, C1SafepointPollStub* code_stub) { // the poll sets the condition code, but no data registers #ifdef _LP64 - code_stub->set_safepoint_offset(__ offset()); - __ relocate(relocInfo::poll_return_type); - __ safepoint_poll(*code_stub->entry(), r15_thread, true /* at_return */, true /* in_nmethod */); + const Register thread = r15_thread; #else - const Register poll_addr = rbx; - assert(FrameMap::is_caller_save_register(poll_addr), "will overwrite"); - __ get_thread(poll_addr); - __ movptr(poll_addr, Address(poll_addr, Thread::polling_page_offset())); - __ relocate(relocInfo::poll_return_type); - __ testl(rax, Address(poll_addr, 0)); + const Register thread = rbx; + __ get_thread(thread); #endif + code_stub->set_safepoint_offset(__ offset()); + __ relocate(relocInfo::poll_return_type); + __ safepoint_poll(*code_stub->entry(), thread, true /* at_return */, true /* in_nmethod */); __ ret(0); } diff --git a/src/hotspot/cpu/x86/c2_safepointPollStubTable_x86.cpp b/src/hotspot/cpu/x86/c2_safepointPollStubTable_x86.cpp index 55a923bc588..c3d4850a5db 100644 --- a/src/hotspot/cpu/x86/c2_safepointPollStubTable_x86.cpp +++ b/src/hotspot/cpu/x86/c2_safepointPollStubTable_x86.cpp @@ -31,7 +31,6 @@ #define __ masm. void C2SafepointPollStubTable::emit_stub_impl(MacroAssembler& masm, C2SafepointPollStub* entry) const { -#ifdef _LP64 assert(SharedRuntime::polling_page_return_handler_blob() != NULL, "polling page return stub not created yet"); address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point(); @@ -40,11 +39,22 @@ void C2SafepointPollStubTable::emit_stub_impl(MacroAssembler& masm, C2SafepointP __ bind(entry->_stub_label); InternalAddress safepoint_pc(masm.pc() - masm.offset() + entry->_safepoint_offset); +#ifdef _LP64 __ lea(rscratch1, safepoint_pc); __ movptr(Address(r15_thread, JavaThread::saved_exception_pc_offset()), rscratch1); - __ jump(callback_addr); #else - ShouldNotReachHere(); + const Register tmp1 = rcx; + const Register tmp2 = rdx; + __ push(tmp1); + __ push(tmp2); + + __ lea(tmp1, safepoint_pc); + __ get_thread(tmp2); + __ movptr(Address(tmp2, JavaThread::saved_exception_pc_offset()), tmp1); + + __ pop(tmp2); + __ pop(tmp1); #endif + __ jump(callback_addr); } #undef __ diff --git a/src/hotspot/cpu/x86/gc/shenandoah/c1/shenandoahBarrierSetC1_x86.cpp b/src/hotspot/cpu/x86/gc/shenandoah/c1/shenandoahBarrierSetC1_x86.cpp index 58dcd9ed5fb..01b53c5266a 100644 --- a/src/hotspot/cpu/x86/gc/shenandoah/c1/shenandoahBarrierSetC1_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shenandoah/c1/shenandoahBarrierSetC1_x86.cpp @@ -111,7 +111,7 @@ LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRIt __ xchg(access.resolved_addr(), result, result, LIR_OprFact::illegalOpr); if (access.is_oop()) { - result = load_reference_barrier(access.gen(), result, LIR_OprFact::addressConst(0), false); + result = load_reference_barrier(access.gen(), result, LIR_OprFact::addressConst(0), ShenandoahBarrierSet::AccessKind::NORMAL); LIR_Opr tmp = gen->new_register(type); __ move(result, tmp); result = tmp; diff --git a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp index ef1ce91b0df..4867ddeb00f 100644 --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp @@ -32,7 +32,6 @@ #include "gc/shenandoah/shenandoahThreadLocalData.hpp" #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp" #include "interpreter/interpreter.hpp" -#include "interpreter/interp_masm.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/thread.hpp" #include "utilities/macros.hpp" @@ -44,8 +43,6 @@ #define __ masm-> -address ShenandoahBarrierSetAssembler::_shenandoah_lrb = NULL; - static void save_xmm_registers(MacroAssembler* masm) { __ subptr(rsp, 64); __ movdbl(Address(rsp, 0), xmm0); @@ -271,11 +268,14 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm, __ bind(done); } -void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Address src) { +void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst, Address src, ShenandoahBarrierSet::AccessKind kind) { assert(ShenandoahLoadRefBarrier, "Should be enabled"); - Label done; + Label heap_stable, not_cset; + __ block_comment("load_reference_barrier { "); + + // Check if GC is active #ifdef _LP64 Register thread = r15_thread; #else @@ -289,138 +289,130 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembl Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); __ testb(gc_state, ShenandoahHeap::HAS_FORWARDED); - __ jccb(Assembler::zero, done); - - // Use rsi for src address - const Register src_addr = rsi; - // Setup address parameter first, if it does not clobber oop in dst - bool need_addr_setup = (src_addr != dst); - - if (need_addr_setup) { - __ push(src_addr); - __ lea(src_addr, src); - - if (dst != rax) { - // Move obj into rax and save rax - __ push(rax); - __ movptr(rax, dst); - } - } else { - // dst == rsi - __ push(rax); - __ movptr(rax, dst); - - // we can clobber it, since it is outgoing register - __ lea(src_addr, src); - } - - save_xmm_registers(masm); - __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, ShenandoahBarrierSetAssembler::shenandoah_lrb()))); - restore_xmm_registers(masm); - - if (need_addr_setup) { - if (dst != rax) { - __ movptr(dst, rax); - __ pop(rax); + __ jcc(Assembler::zero, heap_stable); + + Register tmp1 = noreg, tmp2 = noreg; + if (kind == ShenandoahBarrierSet::AccessKind::NORMAL) { + // Test for object in cset + // Allocate temporary registers + for (int i = 0; i < 8; i++) { + Register r = as_Register(i); + if (r != rsp && r != rbp && r != dst && r != src.base() && r != src.index()) { + if (tmp1 == noreg) { + tmp1 = r; + } else { + tmp2 = r; + break; + } + } } - __ pop(src_addr); - } else { - __ movptr(dst, rax); - __ pop(rax); + assert(tmp1 != noreg, "tmp1 allocated"); + assert(tmp2 != noreg, "tmp2 allocated"); + assert_different_registers(tmp1, tmp2, src.base(), src.index()); + assert_different_registers(tmp1, tmp2, dst); + + __ push(tmp1); + __ push(tmp2); + + // Optimized cset-test + __ movptr(tmp1, dst); + __ shrptr(tmp1, ShenandoahHeapRegion::region_size_bytes_shift_jint()); + __ movptr(tmp2, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr()); + __ movbool(tmp1, Address(tmp1, tmp2, Address::times_1)); + __ testbool(tmp1); + __ jcc(Assembler::zero, not_cset); + } + + uint num_saved_regs = 4 + (dst != rax ? 1 : 0) LP64_ONLY(+4); + __ subptr(rsp, num_saved_regs * wordSize); + uint slot = num_saved_regs; + if (dst != rax) { + __ movptr(Address(rsp, (--slot) * wordSize), rax); } - - __ bind(done); - -#ifndef _LP64 - __ pop(thread); + __ movptr(Address(rsp, (--slot) * wordSize), rcx); + __ movptr(Address(rsp, (--slot) * wordSize), rdx); + __ movptr(Address(rsp, (--slot) * wordSize), rdi); + __ movptr(Address(rsp, (--slot) * wordSize), rsi); +#ifdef _LP64 + __ movptr(Address(rsp, (--slot) * wordSize), r8); + __ movptr(Address(rsp, (--slot) * wordSize), r9); + __ movptr(Address(rsp, (--slot) * wordSize), r10); + __ movptr(Address(rsp, (--slot) * wordSize), r11); + // r12-r15 are callee saved in all calling conventions #endif -} - -void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Address src) { - if (!ShenandoahLoadRefBarrier) { - return; - } - - Label done; - Label not_null; - Label slow_path; - __ block_comment("load_reference_barrier_native { "); - - // null check - __ testptr(dst, dst); - __ jcc(Assembler::notZero, not_null); - __ jmp(done); - __ bind(not_null); - + assert(slot == 0, "must use all slots"); + // Shuffle registers such that dst is in c_rarg0 and addr in c_rarg1. #ifdef _LP64 - Register thread = r15_thread; + Register arg0 = c_rarg0, arg1 = c_rarg1; #else - Register thread = rcx; - if (thread == dst) { - thread = rbx; - } - __ push(thread); - __ get_thread(thread); -#endif - assert_different_registers(dst, thread); - - Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); - __ testb(gc_state, ShenandoahHeap::HAS_FORWARDED); -#ifndef _LP64 - __ pop(thread); + Register arg0 = rdi, arg1 = rsi; #endif - __ jccb(Assembler::notZero, slow_path); - __ jmp(done); - __ bind(slow_path); - - if (dst != rax) { - __ push(rax); + if (dst == arg1) { + __ lea(arg0, src); + __ xchgptr(arg1, arg0); + } else { + __ lea(arg1, src); + __ movptr(arg0, dst); } - __ push(rcx); - __ push(rdx); - __ push(rdi); - __ push(rsi); -#ifdef _LP64 - __ push(r8); - __ push(r9); - __ push(r10); - __ push(r11); - __ push(r12); - __ push(r13); - __ push(r14); - __ push(r15); -#endif - - assert_different_registers(dst, rsi); - __ lea(rsi, src); save_xmm_registers(masm); - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), dst, rsi); + switch (kind) { + case ShenandoahBarrierSet::AccessKind::NORMAL: + if (UseCompressedOops) { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow), arg0, arg1); + } else { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), arg0, arg1); + } + break; + case ShenandoahBarrierSet::AccessKind::WEAK: + if (UseCompressedOops) { + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak_narrow), arg0, arg1); + } else { + __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), arg0, arg1); + } + break; + case ShenandoahBarrierSet::AccessKind::NATIVE: + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), arg0, arg1); + break; + default: + ShouldNotReachHere(); + } restore_xmm_registers(masm); #ifdef _LP64 - __ pop(r15); - __ pop(r14); - __ pop(r13); - __ pop(r12); - __ pop(r11); - __ pop(r10); - __ pop(r9); - __ pop(r8); + __ movptr(r11, Address(rsp, (slot++) * wordSize)); + __ movptr(r10, Address(rsp, (slot++) * wordSize)); + __ movptr(r9, Address(rsp, (slot++) * wordSize)); + __ movptr(r8, Address(rsp, (slot++) * wordSize)); #endif - __ pop(rsi); - __ pop(rdi); - __ pop(rdx); - __ pop(rcx); + __ movptr(rsi, Address(rsp, (slot++) * wordSize)); + __ movptr(rdi, Address(rsp, (slot++) * wordSize)); + __ movptr(rdx, Address(rsp, (slot++) * wordSize)); + __ movptr(rcx, Address(rsp, (slot++) * wordSize)); if (dst != rax) { __ movptr(dst, rax); - __ pop(rax); + __ movptr(rax, Address(rsp, (slot++) * wordSize)); } - __ bind(done); - __ block_comment("load_reference_barrier_native { "); + assert(slot == num_saved_regs, "must use all slots"); + __ addptr(rsp, num_saved_regs * wordSize); + + __ bind(not_cset); + + if (kind == ShenandoahBarrierSet::AccessKind::NORMAL) { + __ pop(tmp2); + __ pop(tmp1); + } + + __ bind(heap_stable); + + __ block_comment("} load_reference_barrier"); + +#ifndef _LP64 + __ pop(thread); +#endif } void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) { @@ -464,16 +456,6 @@ void ShenandoahBarrierSetAssembler::storeval_barrier_impl(MacroAssembler* masm, } } -void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst, Address src) { - if (ShenandoahLoadRefBarrier) { - Label done; - __ testptr(dst, dst); - __ jcc(Assembler::zero, done); - load_reference_barrier_not_null(masm, dst, src); - __ bind(done); - } -} - // // Arguments: // @@ -504,7 +486,7 @@ void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet d // Preserve src location for LRB if (dst == src.base() || dst == src.index()) { - // Use tmp1 for dst if possible, as it is not used in BarrierAssembler::load_at() + // Use tmp1 for dst if possible, as it is not used in BarrierAssembler::load_at() if (tmp1->is_valid() && tmp1 != src.base() && tmp1 != src.index()) { dst = tmp1; use_tmp1_for_dst = true; @@ -517,11 +499,8 @@ void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet d BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); - if (ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type)) { - load_reference_barrier_native(masm, dst, src); - } else { - load_reference_barrier(masm, dst, src); - } + ShenandoahBarrierSet::AccessKind kind = ShenandoahBarrierSet::access_kind(decorators, type); + load_reference_barrier(masm, dst, src, kind); // Move loaded oop to final destination if (dst != result_dst) { @@ -638,7 +617,8 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, bool exchange, Register tmp1, Register tmp2) { assert(ShenandoahCASBarrier, "Should only be used when CAS barrier is enabled"); assert(oldval == rax, "must be in rax for implicit use in cmpxchg"); - assert_different_registers(oldval, newval, tmp1, tmp2); + assert_different_registers(oldval, tmp1, tmp2); + assert_different_registers(newval, tmp1, tmp2); Label L_success, L_failure; @@ -870,10 +850,18 @@ void ShenandoahBarrierSetAssembler::gen_load_reference_barrier_stub(LIR_Assemble __ bind(slow_path); ce->store_parameter(res, 0); ce->store_parameter(addr, 1); - if (stub->is_native()) { - __ call(RuntimeAddress(bs->load_reference_barrier_native_rt_code_blob()->code_begin())); - } else { - __ call(RuntimeAddress(bs->load_reference_barrier_rt_code_blob()->code_begin())); + switch (stub->kind()) { + case ShenandoahBarrierSet::AccessKind::NORMAL: + __ call(RuntimeAddress(bs->load_reference_barrier_normal_rt_code_blob()->code_begin())); + break; + case ShenandoahBarrierSet::AccessKind::WEAK: + __ call(RuntimeAddress(bs->load_reference_barrier_weak_rt_code_blob()->code_begin())); + break; + case ShenandoahBarrierSet::AccessKind::NATIVE: + __ call(RuntimeAddress(bs->load_reference_barrier_native_rt_code_blob()->code_begin())); + break; + default: + ShouldNotReachHere(); } __ jmp(*stub->continuation()); } @@ -938,7 +926,7 @@ void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAss __ epilogue(); } -void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_native) { +void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, ShenandoahBarrierSet::AccessKind kind) { __ prologue("shenandoah_load_reference_barrier", false); // arg0 : object to be resolved @@ -947,20 +935,40 @@ void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_s #ifdef _LP64 __ load_parameter(0, c_rarg0); __ load_parameter(1, c_rarg1); - if (is_native) { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), c_rarg0, c_rarg1); - } else if (UseCompressedOops) { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow), c_rarg0, c_rarg1); - } else { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), c_rarg0, c_rarg1); + switch (kind) { + case ShenandoahBarrierSet::AccessKind::NORMAL: + if (UseCompressedOops) { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow), c_rarg0, c_rarg1); + } else { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), c_rarg0, c_rarg1); + } + break; + case ShenandoahBarrierSet::AccessKind::WEAK: + if (UseCompressedOops) { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak_narrow), c_rarg0, c_rarg1); + } else { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), c_rarg0, c_rarg1); + } + break; + case ShenandoahBarrierSet::AccessKind::NATIVE: + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), c_rarg0, c_rarg1); + break; + default: + ShouldNotReachHere(); } #else __ load_parameter(0, rax); __ load_parameter(1, rbx); - if (is_native) { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), rax, rbx); - } else { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), rax, rbx); + switch (kind) { + case ShenandoahBarrierSet::AccessKind::NORMAL: + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), rax, rbx); + break; + case ShenandoahBarrierSet::AccessKind::WEAK: + case ShenandoahBarrierSet::AccessKind::NATIVE: + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), rax, rbx); + break; + default: + ShouldNotReachHere(); } #endif @@ -972,104 +980,3 @@ void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_s #undef __ #endif // COMPILER1 - -address ShenandoahBarrierSetAssembler::shenandoah_lrb() { - assert(_shenandoah_lrb != NULL, "need load reference barrier stub"); - return _shenandoah_lrb; -} - -#define __ cgen->assembler()-> - -/* - * Incoming parameters: - * rax: oop - * rsi: load address - */ -address ShenandoahBarrierSetAssembler::generate_shenandoah_lrb(StubCodeGenerator* cgen) { - __ align(CodeEntryAlignment); - StubCodeMark mark(cgen, "StubRoutines", "shenandoah_lrb"); - address start = __ pc(); - - Label slow_path; - - // We use RDI, which also serves as argument register for slow call. - // RAX always holds the src object ptr, except after the slow call, - // then it holds the result. R8/RBX is used as temporary register. - - Register tmp1 = rdi; - Register tmp2 = LP64_ONLY(r8) NOT_LP64(rbx); - - __ push(tmp1); - __ push(tmp2); - - // Check for object being in the collection set. - __ mov(tmp1, rax); - __ shrptr(tmp1, ShenandoahHeapRegion::region_size_bytes_shift_jint()); - __ movptr(tmp2, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr()); - __ movbool(tmp2, Address(tmp2, tmp1, Address::times_1)); - __ testbool(tmp2); - __ jccb(Assembler::notZero, slow_path); - __ pop(tmp2); - __ pop(tmp1); - __ ret(0); - - __ bind(slow_path); - - __ push(rcx); - __ push(rdx); - __ push(rdi); -#ifdef _LP64 - __ push(r8); - __ push(r9); - __ push(r10); - __ push(r11); - __ push(r12); - __ push(r13); - __ push(r14); - __ push(r15); -#endif - __ push(rbp); - __ movptr(rbp, rsp); - __ andptr(rsp, -StackAlignmentInBytes); - __ push_FPU_state(); - if (UseCompressedOops) { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow), rax, rsi); - } else { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), rax, rsi); - } - __ pop_FPU_state(); - __ movptr(rsp, rbp); - __ pop(rbp); -#ifdef _LP64 - __ pop(r15); - __ pop(r14); - __ pop(r13); - __ pop(r12); - __ pop(r11); - __ pop(r10); - __ pop(r9); - __ pop(r8); -#endif - __ pop(rdi); - __ pop(rdx); - __ pop(rcx); - - __ pop(tmp2); - __ pop(tmp1); - __ ret(0); - - return start; -} - -#undef __ - -void ShenandoahBarrierSetAssembler::barrier_stubs_init() { - if (ShenandoahLoadRefBarrier) { - int stub_code_size = 4096; - ResourceMark rm; - BufferBlob* bb = BufferBlob::create("shenandoah_barrier_stubs", stub_code_size); - CodeBuffer buf(bb); - StubCodeGenerator cgen(&buf); - _shenandoah_lrb = generate_shenandoah_lrb(&cgen); - } -} diff --git a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp index af533c75e66..c29dff56f3b 100644 --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp @@ -27,6 +27,8 @@ #include "asm/macroAssembler.hpp" #include "gc/shared/barrierSetAssembler.hpp" +#include "gc/shenandoah/shenandoahBarrierSet.hpp" + #ifdef COMPILER1 class LIR_Assembler; class ShenandoahPreBarrierStub; @@ -38,8 +40,6 @@ class StubCodeGenerator; class ShenandoahBarrierSetAssembler: public BarrierSetAssembler { private: - static address _shenandoah_lrb; - void satb_write_barrier_pre(MacroAssembler* masm, Register obj, Register pre_val, @@ -56,25 +56,18 @@ class ShenandoahBarrierSetAssembler: public BarrierSetAssembler { bool tosca_live, bool expand_call); - void load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Address src); - void storeval_barrier_impl(MacroAssembler* masm, Register dst, Register tmp); - address generate_shenandoah_lrb(StubCodeGenerator* cgen); - public: - static address shenandoah_lrb(); - void storeval_barrier(MacroAssembler* masm, Register dst, Register tmp); #ifdef COMPILER1 void gen_pre_barrier_stub(LIR_Assembler* ce, ShenandoahPreBarrierStub* stub); void gen_load_reference_barrier_stub(LIR_Assembler* ce, ShenandoahLoadReferenceBarrierStub* stub); void generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm); - void generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, bool is_native); + void generate_c1_load_reference_barrier_runtime_stub(StubAssembler* sasm, ShenandoahBarrierSet::AccessKind kind); #endif - void load_reference_barrier(MacroAssembler* masm, Register dst, Address src); - void load_reference_barrier_native(MacroAssembler* masm, Register dst, Address src); + void load_reference_barrier(MacroAssembler* masm, Register dst, Address src, ShenandoahBarrierSet::AccessKind kind); void cmpxchg_oop(MacroAssembler* masm, Register res, Address addr, Register oldval, Register newval, @@ -87,8 +80,6 @@ class ShenandoahBarrierSetAssembler: public BarrierSetAssembler { Address dst, Register val, Register tmp1, Register tmp2, Register tmp3 = noreg); virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env, Register obj, Register tmp, Label& slowpath); - virtual void barrier_stubs_init(); - }; #endif // CPU_X86_GC_SHENANDOAH_SHENANDOAHBARRIERSETASSEMBLER_X86_HPP diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp index 63d7b5ce97c..ae641b7323c 100644 --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp @@ -1011,9 +1011,9 @@ void InterpreterMacroAssembler::remove_activation( push(state); set_last_Java_frame(rthread, noreg, rbp, (address)pc()); super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::at_unwind), rthread); + NOT_LP64(get_thread(rthread);) // call_VM clobbered it, restore reset_last_Java_frame(rthread, true); pop(state); - NOT_LP64(get_thread(rthread);) // call_VM clobbered it, restore bind(fast_path); // get the value of _do_not_unlock_if_synchronized into rdx @@ -2186,7 +2186,7 @@ void InterpreterMacroAssembler::profile_acmp(Register mdp, void InterpreterMacroAssembler::_interp_verify_oop(Register reg, TosState state, const char* file, int line) { if (state == atos) { - MacroAssembler::_verify_oop(reg, "broken oop", file, line); + MacroAssembler::_verify_oop_checked(reg, "broken oop", file, line); } } diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index 87df2d98482..474416c977f 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -376,11 +376,6 @@ void MacroAssembler::pushptr(AddressLiteral src) { } } -void MacroAssembler::set_word_if_not_zero(Register dst) { - xorl(dst, dst); - set_byte_if_not_zero(dst); -} - static void pass_arg0(MacroAssembler* masm, Register arg) { masm->push(arg); } @@ -720,8 +715,12 @@ void MacroAssembler::movptr(Register dst, ArrayAddress src) { // src should NEVER be a real pointer. Use AddressLiteral for true pointers void MacroAssembler::movptr(Address dst, intptr_t src) { - mov64(rscratch1, src); - movq(dst, rscratch1); + if (is_simm32(src)) { + movptr(dst, checked_cast(src)); + } else { + mov64(rscratch1, src); + movq(dst, rscratch1); + } } // These are mostly for initializing NULL @@ -2911,15 +2910,13 @@ void MacroAssembler::save_rax(Register tmp) { } void MacroAssembler::safepoint_poll(Label& slow_path, Register thread_reg, bool at_return, bool in_nmethod) { -#ifdef _LP64 if (at_return) { // Note that when in_nmethod is set, the stack pointer is incremented before the poll. Therefore, // we may safely use rsp instead to perform the stack watermark check. - cmpq(Address(thread_reg, Thread::polling_word_offset()), in_nmethod ? rsp : rbp); + cmpptr(in_nmethod ? rsp : rbp, Address(thread_reg, Thread::polling_word_offset())); jcc(Assembler::above, slow_path); return; } -#endif testb(Address(thread_reg, Thread::polling_word_offset()), SafepointMechanism::poll_bit()); jcc(Assembler::notZero, slow_path); // handshake bit set implies poll } @@ -4324,7 +4321,6 @@ Address MacroAssembler::argument_address(RegisterOrConstant arg_slot, return Address(rsp, scale_reg, scale_factor, offset); } - void MacroAssembler::_verify_oop_addr(Address addr, const char* s, const char* file, int line) { if (!VerifyOops || VerifyAdapterSharing) { // Below address of the code string confuses VerifyAdapterSharing diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp index 28586637d11..23e8de560a2 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp @@ -640,22 +640,30 @@ class MacroAssembler: public Assembler { // method handles (JSR 292) Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0); - //---- - void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0 - // Debugging // only if +VerifyOops void _verify_oop(Register reg, const char* s, const char* file, int line); void _verify_oop_addr(Address addr, const char* s, const char* file, int line); + void _verify_oop_checked(Register reg, const char* s, const char* file, int line) { + if (VerifyOops) { + _verify_oop(reg, s, file, line); + } + } + void _verify_oop_addr_checked(Address reg, const char* s, const char* file, int line) { + if (VerifyOops) { + _verify_oop_addr(reg, s, file, line); + } + } + // TODO: verify method and klass metadata (compare against vptr?) void _verify_method_ptr(Register reg, const char * msg, const char * file, int line) {} void _verify_klass_ptr(Register reg, const char * msg, const char * file, int line){} -#define verify_oop(reg) _verify_oop(reg, "broken oop " #reg, __FILE__, __LINE__) -#define verify_oop_msg(reg, msg) _verify_oop(reg, "broken oop " #reg ", " #msg, __FILE__, __LINE__) -#define verify_oop_addr(addr) _verify_oop_addr(addr, "broken oop addr " #addr, __FILE__, __LINE__) +#define verify_oop(reg) _verify_oop_checked(reg, "broken oop " #reg, __FILE__, __LINE__) +#define verify_oop_msg(reg, msg) _verify_oop_checked(reg, "broken oop " #reg ", " #msg, __FILE__, __LINE__) +#define verify_oop_addr(addr) _verify_oop_addr_checked(addr, "broken oop addr " #addr, __FILE__, __LINE__) #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__) diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp index 57c3e06a205..5d05a873dbe 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp @@ -7033,7 +7033,9 @@ address generate_avx_ghash_processBlocks() { StubRoutines::x86::_vector_iota_indices = generate_iota_indices("iota_indices"); // support for verify_oop (must happen after universe_init) - StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); + if (VerifyOops) { + StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop(); + } // data cache line writeback StubRoutines::_data_cache_writeback = generate_data_cache_writeback(); diff --git a/src/hotspot/cpu/x86/vm_version_x86.hpp b/src/hotspot/cpu/x86/vm_version_x86.hpp index 963e5bae26c..5d91280e616 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.hpp +++ b/src/hotspot/cpu/x86/vm_version_x86.hpp @@ -1023,7 +1023,7 @@ enum Extended_Family { } constexpr static bool supports_stack_watermark_barrier() { - return LP64_ONLY(true) NOT_LP64(false); + return true; } // there are several insns to force cache line sync to memory which diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 47f567f0758..c6c8c172b0a 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -4446,9 +4446,8 @@ instruct reductionI(rRegI dst, rRegI src1, legVec src2, legVec vtmp1, legVec vtm // =======================Long Reduction========================================== #ifdef _LP64 -instruct reductionL(rRegL dst, rRegL src1, vec src2, vec vtmp1, vec vtmp2) %{ - predicate(vector_element_basic_type(n->in(2)) == T_LONG && - vector_length(n->in(2)) < 8); // src2 +instruct reductionL(rRegL dst, rRegL src1, legVec src2, legVec vtmp1, legVec vtmp2) %{ + predicate(vector_element_basic_type(n->in(2)) == T_LONG && !VM_Version::supports_avx512dq()); match(Set dst (AddReductionVL src1 src2)); match(Set dst (MulReductionVL src1 src2)); match(Set dst (AndReductionV src1 src2)); @@ -4466,9 +4465,8 @@ instruct reductionL(rRegL dst, rRegL src1, vec src2, vec vtmp1, vec vtmp2) %{ ins_pipe( pipe_slow ); %} -instruct reduction8L(rRegL dst, rRegL src1, legVec src2, legVec vtmp1, legVec vtmp2) %{ - predicate(vector_element_basic_type(n->in(2)) == T_LONG && - vector_length(n->in(2)) == 8); // src2 +instruct reductionL_avx512dq(rRegL dst, rRegL src1, vec src2, vec vtmp1, vec vtmp2) %{ + predicate(vector_element_basic_type(n->in(2)) == T_LONG && VM_Version::supports_avx512dq()); match(Set dst (AddReductionVL src1 src2)); match(Set dst (MulReductionVL src1 src2)); match(Set dst (AndReductionV src1 src2)); @@ -4578,9 +4576,8 @@ instruct reduction8D(regD dst, legVec src, legVec vtmp1, legVec vtmp2) %{ // =======================Byte Reduction========================================== #ifdef _LP64 -instruct reductionB(rRegI dst, rRegI src1, vec src2, vec vtmp1, vec vtmp2) %{ - predicate(vector_element_basic_type(n->in(2)) == T_BYTE && - vector_length(n->in(2)) <= 32); // src2 +instruct reductionB(rRegI dst, rRegI src1, legVec src2, legVec vtmp1, legVec vtmp2) %{ + predicate(vector_element_basic_type(n->in(2)) == T_BYTE && !VM_Version::supports_avx512bw()); match(Set dst (AddReductionVI src1 src2)); match(Set dst (AndReductionV src1 src2)); match(Set dst ( OrReductionV src1 src2)); @@ -4597,9 +4594,8 @@ instruct reductionB(rRegI dst, rRegI src1, vec src2, vec vtmp1, vec vtmp2) %{ ins_pipe( pipe_slow ); %} -instruct reduction64B(rRegI dst, rRegI src1, legVec src2, legVec vtmp1, legVec vtmp2) %{ - predicate(vector_element_basic_type(n->in(2)) == T_BYTE && - vector_length(n->in(2)) == 64); // src2 +instruct reductionB_avx512bw(rRegI dst, rRegI src1, vec src2, vec vtmp1, vec vtmp2) %{ + predicate(vector_element_basic_type(n->in(2)) == T_BYTE && VM_Version::supports_avx512bw()); match(Set dst (AddReductionVI src1 src2)); match(Set dst (AndReductionV src1 src2)); match(Set dst ( OrReductionV src1 src2)); @@ -5450,7 +5446,7 @@ instruct vmulL_mem(vec dst, vec src, memory mem) %{ ins_pipe( pipe_slow ); %} -instruct mul2L_reg(vec dst, vec src2, vec tmp) %{ +instruct mul2L_reg(vec dst, vec src2, legVec tmp) %{ predicate(vector_length(n) == 2 && !VM_Version::supports_avx512dq()); match(Set dst (MulVL dst src2)); effect(TEMP dst, TEMP tmp); @@ -5476,7 +5472,7 @@ instruct mul2L_reg(vec dst, vec src2, vec tmp) %{ ins_pipe( pipe_slow ); %} -instruct vmul4L_reg_avx(vec dst, vec src1, vec src2, vec tmp, vec tmp1) %{ +instruct vmul4L_reg_avx(vec dst, vec src1, vec src2, legVec tmp, legVec tmp1) %{ predicate(vector_length(n) == 4 && !VM_Version::supports_avx512dq()); match(Set dst (MulVL src1 src2)); effect(TEMP tmp1, TEMP tmp); @@ -6961,6 +6957,7 @@ instruct extractI(rRegI dst, legVec src, immU8 idx) %{ #ifdef _LP64 match(Set dst (ExtractB src idx)); #endif + format %{ "extractI $dst,$src,$idx\t!" %} ins_encode %{ assert($idx$$constant < (int)vector_length(this, $src), "out of bounds"); @@ -6979,6 +6976,7 @@ instruct vextractI(rRegI dst, legVec src, immI idx, legVec vtmp) %{ match(Set dst (ExtractB src idx)); #endif effect(TEMP vtmp); + format %{ "vextractI $dst,$src,$idx\t! using $vtmp as TEMP" %} ins_encode %{ assert($idx$$constant < (int)vector_length(this, $src), "out of bounds"); @@ -6993,6 +6991,7 @@ instruct vextractI(rRegI dst, legVec src, immI idx, legVec vtmp) %{ instruct extractL(rRegL dst, legVec src, immU8 idx) %{ predicate(vector_length(n->in(1)) <= 2); // src match(Set dst (ExtractL src idx)); + format %{ "extractL $dst,$src,$idx\t!" %} ins_encode %{ assert(UseSSE >= 4, "required"); assert($idx$$constant < (int)vector_length(this, $src), "out of bounds"); @@ -7007,6 +7006,7 @@ instruct vextractL(rRegL dst, legVec src, immU8 idx, legVec vtmp) %{ vector_length(n->in(1)) == 8); // src match(Set dst (ExtractL src idx)); effect(TEMP vtmp); + format %{ "vextractL $dst,$src,$idx\t! using $vtmp as TEMP" %} ins_encode %{ assert($idx$$constant < (int)vector_length(this, $src), "out of bounds"); @@ -7021,6 +7021,7 @@ instruct extractF(legRegF dst, legVec src, immU8 idx, rRegI tmp, legVec vtmp) %{ predicate(vector_length(n->in(1)) <= 4); match(Set dst (ExtractF src idx)); effect(TEMP dst, TEMP tmp, TEMP vtmp); + format %{ "extractF $dst,$src,$idx\t! using $tmp, $vtmp as TEMP" %} ins_encode %{ assert($idx$$constant < (int)vector_length(this, $src), "out of bounds"); @@ -7034,6 +7035,7 @@ instruct vextractF(legRegF dst, legVec src, immU8 idx, rRegI tmp, legVec vtmp) % vector_length(n->in(1)/*src*/) == 16); match(Set dst (ExtractF src idx)); effect(TEMP tmp, TEMP vtmp); + format %{ "vextractF $dst,$src,$idx\t! using $tmp, $vtmp as TEMP" %} ins_encode %{ assert($idx$$constant < (int)vector_length(this, $src), "out of bounds"); @@ -7046,6 +7048,7 @@ instruct vextractF(legRegF dst, legVec src, immU8 idx, rRegI tmp, legVec vtmp) % instruct extractD(legRegD dst, legVec src, immU8 idx) %{ predicate(vector_length(n->in(1)) == 2); // src match(Set dst (ExtractD src idx)); + format %{ "extractD $dst,$src,$idx\t!" %} ins_encode %{ assert($idx$$constant < (int)vector_length(this, $src), "out of bounds"); @@ -7059,6 +7062,7 @@ instruct vextractD(legRegD dst, legVec src, immU8 idx, legVec vtmp) %{ vector_length(n->in(1)) == 8); // src match(Set dst (ExtractD src idx)); effect(TEMP vtmp); + format %{ "vextractD $dst,$src,$idx\t! using $vtmp as TEMP" %} ins_encode %{ assert($idx$$constant < (int)vector_length(this, $src), "out of bounds"); diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index 45b3c3a4228..39cf78fede8 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -650,8 +650,9 @@ void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { } st->print_cr("POPL EBP"); st->print("\t"); if (do_polling() && C->is_method_compilation()) { - st->print("TEST PollPage,EAX\t! Poll Safepoint"); - st->cr(); st->print("\t"); + st->print("CMPL rsp, poll_offset[thread] \n\t" + "JA #safepoint_stub\t" + "# Safepoint: poll for GC"); } } #endif @@ -694,12 +695,16 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { } if (do_polling() && C->is_method_compilation()) { - Register pollReg = as_Register(EBX_enc); + Register thread = as_Register(EBX_enc); MacroAssembler masm(&cbuf); - masm.get_thread(pollReg); - masm.movl(pollReg, Address(pollReg, in_bytes(Thread::polling_page_offset()))); - masm.relocate(relocInfo::poll_return_type); - masm.testl(rax, Address(pollReg, 0)); + __ get_thread(thread); + Label dummy_label; + Label* code_stub = &dummy_label; + if (!C->output()->in_scratch_emit_size()) { + code_stub = &C->output()->safepoint_poll_table()->add_safepoint(__ offset()); + } + __ relocate(relocInfo::poll_return_type); + __ safepoint_poll(*code_stub, thread, true /* at_return */, true /* in_nmethod */); } } diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index b2417ae59a0..a97ee8f6de7 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -927,8 +927,8 @@ void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const st->print_cr("popq rbp"); if (do_polling() && C->is_method_compilation()) { st->print("\t"); - st->print_cr("cmpq poll_offset[r15_thread], rsp\n\t" - "ja #safepoint_stub\t" + st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" + "ja #safepoint_stub\t" "# Safepoint: poll for GC"); } } diff --git a/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp b/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp index d20fe3e4f7f..f165de3a086 100644 --- a/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp +++ b/src/hotspot/cpu/zero/bytecodeInterpreter_zero.cpp @@ -47,7 +47,6 @@ const char *BytecodeInterpreter::name_of_field_at_address(address addr) { DO(_constants); DO(_method); DO(_mirror); - DO(_mdx); DO(_stack); DO(_msg); DO(_result); @@ -84,7 +83,6 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState istate, istate->set_msg(BytecodeInterpreter::method_resume); istate->set_bcp_advance(0); istate->set_oop_temp(NULL); - istate->set_mdx(NULL); if (caller->is_interpreted_frame()) { interpreterState prev = caller->get_interpreterState(); prev->set_callee(method); diff --git a/src/hotspot/cpu/zero/frame_zero.inline.hpp b/src/hotspot/cpu/zero/frame_zero.inline.hpp index 11472461d64..396e189a5db 100644 --- a/src/hotspot/cpu/zero/frame_zero.inline.hpp +++ b/src/hotspot/cpu/zero/frame_zero.inline.hpp @@ -107,7 +107,8 @@ inline oop* frame::interpreter_frame_mirror_addr() const { } inline intptr_t* frame::interpreter_frame_mdp_addr() const { - return (intptr_t*) &(get_interpreterState()->_mdx); + fatal("Should not call this: Zero never profiles"); + return NULL; // silence compiler warnings } inline intptr_t* frame::interpreter_frame_tos_address() const { diff --git a/src/hotspot/cpu/zero/stack_zero.inline.hpp b/src/hotspot/cpu/zero/stack_zero.inline.hpp index 0c85af5dfde..f363de57180 100644 --- a/src/hotspot/cpu/zero/stack_zero.inline.hpp +++ b/src/hotspot/cpu/zero/stack_zero.inline.hpp @@ -47,7 +47,7 @@ inline void ZeroStack::overflow_check(int required_words, TRAPS) { // to use under normal circumstances. Note that the returned // value can be negative. inline int ZeroStack::abi_stack_available(Thread *thread) const { - guarantee(Thread::current() == thread, "should run in the same thread"); + assert(Thread::current() == thread, "should run in the same thread"); int stack_used = thread->stack_base() - (address) &stack_used + (StackOverflow::stack_guard_zone_size() + StackOverflow::stack_shadow_zone_size()); int stack_free = thread->stack_size() - stack_used; diff --git a/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp b/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp index 21a90d07522..909f6caa266 100644 --- a/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp +++ b/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp @@ -749,7 +749,6 @@ InterpreterFrame *InterpreterFrame::build(Method* const method, TRAPS) { istate->set_constants(method->constants()->cache()); istate->set_msg(BytecodeInterpreter::method_entry); istate->set_oop_temp(NULL); - istate->set_mdx(NULL); istate->set_callee(NULL); istate->set_monitor_base((BasicObjectLock *) stack->sp()); diff --git a/src/hotspot/os/linux/globals_linux.hpp b/src/hotspot/os/linux/globals_linux.hpp index 0e5c209c940..047901c6efa 100644 --- a/src/hotspot/os/linux/globals_linux.hpp +++ b/src/hotspot/os/linux/globals_linux.hpp @@ -79,7 +79,10 @@ "be dumped into the corefile.") \ \ product(bool, UseCpuAllocPath, false, DIAGNOSTIC, \ - "Use CPU_ALLOC code path in os::active_processor_count ") + "Use CPU_ALLOC code path in os::active_processor_count ") \ + \ + product(bool, DumpPerfMapAtExit, false, DIAGNOSTIC, \ + "Write map file for Linux perf tool at exit") // end of RUNTIME_OS_FLAGS diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index c9d07dfb0fe..e7e332c16b5 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -4635,6 +4635,12 @@ jint os::init_2(void) { set_coredump_filter(FILE_BACKED_SHARED_BIT); } + if (DumpPerfMapAtExit && FLAG_IS_DEFAULT(UseCodeCacheFlushing)) { + // Disable code cache flushing to ensure the map file written at + // exit contains all nmethods generated during execution. + FLAG_SET_DEFAULT(UseCodeCacheFlushing, false); + } + return JNI_OK; } diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp index 4eea0664566..6b248a96981 100644 --- a/src/hotspot/os/posix/signals_posix.cpp +++ b/src/hotspot/os/posix/signals_posix.cpp @@ -451,46 +451,62 @@ extern "C" JNIEXPORT int JVM_handle_linux_signal(int signo, siginfo_t* siginfo, int abort_if_unrecognized); #endif -#if defined(AIX) -// Set thread signal mask (for some reason on AIX sigthreadmask() seems -// to be the thing to call; documentation is not terribly clear about whether -// pthread_sigmask also works, and if it does, whether it does the same. -bool set_thread_signal_mask(int how, const sigset_t* set, sigset_t* oset) { - const int rc = ::pthread_sigmask(how, set, oset); - // return value semantics differ slightly for error case: - // pthread_sigmask returns error number, sigthreadmask -1 and sets global errno - // (so, pthread_sigmask is more theadsafe for error handling) - // But success is always 0. - return rc == 0 ? true : false; +///// Synchronous (non-deferrable) error signals (ILL, SEGV, FPE, BUS, TRAP): + +// These signals are special because they cannot be deferred and, if they +// happen while delivery is blocked for the receiving thread, will cause UB +// (in practice typically resulting in sudden process deaths or hangs, see +// JDK-8252533). So we must take care never to block them when we cannot be +// absolutely sure they won't happen. In practice, this is always. +// +// Relevant Posix quote: +// "The behavior of a process is undefined after it ignores a SIGFPE, SIGILL, +// SIGSEGV, or SIGBUS signal that was not generated by kill(), sigqueue(), or +// raise()." +// +// We also include SIGTRAP in that list of never-to-block-signals. While not +// mentioned by the Posix documentation, in our (SAPs) experience blocking it +// causes similar problems. Beside, during normal operation - outside of error +// handling - SIGTRAP may be used for implicit NULL checking, so it makes sense +// to never block it. +// +// We deal with those signals in two ways: +// - we just never explicitly block them, which includes not accidentally blocking +// them via sa_mask when establishing signal handlers. +// - as an additional safety measure, at the entrance of a signal handler, we +// unblock them explicitly. + +static void add_error_signals_to_set(sigset_t* set) { + sigaddset(set, SIGILL); + sigaddset(set, SIGBUS); + sigaddset(set, SIGFPE); + sigaddset(set, SIGSEGV); + sigaddset(set, SIGTRAP); +} + +static void remove_error_signals_from_set(sigset_t* set) { + sigdelset(set, SIGILL); + sigdelset(set, SIGBUS); + sigdelset(set, SIGFPE); + sigdelset(set, SIGSEGV); + sigdelset(set, SIGTRAP); } -// Function to unblock all signals which are, according -// to POSIX, typical program error signals. If they happen while being blocked, -// they typically will bring down the process immediately. -bool unblock_program_error_signals() { +// Unblock all signals whose delivery cannot be deferred and which, if they happen +// while delivery is blocked, would cause crashes or hangs (JDK-8252533). +void PosixSignals::unblock_error_signals() { sigset_t set; sigemptyset(&set); - sigaddset(&set, SIGILL); - sigaddset(&set, SIGBUS); - sigaddset(&set, SIGFPE); - sigaddset(&set, SIGSEGV); - return set_thread_signal_mask(SIG_UNBLOCK, &set, NULL); + add_error_signals_to_set(&set); + ::pthread_sigmask(SIG_UNBLOCK, &set, NULL); } -#endif - // Renamed from 'signalHandler' to avoid collision with other shared libs. static void javaSignalHandler(int sig, siginfo_t* info, void* uc) { assert(info != NULL && uc != NULL, "it must be old kernel"); -// TODO: reconcile the differences between Linux/BSD vs AIX here! -#if defined(AIX) - // Never leave program error signals blocked; - // on all our platforms they would bring down the process immediately when - // getting raised while being blocked. - unblock_program_error_signals(); -#endif + PosixSignals::unblock_error_signals(); int orig_errno = errno; // Preserve errno value over signal handler. #if defined(BSD) @@ -504,6 +520,9 @@ static void javaSignalHandler(int sig, siginfo_t* info, void* uc) { } static void UserHandler(int sig, void *siginfo, void *context) { + + PosixSignals::unblock_error_signals(); + // Ctrl-C is pressed during error reporting, likely because the error // handler fails to abort. Let VM die immediately. if (sig == SIGINT && VMError::is_error_reported()) { @@ -702,23 +721,7 @@ void* os::signal(int signal_number, void* handler) { struct sigaction sigAct, oldSigAct; sigfillset(&(sigAct.sa_mask)); - -#if defined(AIX) - // Do not block out synchronous signals in the signal handler. - // Blocking synchronous signals only makes sense if you can really - // be sure that those signals won't happen during signal handling, - // when the blocking applies. Normal signal handlers are lean and - // do not cause signals. But our signal handlers tend to be "risky" - // - secondary SIGSEGV, SIGILL, SIGBUS' may and do happen. - // On AIX, PASE there was a case where a SIGSEGV happened, followed - // by a SIGILL, which was blocked due to the signal mask. The process - // just hung forever. Better to crash from a secondary signal than to hang. - sigdelset(&(sigAct.sa_mask), SIGSEGV); - sigdelset(&(sigAct.sa_mask), SIGBUS); - sigdelset(&(sigAct.sa_mask), SIGILL); - sigdelset(&(sigAct.sa_mask), SIGFPE); - sigdelset(&(sigAct.sa_mask), SIGTRAP); -#endif + remove_error_signals_from_set(&(sigAct.sa_mask)); sigAct.sa_flags = SA_RESTART|SA_SIGINFO; sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler); @@ -1099,6 +1102,7 @@ void set_signal_handler(int sig, bool set_installed) { struct sigaction sigAct; sigfillset(&(sigAct.sa_mask)); + remove_error_signals_from_set(&(sigAct.sa_mask)); sigAct.sa_handler = SIG_DFL; if (!set_installed) { sigAct.sa_flags = SA_SIGINFO|SA_RESTART; @@ -1303,10 +1307,6 @@ bool PosixSignals::is_sig_ignored(int sig) { } } -int PosixSignals::unblock_thread_signal_mask(const sigset_t *set) { - return pthread_sigmask(SIG_UNBLOCK, set, NULL); -} - address PosixSignals::ucontext_get_pc(const ucontext_t* ctx) { #if defined(AIX) return os::Aix::ucontext_get_pc(ctx); @@ -1470,10 +1470,13 @@ static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontex // Currently only ever called on the VMThread and JavaThreads (PC sampling) // static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { + // Save and restore errno to avoid confusing native code with EINTR // after sigsuspend. int old_errno = errno; + PosixSignals::unblock_error_signals(); + Thread* thread = Thread::current_or_null_safe(); assert(thread != NULL, "Missing current thread in SR_handler"); @@ -1567,6 +1570,7 @@ int PosixSignals::SR_initialize() { // SR_signum is blocked by default. pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask); + remove_error_signals_from_set(&(act.sa_mask)); if (sigaction(SR_signum, &act, 0) == -1) { return -1; diff --git a/src/hotspot/os/posix/signals_posix.hpp b/src/hotspot/os/posix/signals_posix.hpp index a2f7d955e14..7194bd6c573 100644 --- a/src/hotspot/os/posix/signals_posix.hpp +++ b/src/hotspot/os/posix/signals_posix.hpp @@ -44,8 +44,6 @@ class PosixSignals : public AllStatic { static bool is_sig_ignored(int sig); static void signal_sets_init(); - // unblocks the signal masks for current thread - static int unblock_thread_signal_mask(const sigset_t *set); static void hotspot_sigmask(Thread* thread); static void print_signal_handler(outputStream* st, int sig, char* buf, size_t buflen); @@ -64,6 +62,11 @@ class PosixSignals : public AllStatic { // sun.misc.Signal support static void jdk_misc_signal_init(); + + // Unblock all signals whose delivery cannot be deferred and which, if they happen + // while delivery is blocked, would cause crashes or hangs (see JDK-8252533). + static void unblock_error_signals(); + }; #endif // OS_POSIX_SIGNALS_POSIX_HPP diff --git a/src/hotspot/os/posix/vmError_posix.cpp b/src/hotspot/os/posix/vmError_posix.cpp index 9c83d263e71..bde46e28741 100644 --- a/src/hotspot/os/posix/vmError_posix.cpp +++ b/src/hotspot/os/posix/vmError_posix.cpp @@ -101,15 +101,8 @@ address VMError::get_resetted_sighandler(int sig) { } static void crash_handler(int sig, siginfo_t* info, void* ucVoid) { - // unmask current signal - sigset_t newset; - sigemptyset(&newset); - sigaddset(&newset, sig); - // also unmask other synchronous signals - for (int i = 0; i < NUM_SIGNALS; i++) { - sigaddset(&newset, SIGNALS[i]); - } - PosixSignals::unblock_thread_signal_mask(&newset); + + PosixSignals::unblock_error_signals(); // support safefetch faults in error handling ucontext_t* const uc = (ucontext_t*) ucVoid; @@ -139,16 +132,10 @@ static void crash_handler(int sig, siginfo_t* info, void* ucVoid) { } void VMError::reset_signal_handlers() { - // install signal handlers for all synchronous program error signals - sigset_t newset; - sigemptyset(&newset); - for (int i = 0; i < NUM_SIGNALS; i++) { save_signal(i, SIGNALS[i]); os::signal(SIGNALS[i], CAST_FROM_FN_PTR(void *, crash_handler)); - sigaddset(&newset, SIGNALS[i]); } - PosixSignals::unblock_thread_signal_mask(&newset); } // Write a hint to the stream in case siginfo relates to a segv/bus error diff --git a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp index 868fe4c529f..ca1c74aeee2 100644 --- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp +++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp @@ -184,7 +184,7 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec // avoid unnecessary crash when libjsig is not preloaded, try handle signals // that do not require siginfo/ucontext first. - if (sig == SIGPIPE) { + if (sig == SIGPIPE || sig == SIGXFSZ) { if (PosixSignals::chained_handler(sig, info, ucVoid)) { return 1; } else { diff --git a/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp index 162951c4317..199a096d7f9 100644 --- a/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/vm_version_linux_aarch64.cpp @@ -142,7 +142,6 @@ void VM_Version::get_os_cpu_info() { _zva_length = 4 << (dczid_el0 & 0xf); } - int cpu_lines = 0; if (FILE *f = fopen("/proc/cpuinfo", "r")) { // need a large buffer as the flags line may include lots of text char buf[1024], *p; @@ -151,7 +150,6 @@ void VM_Version::get_os_cpu_info() { long v = strtol(p+1, NULL, 0); if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) { _cpu = v; - cpu_lines++; } else if (strncmp(buf, "CPU variant", sizeof "CPU variant" - 1) == 0) { _variant = v; } else if (strncmp(buf, "CPU part", sizeof "CPU part" - 1) == 0) { @@ -168,5 +166,4 @@ void VM_Version::get_os_cpu_info() { } fclose(f); } - guarantee(cpu_lines == os::processor_count(), "core count should be consistent"); } diff --git a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp index 49e901a2a00..288e2a3ece6 100644 --- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp +++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp @@ -206,7 +206,7 @@ JVM_handle_linux_signal(int sig, // avoid unnecessary crash when libjsig is not preloaded, try handle signals // that do not require siginfo/ucontext first. - if (sig == SIGPIPE) { + if (sig == SIGPIPE || sig == SIGXFSZ) { if (PosixSignals::chained_handler(sig, info, ucVoid)) { return true; } else { diff --git a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp index d5181b48339..64d5fd8d512 100644 --- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp +++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp @@ -227,7 +227,7 @@ JVM_handle_linux_signal(int sig, // avoid unnecessary crash when libjsig is not preloaded, try handle signals // that do not require siginfo/ucontext first. - if (sig == SIGPIPE) { + if (sig == SIGPIPE || sig == SIGXFSZ) { if (PosixSignals::chained_handler(sig, info, ucVoid)) { return true; } else { diff --git a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp index bbacc5f0029..8f2c8b8bc16 100644 --- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp +++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp @@ -240,9 +240,16 @@ JVM_handle_linux_signal(int sig, } #endif // !PRODUCT - char buf[64]; - - sprintf(buf, "caught unhandled signal %d", sig); + char buf[128]; + char exc_buf[32]; + + if (os::exception_name(sig, exc_buf, sizeof(exc_buf))) { + bool sent_by_kill = (info != NULL && os::signal_sent_by_kill(info)); + snprintf(buf, sizeof(buf), "caught unhandled signal: %s %s", + exc_buf, sent_by_kill ? "(sent by kill)" : ""); + } else { + snprintf(buf, sizeof(buf), "caught unhandled signal: %d", sig); + } // Silence -Wformat-security warning for fatal() PRAGMA_DIAG_PUSH diff --git a/src/hotspot/share/adlc/output_c.cpp b/src/hotspot/share/adlc/output_c.cpp index 82a3a11bc46..f4e6e295603 100644 --- a/src/hotspot/share/adlc/output_c.cpp +++ b/src/hotspot/share/adlc/output_c.cpp @@ -1150,10 +1150,9 @@ static void check_peepconstraints(FILE *fp, FormDict &globals, PeepMatch *pmatch // // Check for equivalence // - // fprintf(fp, "phase->eqv( "); - // fprintf(fp, "inst%d->in(%d+%d) /* %s */, inst%d->in(%d+%d) /* %s */", - // left_index, left_op_base, left_op_index, left_op, - // right_index, right_op_base, right_op_index, right_op ); + // fprintf(fp, "(inst%d->_opnds[%d]->reg(ra_,inst%d%s) /* %d.%s */ == /* %d.%s */ inst%d->_opnds[%d]->reg(ra_,inst%d%s)", + // left_index, left_op_index, left_index, left_reg_index, left_index, left_op + // right_index, right_op, right_index, right_op_index, right_index, right_reg_index); // fprintf(fp, ")"); // switch( left_interface_type ) { diff --git a/src/hotspot/share/ci/ciMethodData.cpp b/src/hotspot/share/ci/ciMethodData.cpp index 6e6abb9457f..b2200fcee71 100644 --- a/src/hotspot/share/ci/ciMethodData.cpp +++ b/src/hotspot/share/ci/ciMethodData.cpp @@ -335,7 +335,10 @@ ciProfileData* ciMethodData::data_at(int data_index) { return NULL; } DataLayout* data_layout = data_layout_at(data_index); + return data_from(data_layout); +} +ciProfileData* ciMethodData::data_from(DataLayout* data_layout) { switch (data_layout->tag()) { case DataLayout::no_tag: default: @@ -380,6 +383,16 @@ ciProfileData* ciMethodData::next_data(ciProfileData* current) { return next; } +DataLayout* ciMethodData::next_data_layout(DataLayout* current) { + int current_index = dp_to_di((address)current); + int next_index = current_index + current->size_in_bytes(); + if (out_of_bounds(next_index)) { + return NULL; + } + DataLayout* next = data_layout_at(next_index); + return next; +} + ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots) { DataLayout* dp = extra_data_base(); DataLayout* end = args_data_limit(); @@ -417,12 +430,12 @@ ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_f ciProfileData* ciMethodData::bci_to_data(int bci, ciMethod* m) { // If m is not NULL we look for a SpeculativeTrapData entry if (m == NULL) { - ciProfileData* data = data_before(bci); - for ( ; is_valid(data); data = next_data(data)) { - if (data->bci() == bci) { - set_hint_di(dp_to_di(data->dp())); - return data; - } else if (data->bci() > bci) { + DataLayout* data_layout = data_layout_before(bci); + for ( ; is_valid(data_layout); data_layout = next_data_layout(data_layout)) { + if (data_layout->bci() == bci) { + set_hint_di(dp_to_di((address)data_layout)); + return data_from(data_layout); + } else if (data_layout->bci() > bci) { break; } } diff --git a/src/hotspot/share/ci/ciMethodData.hpp b/src/hotspot/share/ci/ciMethodData.hpp index ad6f5bf96ec..114a4e8fdc2 100644 --- a/src/hotspot/share/ci/ciMethodData.hpp +++ b/src/hotspot/share/ci/ciMethodData.hpp @@ -413,7 +413,7 @@ class ciMethodData : public ciMetadata { // Data entries intptr_t* _data; - // Cached hint for data_before() + // Cached hint for data_layout_before() int _hint_di; // Is data attached? And is it mature? @@ -479,17 +479,17 @@ class ciMethodData : public ciMetadata { assert(!out_of_bounds(di), "hint_di out of bounds"); _hint_di = di; } - ciProfileData* data_before(int bci) { + + DataLayout* data_layout_before(int bci) { // avoid SEGV on this edge case if (data_size() == 0) return NULL; - int hint = hint_di(); - if (data_layout_at(hint)->bci() <= bci) - return data_at(hint); - return first_data(); + DataLayout* layout = data_layout_at(hint_di()); + if (layout->bci() <= bci) + return layout; + return data_layout_at(first_di()); } - // What is the index of the first data entry? int first_di() { return 0; } @@ -503,6 +503,7 @@ class ciMethodData : public ciMetadata { template void dump_replay_data_call_type_helper(outputStream* out, int round, int& count, T* call_type_data); template void dump_replay_data_receiver_type_helper(outputStream* out, int round, int& count, T* call_type_data); void dump_replay_data_extra_data_helper(outputStream* out, int round, int& count); + ciProfileData* data_from(DataLayout* data_layout); public: bool is_method_data() const { return true; } @@ -553,7 +554,9 @@ class ciMethodData : public ciMetadata { // Walk through the data in order. ciProfileData* first_data() { return data_at(first_di()); } ciProfileData* next_data(ciProfileData* current); + DataLayout* next_data_layout(DataLayout* current); bool is_valid(ciProfileData* current) { return current != NULL; } + bool is_valid(DataLayout* current) { return current != NULL; } DataLayout* extra_data_base() const { return data_layout_at(data_size()); } DataLayout* args_data_limit() const { return data_layout_at(data_size() + extra_data_size() - diff --git a/src/hotspot/share/ci/ciReplay.cpp b/src/hotspot/share/ci/ciReplay.cpp index 4188b3dac61..e66bba311c8 100644 --- a/src/hotspot/share/ci/ciReplay.cpp +++ b/src/hotspot/share/ci/ciReplay.cpp @@ -495,7 +495,7 @@ class CompileReplay : public StackObj { return true; } - // compile inline ... + // compile inline ( )* void* process_inline(ciMethod* imethod, Method* m, int entry_bci, int comp_level, TRAPS) { _imethod = m; _iklass = imethod->holder(); @@ -525,7 +525,7 @@ class CompileReplay : public StackObj { return NULL; } - // compile inline ... + // compile inline ( )* void process_compile(TRAPS) { Method* method = parse_method(CHECK); if (had_error()) return; @@ -607,8 +607,6 @@ class CompileReplay : public StackObj { } // ciMethod - // - // void process_ciMethod(TRAPS) { Method* method = parse_method(CHECK); if (had_error()) return; @@ -620,7 +618,7 @@ class CompileReplay : public StackObj { rec->_instructions_size = parse_int("instructions_size"); } - // ciMethodData orig # # ... data # # ... oops # ... methods + // ciMethodData orig * data * oops ( )* methods ( )* void process_ciMethodData(TRAPS) { Method* method = parse_method(CHECK); if (had_error()) return; @@ -695,7 +693,7 @@ class CompileReplay : public StackObj { Klass* k = parse_klass(CHECK); } - // ciInstanceKlass tag # # # ... + // ciInstanceKlass tag* // // Load the klass 'name' and link or initialize it. Verify that the // constant pool is the same length as 'length' and make sure the @@ -1017,6 +1015,7 @@ class CompileReplay : public StackObj { } #if INCLUDE_JVMTI + // JvmtiExport void process_JvmtiExport(TRAPS) { const char* field = parse_string(); bool value = parse_int("JvmtiExport flag") != 0; diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index b729180755a..b3f06cf60fc 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -4045,9 +4045,16 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf class_info_index, CHECK); _nest_host = class_info_index; - } else if (_major_version >= JAVA_15_VERSION) { - // Check for PermittedSubclasses tag - if (tag == vmSymbols::tag_permitted_subclasses()) { + } else if (_major_version >= JAVA_16_VERSION) { + if (tag == vmSymbols::tag_record()) { + if (parsed_record_attribute) { + classfile_parse_error("Multiple Record attributes in class file %s", THREAD); + return; + } + parsed_record_attribute = true; + record_attribute_start = cfs->current(); + record_attribute_length = attribute_length; + } else if (tag == vmSymbols::tag_permitted_subclasses()) { if (supports_sealed_types()) { if (parsed_permitted_subclasses_attribute) { classfile_parse_error("Multiple PermittedSubclasses attributes in class file %s", CHECK); @@ -4062,23 +4069,9 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf permitted_subclasses_attribute_start = cfs->current(); permitted_subclasses_attribute_length = attribute_length; } - cfs->skip_u1(attribute_length, CHECK); - - } else if (_major_version >= JAVA_16_VERSION) { - if (tag == vmSymbols::tag_record()) { - if (parsed_record_attribute) { - classfile_parse_error("Multiple Record attributes in class file %s", THREAD); - return; - } - parsed_record_attribute = true; - record_attribute_start = cfs->current(); - record_attribute_length = attribute_length; - } - cfs->skip_u1(attribute_length, CHECK); - } else { - // Unknown attribute - cfs->skip_u1(attribute_length, CHECK); } + // Skip attribute_length for any attribute where major_verson >= JAVA_16_VERSION + cfs->skip_u1(attribute_length, CHECK); } else { // Unknown attribute cfs->skip_u1(attribute_length, CHECK); diff --git a/src/hotspot/share/classfile/classListParser.cpp b/src/hotspot/share/classfile/classListParser.cpp index eb33fa739c4..c978b8b8e25 100644 --- a/src/hotspot/share/classfile/classListParser.cpp +++ b/src/hotspot/share/classfile/classListParser.cpp @@ -37,6 +37,7 @@ #include "interpreter/linkResolver.hpp" #include "logging/log.hpp" #include "logging/logTag.hpp" +#include "memory/archiveUtils.hpp" #include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "oops/constantPool.hpp" @@ -115,13 +116,6 @@ bool ClassListParser::parse_one_line() { _line_len = len; } - // Check if the line is output TRACE_RESOLVE - if (strncmp(_line, LambdaFormInvokers::lambda_form_invoker_tag(), - strlen(LambdaFormInvokers::lambda_form_invoker_tag())) == 0) { - LambdaFormInvokers::append(os::strdup((const char*)_line, mtInternal)); - continue; - } - // valid line break; } @@ -133,6 +127,7 @@ bool ClassListParser::parse_one_line() { _source = NULL; _interfaces_specified = false; _indy_items->clear(); + _lambda_form_line = false; if (_line[0] == '@') { return parse_at_tags(); @@ -185,8 +180,8 @@ bool ClassListParser::parse_one_line() { return true; } -void ClassListParser::split_tokens_by_whitespace() { - int start = 0; +void ClassListParser::split_tokens_by_whitespace(int offset) { + int start = offset; int end; bool done = false; while (!done) { @@ -203,19 +198,40 @@ void ClassListParser::split_tokens_by_whitespace() { } } +int ClassListParser::split_at_tag_from_line() { + _token = _line; + char* ptr; + if ((ptr = strchr(_line, ' ')) == NULL) { + error("Too few items following the @ tag \"%s\" line #%d", _line, _line_no); + return 0; + } + *ptr++ = '\0'; + while (*ptr == ' ' || *ptr == '\t') ptr++; + return (int)(ptr - _line); +} + bool ClassListParser::parse_at_tags() { assert(_line[0] == '@', "must be"); - split_tokens_by_whitespace(); - if (strcmp(_indy_items->at(0), LAMBDA_PROXY_TAG) == 0) { - if (_indy_items->length() < 3) { - error("Line with @ tag has too few items \"%s\" line #%d", _line, _line_no); + int offset; + if ((offset = split_at_tag_from_line()) == 0) { + return false; + } + + if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) { + split_tokens_by_whitespace(offset); + if (_indy_items->length() < 2) { + error("Line with @ tag has too few items \"%s\" line #%d", _token, _line_no); return false; } // set the class name - _class_name = _indy_items->at(1); + _class_name = _indy_items->at(0); + return true; + } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) { + LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal)); + _lambda_form_line = true; return true; } else { - error("Invalid @ tag at the beginning of line \"%s\" line #%d", _line, _line_no); + error("Invalid @ tag at the beginning of line \"%s\" line #%d", _token, _line_no); return false; } } @@ -458,7 +474,7 @@ bool ClassListParser::is_matching_cp_entry(constantPoolHandle &pool, int cp_inde CDSIndyInfo cii; populate_cds_indy_info(pool, cp_index, &cii, THREAD); GrowableArray* items = cii.items(); - int indy_info_offset = 2; + int indy_info_offset = 1; if (_indy_items->length() - indy_info_offset != items->length()) { return false; } @@ -583,6 +599,7 @@ Klass* ClassListParser::load_current_class(TRAPS) { klass = java_lang_Class::as_Klass(obj); } else { // load classes in bootclasspath/a if (HAS_PENDING_EXCEPTION) { + ArchiveUtils::check_for_oom(PENDING_EXCEPTION); // exit on OOM CLEAR_PENDING_EXCEPTION; } @@ -593,6 +610,8 @@ Klass* ClassListParser::load_current_class(TRAPS) { } else { if (!HAS_PENDING_EXCEPTION) { THROW_NULL(vmSymbols::java_lang_ClassNotFoundException()); + } else { + ArchiveUtils::check_for_oom(PENDING_EXCEPTION); // exit on OOM } } } @@ -601,6 +620,9 @@ Klass* ClassListParser::load_current_class(TRAPS) { // If "source:" tag is specified, all super class and super interfaces must be specified in the // class list file. klass = load_class_from_source(class_name_symbol, CHECK_NULL); + if (HAS_PENDING_EXCEPTION) { + ArchiveUtils::check_for_oom(PENDING_EXCEPTION); // exit on OOM + } } if (klass != NULL && klass->is_instance_klass() && is_id_specified()) { diff --git a/src/hotspot/share/classfile/classListParser.hpp b/src/hotspot/share/classfile/classListParser.hpp index bbbaf0720a6..dd5cf0b62ff 100644 --- a/src/hotspot/share/classfile/classListParser.hpp +++ b/src/hotspot/share/classfile/classListParser.hpp @@ -30,7 +30,8 @@ #include "utilities/growableArray.hpp" #include "utilities/hashtable.inline.hpp" -#define LAMBDA_PROXY_TAG "@lambda-proxy:" +#define LAMBDA_PROXY_TAG "@lambda-proxy" +#define LAMBDA_FORM_TAG "@lambda-form-invoker" class ID2KlassTable : public KVHashtable { public: @@ -99,6 +100,7 @@ class ClassListParser : public StackObj { GrowableArray* _interfaces; bool _interfaces_specified; const char* _source; + bool _lambda_form_line; bool parse_int_option(const char* option_name, int* value); bool parse_uint_option(const char* option_name, int* value); @@ -120,7 +122,8 @@ class ClassListParser : public StackObj { return _instance; } bool parse_one_line(); - void split_tokens_by_whitespace(); + void split_tokens_by_whitespace(int offset); + int split_at_tag_from_line(); bool parse_at_tags(); char* _token; void error(const char* msg, ...); @@ -162,6 +165,8 @@ class ClassListParser : public StackObj { bool is_loading_from_source(); + bool lambda_form_line() { return _lambda_form_line; } + // Look up the super or interface of the current class being loaded // (in this->load_current_class()). InstanceKlass* lookup_super_for_current_class(Symbol* super_name); diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 4f04dfb8fd3..6a4f874dfbc 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -904,8 +904,9 @@ class java_lang_ref_Reference: AllStatic { public: // Accessors - static inline oop referent(oop ref); - static inline void set_referent(oop ref, oop value); + static inline oop weak_referent_no_keepalive(oop ref); + static inline oop phantom_referent_no_keepalive(oop ref); + static inline oop unknown_referent_no_keepalive(oop ref); static inline void set_referent_raw(oop ref, oop value); static inline HeapWord* referent_addr_raw(oop ref); static inline oop next(oop ref); diff --git a/src/hotspot/share/classfile/javaClasses.inline.hpp b/src/hotspot/share/classfile/javaClasses.inline.hpp index 3e880da8ae5..44d62dab5da 100644 --- a/src/hotspot/share/classfile/javaClasses.inline.hpp +++ b/src/hotspot/share/classfile/javaClasses.inline.hpp @@ -100,12 +100,17 @@ bool java_lang_String::is_instance_inlined(oop obj) { } // Accessors -oop java_lang_ref_Reference::referent(oop ref) { - return ref->obj_field(_referent_offset); + +oop java_lang_ref_Reference::weak_referent_no_keepalive(oop ref) { + return ref->obj_field_access(_referent_offset); +} + +oop java_lang_ref_Reference::phantom_referent_no_keepalive(oop ref) { + return ref->obj_field_access(_referent_offset); } -void java_lang_ref_Reference::set_referent(oop ref, oop value) { - ref->obj_field_put(_referent_offset, value); +oop java_lang_ref_Reference::unknown_referent_no_keepalive(oop ref) { + return ref->obj_field_access(_referent_offset); } void java_lang_ref_Reference::set_referent_raw(oop ref, oop value) { diff --git a/src/hotspot/share/classfile/lambdaFormInvokers.cpp b/src/hotspot/share/classfile/lambdaFormInvokers.cpp index aeca99a14df..ca7dc211e32 100644 --- a/src/hotspot/share/classfile/lambdaFormInvokers.cpp +++ b/src/hotspot/share/classfile/lambdaFormInvokers.cpp @@ -66,9 +66,7 @@ void LambdaFormInvokers::regenerate_holder_classes(TRAPS) { int len = _lambdaform_lines->length(); objArrayHandle list_lines = oopFactory::new_objArray_handle(SystemDictionary::String_klass(), len, CHECK); for (int i = 0; i < len; i++) { - char* record = _lambdaform_lines->at(i); - record += strlen(lambda_form_invoker_tag()) + 1; // skip the @lambda_form_invoker prefix - Handle h_line = java_lang_String::create_from_str(record, CHECK); + Handle h_line = java_lang_String::create_from_str(_lambdaform_lines->at(i), CHECK); list_lines->obj_at_put(i, h_line()); } diff --git a/src/hotspot/share/classfile/lambdaFormInvokers.hpp b/src/hotspot/share/classfile/lambdaFormInvokers.hpp index e587deba8c5..d21fb8e64ca 100644 --- a/src/hotspot/share/classfile/lambdaFormInvokers.hpp +++ b/src/hotspot/share/classfile/lambdaFormInvokers.hpp @@ -42,9 +42,5 @@ class LambdaFormInvokers : public AllStatic { static GrowableArray* lambdaform_lines() { return _lambdaform_lines; } - - static const char* lambda_form_invoker_tag() { - return "@lambda-form-invoker"; - } }; #endif // SHARE_MEMORY_LAMBDAFORMINVOKERS_HPP diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp index 3b589844232..7e4c88e65e2 100644 --- a/src/hotspot/share/code/codeCache.cpp +++ b/src/hotspot/share/code/codeCache.cpp @@ -1559,6 +1559,34 @@ void CodeCache::log_state(outputStream* st) { unallocated_capacity()); } +#ifdef LINUX +void CodeCache::write_perf_map() { + MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); + + // Perf expects to find the map file at /tmp/perf-.map. + char fname[32]; + jio_snprintf(fname, sizeof(fname), "/tmp/perf-%d.map", os::current_process_id()); + + fileStream fs(fname, "w"); + if (!fs.is_open()) { + log_warning(codecache)("Failed to create %s for perf map", fname); + return; + } + + AllCodeBlobsIterator iter(AllCodeBlobsIterator::only_alive_and_not_unloading); + while (iter.next()) { + CodeBlob *cb = iter.method(); + ResourceMark rm; + const char* method_name = + cb->is_compiled() ? cb->as_compiled_method()->method()->external_name() + : cb->name(); + fs.print_cr(INTPTR_FORMAT " " INTPTR_FORMAT " %s", + (intptr_t)cb->code_begin(), (intptr_t)cb->code_size(), + method_name); + } +} +#endif // LINUX + //---< BEGIN >--- CodeHeap State Analytics. void CodeCache::aggregate(outputStream *out, size_t granularity) { diff --git a/src/hotspot/share/code/codeCache.hpp b/src/hotspot/share/code/codeCache.hpp index 4a3e29810f3..959396f8699 100644 --- a/src/hotspot/share/code/codeCache.hpp +++ b/src/hotspot/share/code/codeCache.hpp @@ -191,6 +191,7 @@ class CodeCache : AllStatic { static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN; static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage static void log_state(outputStream* st); + LINUX_ONLY(static void write_perf_map();) static const char* get_code_heap_name(int code_blob_type) { return (heap_available(code_blob_type) ? get_code_heap(code_blob_type)->name() : "Unused"); } static void report_codemem_full(int code_blob_type, bool print); @@ -409,7 +410,13 @@ struct NMethodFilter { static const GrowableArray* heaps() { return CodeCache::nmethod_heaps(); } }; +struct AllCodeBlobsFilter { + static bool apply(CodeBlob* cb) { return true; } + static const GrowableArray* heaps() { return CodeCache::heaps(); } +}; + typedef CodeBlobIterator CompiledMethodIterator; typedef CodeBlobIterator NMethodIterator; +typedef CodeBlobIterator AllCodeBlobsIterator; #endif // SHARE_CODE_CODECACHE_HPP diff --git a/src/hotspot/share/compiler/compilerDirectives.cpp b/src/hotspot/share/compiler/compilerDirectives.cpp index b940a7e8e36..753f9798a83 100644 --- a/src/hotspot/share/compiler/compilerDirectives.cpp +++ b/src/hotspot/share/compiler/compilerDirectives.cpp @@ -322,7 +322,6 @@ class DirectiveSetPtr { // - if some option is changed we need to copy directiveset since it no longer can be shared // - Need to free copy after use // - Requires a modified bit so we don't overwrite options that is set by directives - DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle& method) { // Early bail out - checking all options is expensive - we rely on them not being used // Only set a flag if it has not been modified and value changes. @@ -360,6 +359,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle } // inline and dontinline (including exclude) are implemented in the directiveset accessors + // ignore flags whose cc_flags are X #define init_default_cc(name, type, dvalue, cc_flag) { type v; if (!_modified[name##Index] && CompilerOracle::has_option_value(method, #cc_flag, v) && v != this->name##Option) { set.cloned()->name##Option = v; } } compilerdirectives_common_flags(init_default_cc) compilerdirectives_c2_flags(init_default_cc) diff --git a/src/hotspot/share/compiler/compilerDirectives.hpp b/src/hotspot/share/compiler/compilerDirectives.hpp index a04c13ea061..a67e534a9b2 100644 --- a/src/hotspot/share/compiler/compilerDirectives.hpp +++ b/src/hotspot/share/compiler/compilerDirectives.hpp @@ -36,8 +36,8 @@ #define compilerdirectives_common_flags(cflags) \ cflags(Enable, bool, false, X) \ cflags(Exclude, bool, false, X) \ - cflags(BreakAtExecute, bool, false, X) \ - cflags(BreakAtCompile, bool, false, X) \ + cflags(BreakAtExecute, bool, false, BreakAtExecute) \ + cflags(BreakAtCompile, bool, false, BreakAtCompile) \ cflags(Log, bool, LogCompilation, X) \ cflags(PrintAssembly, bool, PrintAssembly, PrintAssembly) \ cflags(PrintInlining, bool, PrintInlining, PrintInlining) \ diff --git a/src/hotspot/share/gc/g1/g1Allocator.cpp b/src/hotspot/share/gc/g1/g1Allocator.cpp index cb172b5f5b5..c20b4400cad 100644 --- a/src/hotspot/share/gc/g1/g1Allocator.cpp +++ b/src/hotspot/share/gc/g1/g1Allocator.cpp @@ -281,22 +281,9 @@ HeapWord* G1Allocator::old_attempt_allocation(size_t min_word_size, return result; } -uint G1PLABAllocator::calc_survivor_alignment_bytes() { - assert(SurvivorAlignmentInBytes >= ObjectAlignmentInBytes, "sanity"); - if (SurvivorAlignmentInBytes == ObjectAlignmentInBytes) { - // No need to align objects in the survivors differently, return 0 - // which means "survivor alignment is not used". - return 0; - } else { - assert(SurvivorAlignmentInBytes > 0, "sanity"); - return SurvivorAlignmentInBytes; - } -} - G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) : _g1h(G1CollectedHeap::heap()), - _allocator(allocator), - _survivor_alignment_bytes(calc_survivor_alignment_bytes()) { + _allocator(allocator) { for (region_type_t state = 0; state < G1HeapRegionAttr::Num; state++) { _direct_allocated[state] = 0; uint length = alloc_buffers_length(state); diff --git a/src/hotspot/share/gc/g1/g1Allocator.hpp b/src/hotspot/share/gc/g1/g1Allocator.hpp index f0702b4d6c2..4346171466f 100644 --- a/src/hotspot/share/gc/g1/g1Allocator.hpp +++ b/src/hotspot/share/gc/g1/g1Allocator.hpp @@ -149,13 +149,6 @@ class G1PLABAllocator : public CHeapObj { PLAB** _alloc_buffers[G1HeapRegionAttr::Num]; - // The survivor alignment in effect in bytes. - // == 0 : don't align survivors - // != 0 : align survivors to that alignment - // These values were chosen to favor the non-alignment case since some - // architectures have a special compare against zero instructions. - const uint _survivor_alignment_bytes; - // Number of words allocated directly (not counting PLAB allocation). size_t _direct_allocated[G1HeapRegionAttr::Num]; @@ -168,10 +161,6 @@ class G1PLABAllocator : public CHeapObj { // active NUMA nodes. inline uint alloc_buffers_length(region_type_t dest) const; - // Calculate the survivor space object alignment in bytes. Returns that or 0 if - // there are no restrictions on survivor alignment. - static uint calc_survivor_alignment_bytes(); - bool may_throw_away_buffer(size_t const allocation_word_sz, size_t const buffer_size) const; public: G1PLABAllocator(G1Allocator* allocator); diff --git a/src/hotspot/share/gc/g1/g1Allocator.inline.hpp b/src/hotspot/share/gc/g1/g1Allocator.inline.hpp index 5b6ab355c4d..6d484292051 100644 --- a/src/hotspot/share/gc/g1/g1Allocator.inline.hpp +++ b/src/hotspot/share/gc/g1/g1Allocator.inline.hpp @@ -105,11 +105,7 @@ inline HeapWord* G1PLABAllocator::plab_allocate(G1HeapRegionAttr dest, size_t word_sz, uint node_index) { PLAB* buffer = alloc_buffer(dest, node_index); - if (_survivor_alignment_bytes == 0 || !dest.is_young()) { - return buffer->allocate(word_sz); - } else { - return buffer->allocate_aligned(word_sz, _survivor_alignment_bytes); - } + return buffer->allocate(word_sz); } inline HeapWord* G1PLABAllocator::allocate(G1HeapRegionAttr dest, diff --git a/src/hotspot/share/gc/g1/g1BiasedArray.cpp b/src/hotspot/share/gc/g1/g1BiasedArray.cpp index 0d9a3caf4eb..ce0196ee5bb 100644 --- a/src/hotspot/share/gc/g1/g1BiasedArray.cpp +++ b/src/hotspot/share/gc/g1/g1BiasedArray.cpp @@ -26,11 +26,23 @@ #include "gc/g1/g1BiasedArray.hpp" #include "memory/padded.inline.hpp" +G1BiasedMappedArrayBase::G1BiasedMappedArrayBase() : + _alloc_base(NULL), + _base(NULL), + _length(0), + _biased_base(NULL), + _bias(0), + _shift_by(0) { } + +G1BiasedMappedArrayBase::~G1BiasedMappedArrayBase() { + FreeHeap(_alloc_base); +} + // Allocate a new array, generic version. address G1BiasedMappedArrayBase::create_new_base_array(size_t length, size_t elem_size) { assert(length > 0, "just checking"); assert(elem_size > 0, "just checking"); - return PaddedPrimitiveArray::create_unfreeable(length * elem_size); + return PaddedPrimitiveArray::create(length * elem_size, &_alloc_base); } #ifndef PRODUCT diff --git a/src/hotspot/share/gc/g1/g1BiasedArray.hpp b/src/hotspot/share/gc/g1/g1BiasedArray.hpp index 248abbabf1e..7c604706566 100644 --- a/src/hotspot/share/gc/g1/g1BiasedArray.hpp +++ b/src/hotspot/share/gc/g1/g1BiasedArray.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_GC_G1_G1BIASEDARRAY_HPP #define SHARE_GC_G1_G1BIASEDARRAY_HPP +#include "memory/allocation.hpp" #include "memory/memRegion.hpp" #include "utilities/debug.hpp" #include "utilities/powerOfTwo.hpp" @@ -32,10 +33,14 @@ // Implements the common base functionality for arrays that contain provisions // for accessing its elements using a biased index. // The element type is defined by the instantiating the template. -class G1BiasedMappedArrayBase { +class G1BiasedMappedArrayBase : public CHeapObj { friend class VMStructs; + + void* _alloc_base; // the address the unpadded array has been allocated to + public: typedef size_t idx_t; + protected: address _base; // the real base address size_t _length; // the length of the array @@ -44,12 +49,10 @@ class G1BiasedMappedArrayBase { uint _shift_by; // the amount of bits to shift right when mapping to an index of the array. protected: - - G1BiasedMappedArrayBase() : _base(NULL), _length(0), _biased_base(NULL), - _bias(0), _shift_by(0) { } + G1BiasedMappedArrayBase(); // Allocate a new array, generic version. - static address create_new_base_array(size_t length, size_t elem_size); + address create_new_base_array(size_t length, size_t elem_size); // Initialize the members of this class. The biased start address of this array // is the bias (in elements) multiplied by the element size. @@ -90,8 +93,10 @@ class G1BiasedMappedArrayBase { void verify_biased_index_inclusive_end(idx_t biased_index) const PRODUCT_RETURN; public: - // Return the length of the array in elements. - size_t length() const { return _length; } + virtual ~G1BiasedMappedArrayBase(); + + // Return the length of the array in elements. + size_t length() const { return _length; } }; // Array that provides biased access and mapping from (valid) addresses in the diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp index 23879d7bbed..b58d8c66d8b 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp @@ -108,7 +108,7 @@ void G1ConcurrentMarkThread::delay_to_keep_mmu(bool remark) { jlong sleep_time_ms = ceil(sleep_time_sec * MILLIUNITS); if (sleep_time_ms <= 0) { break; // Passed end time. - } else if (ml.wait(sleep_time_ms, Monitor::_no_safepoint_check_flag)) { + } else if (ml.wait(sleep_time_ms)) { break; // Timeout => reached end time. } // Other (possibly spurious) wakeup. Retry with updated sleep time. diff --git a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp index efa0fb91bbf..11a66dea934 100644 --- a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ #ifndef SHARE_GC_G1_G1FULLGCMARKER_INLINE_HPP #define SHARE_GC_G1_G1FULLGCMARKER_INLINE_HPP +#include "classfile/javaClasses.inline.hpp" #include "gc/g1/g1Allocator.inline.hpp" #include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp" #include "gc/g1/g1FullGCMarker.hpp" @@ -57,7 +58,8 @@ inline bool G1FullGCMarker::mark_object(oop obj) { } // Check if deduplicatable string. - if (G1StringDedup::is_enabled()) { + if (G1StringDedup::is_enabled() && + java_lang_String::is_instance_inlined(obj)) { G1StringDedup::enqueue_from_mark(obj, _worker_id); } return true; diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp index 0a795389b32..7a5fb1b9cd2 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/systemDictionary.hpp" #include "gc/g1/g1Allocator.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectionSet.hpp" @@ -75,10 +76,17 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, _old_gen_is_full(false), _partial_objarray_chunk_size(ParGCArrayScanChunk), _partial_array_stepper(n_workers), + _string_klass_or_null(G1StringDedup::is_enabled() + ? SystemDictionary::String_klass() + : nullptr), _num_optional_regions(optional_cset_length), _numa(g1h->numa()), _obj_alloc_stat(NULL) { + // Verify klass comparison with _string_klass_or_null is sufficient + // to determine whether dedup is enabled and the object is a String. + assert(SystemDictionary::String_klass()->is_final(), "precondition"); + // We allocate number of young gen regions in the collection set plus one // entries, since entry 0 keeps track of surviving bytes for non-young regions. // We also add a few elements at the beginning and at the end in @@ -511,7 +519,10 @@ oop G1ParScanThreadState::do_copy_to_survivor_space(G1HeapRegionAttr const regio return obj; } - if (G1StringDedup::is_enabled()) { + // StringDedup::is_enabled() and java_lang_String::is_instance_inline + // test of the obj, combined into a single comparison, using the klass + // already in hand and avoiding the null check in is_instance. + if (klass == _string_klass_or_null) { const bool is_from_young = region_attr.is_young(); const bool is_to_young = dest_attr.is_young(); assert(is_from_young == from_region->is_young(), diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp index 0f6a4f211bc..8b1c1b65700 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp @@ -42,6 +42,7 @@ class G1OopStarChunkedList; class G1PLABAllocator; class G1EvacuationRootClosures; class HeapRegion; +class Klass; class outputStream; class G1ParScanThreadState : public CHeapObj { @@ -83,6 +84,8 @@ class G1ParScanThreadState : public CHeapObj { // Size (in elements) of a partial objArray task chunk. int _partial_objarray_chunk_size; PartialArrayTaskStepper _partial_array_stepper; + // Used to check whether string dedup should be applied to an object. + Klass* _string_klass_or_null; G1RedirtyCardsQueue& redirty_cards_queue() { return _rdcq; } G1CardTable* ct() { return _ct; } diff --git a/src/hotspot/share/gc/g1/g1ServiceThread.cpp b/src/hotspot/share/gc/g1/g1ServiceThread.cpp index 0c7f91ab6d7..3c3e561a6b4 100644 --- a/src/hotspot/share/gc/g1/g1ServiceThread.cpp +++ b/src/hotspot/share/gc/g1/g1ServiceThread.cpp @@ -36,92 +36,69 @@ #include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" -G1ServiceThread::G1ServiceThread() : - ConcurrentGCThread(), - _monitor(Mutex::nonleaf, - "G1ServiceThread monitor", - true, - Monitor::_safepoint_check_never), - _last_periodic_gc_attempt_s(os::elapsedTime()), - _vtime_accum(0) { - set_name("G1 Service"); - create_and_start(); +G1SentinelTask::G1SentinelTask() : G1ServiceTask("Sentinel Task") { + set_time(max_jlong); + set_next(this); } -void G1ServiceThread::sleep_before_next_cycle() { - MonitorLocker ml(&_monitor, Mutex::_no_safepoint_check_flag); - if (!should_terminate()) { - uintx waitms = G1ConcRefinementServiceIntervalMillis; - ml.wait(waitms); - } +void G1SentinelTask::execute() { + guarantee(false, "Sentinel service task should never be executed."); } -bool G1ServiceThread::should_start_periodic_gc() { - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - // If we are currently in a concurrent mark we are going to uncommit memory soon. - if (g1h->concurrent_mark()->cm_thread()->in_progress()) { - log_debug(gc, periodic)("Concurrent cycle in progress. Skipping."); - return false; - } +// Task handling periodic GCs +class G1PeriodicGCTask : public G1ServiceTask { + bool should_start_periodic_gc() { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + // If we are currently in a concurrent mark we are going to uncommit memory soon. + if (g1h->concurrent_mark()->cm_thread()->in_progress()) { + log_debug(gc, periodic)("Concurrent cycle in progress. Skipping."); + return false; + } - // Check if enough time has passed since the last GC. - uintx time_since_last_gc = (uintx)g1h->time_since_last_collection().milliseconds(); - if ((time_since_last_gc < G1PeriodicGCInterval)) { - log_debug(gc, periodic)("Last GC occurred " UINTX_FORMAT "ms before which is below threshold " UINTX_FORMAT "ms. Skipping.", - time_since_last_gc, G1PeriodicGCInterval); - return false; - } + // Check if enough time has passed since the last GC. + uintx time_since_last_gc = (uintx)g1h->time_since_last_collection().milliseconds(); + if ((time_since_last_gc < G1PeriodicGCInterval)) { + log_debug(gc, periodic)("Last GC occurred " UINTX_FORMAT "ms before which is below threshold " UINTX_FORMAT "ms. Skipping.", + time_since_last_gc, G1PeriodicGCInterval); + return false; + } - // Check if load is lower than max. - double recent_load; - if ((G1PeriodicGCSystemLoadThreshold > 0.0f) && - (os::loadavg(&recent_load, 1) == -1 || recent_load > G1PeriodicGCSystemLoadThreshold)) { - log_debug(gc, periodic)("Load %1.2f is higher than threshold %1.2f. Skipping.", - recent_load, G1PeriodicGCSystemLoadThreshold); - return false; + // Check if load is lower than max. + double recent_load; + if ((G1PeriodicGCSystemLoadThreshold > 0.0f) && + (os::loadavg(&recent_load, 1) == -1 || recent_load > G1PeriodicGCSystemLoadThreshold)) { + log_debug(gc, periodic)("Load %1.2f is higher than threshold %1.2f. Skipping.", + recent_load, G1PeriodicGCSystemLoadThreshold); + return false; + } + return true; } - return true; -} + void check_for_periodic_gc(){ + // If disabled, just return. + if (G1PeriodicGCInterval == 0) { + return; + } -void G1ServiceThread::check_for_periodic_gc(){ - // If disabled, just return. - if (G1PeriodicGCInterval == 0) { - return; - } - if ((os::elapsedTime() - _last_periodic_gc_attempt_s) > (G1PeriodicGCInterval / 1000.0)) { log_debug(gc, periodic)("Checking for periodic GC."); if (should_start_periodic_gc()) { if (!G1CollectedHeap::heap()->try_collect(GCCause::_g1_periodic_collection)) { log_debug(gc, periodic)("GC request denied. Skipping."); } } - _last_periodic_gc_attempt_s = os::elapsedTime(); } -} - -void G1ServiceThread::run_service() { - double vtime_start = os::elapsedVTime(); - - while (!should_terminate()) { - sample_young_list_rs_length(); - - if (os::supports_vtime()) { - _vtime_accum = (os::elapsedVTime() - vtime_start); - } else { - _vtime_accum = 0.0; - } +public: + G1PeriodicGCTask(const char* name) : G1ServiceTask(name) { } + virtual void execute() { check_for_periodic_gc(); - - sleep_before_next_cycle(); + // G1PeriodicGCInterval is a manageable flag and can be updated + // during runtime. If no value is set, wait a second and run it + // again to see if the value has been updated. Otherwise use the + // real value provided. + schedule(G1PeriodicGCInterval == 0 ? 1000 : G1PeriodicGCInterval); } -} - -void G1ServiceThread::stop_service() { - MutexLocker x(&_monitor, Mutex::_no_safepoint_check_flag); - _monitor.notify(); -} +}; class G1YoungRemSetSamplingClosure : public HeapRegionClosure { SuspendibleThreadSetJoiner* _sts; @@ -155,19 +132,265 @@ class G1YoungRemSetSamplingClosure : public HeapRegionClosure { size_t sampled_rs_length() const { return _sampled_rs_length; } }; -void G1ServiceThread::sample_young_list_rs_length() { - SuspendibleThreadSetJoiner sts; - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - G1Policy* policy = g1h->policy(); +// Task handling young gen remembered set sampling. +class G1RemSetSamplingTask : public G1ServiceTask { + // Sample the current length of remembered sets for young. + // + // At the end of the GC G1 determines the length of the young gen based on + // how much time the next GC can take, and when the next GC may occur + // according to the MMU. + // + // The assumption is that a significant part of the GC is spent on scanning + // the remembered sets (and many other components), so this thread constantly + // reevaluates the prediction for the remembered set scanning costs, and potentially + // G1Policy resizes the young gen. This may do a premature GC or even + // increase the young gen size to keep pause time length goal. + void sample_young_list_rs_length(){ + SuspendibleThreadSetJoiner sts; + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + G1Policy* policy = g1h->policy(); + + if (policy->use_adaptive_young_list_length()) { + G1YoungRemSetSamplingClosure cl(&sts); + + G1CollectionSet* g1cs = g1h->collection_set(); + g1cs->iterate(&cl); + + if (cl.is_complete()) { + policy->revise_young_list_target_length_if_necessary(cl.sampled_rs_length()); + } + } + } +public: + G1RemSetSamplingTask(const char* name) : G1ServiceTask(name) { } + virtual void execute() { + sample_young_list_rs_length(); + schedule(G1ConcRefinementServiceIntervalMillis); + } +}; + +G1ServiceThread::G1ServiceThread() : + ConcurrentGCThread(), + _monitor(Mutex::nonleaf, + "G1ServiceThread monitor", + true, + Monitor::_safepoint_check_never), + _task_queue(), + _vtime_accum(0) { + set_name("G1 Service"); + create_and_start(); +} + +void G1ServiceThread::register_task(G1ServiceTask* task, jlong delay) { + guarantee(!task->is_registered(), "Task already registered"); + guarantee(task->next() == NULL, "Task already in queue"); + + log_debug(gc, task)("G1 Service Thread (%s) (register)", task->name()); + + // Associate the task with the service thread. + task->set_service_thread(this); + + // Schedule the task to run after the given delay. + schedule_task(task, delay); + + // Notify the service thread that there is a new task, thread might + // be waiting and the newly added task might be first in the list. + MonitorLocker ml(&_monitor, Mutex::_no_safepoint_check_flag); + ml.notify(); +} + +void G1ServiceThread::schedule_task(G1ServiceTask* task, jlong delay_ms) { + guarantee(task->is_registered(), "Must be registered before scheduled"); + guarantee(task->next() == NULL, "Task already in queue"); + + // Schedule task by setting the task time and adding it to queue. + jlong delay = TimeHelper::millis_to_counter(delay_ms); + task->set_time(os::elapsed_counter() + delay); + + MutexLocker ml(&_monitor, Mutex::_no_safepoint_check_flag); + _task_queue.add_ordered(task); - if (policy->use_adaptive_young_list_length()) { - G1YoungRemSetSamplingClosure cl(&sts); + log_trace(gc, task)("G1 Service Thread (%s) (schedule) @%1.3fs", + task->name(), TimeHelper::counter_to_seconds(task->time())); +} + +int64_t G1ServiceThread::time_to_next_task_ms() { + assert(_monitor.owned_by_self(), "Must be owner of lock"); + assert(!_task_queue.is_empty(), "Should not be called for empty list"); + + jlong time_diff = _task_queue.peek()->time() - os::elapsed_counter(); + if (time_diff < 0) { + // Run without sleeping. + return 0; + } + + // Return sleep time in milliseconds. + return (int64_t) TimeHelper::counter_to_millis(time_diff); +} + +void G1ServiceThread::sleep_before_next_cycle() { + if (should_terminate()) { + return; + } + + MonitorLocker ml(&_monitor, Mutex::_no_safepoint_check_flag); + if (_task_queue.is_empty()) { + // Sleep until new task is registered if no tasks available. + log_trace(gc, task)("G1 Service Thread (wait for new tasks)"); + ml.wait(0); + } else { + int64_t sleep_ms = time_to_next_task_ms(); + if (sleep_ms > 0) { + log_trace(gc, task)("G1 Service Thread (wait) %1.3fs", sleep_ms / 1000.0); + ml.wait(sleep_ms); + } + } +} + +G1ServiceTask* G1ServiceThread::pop_due_task() { + MutexLocker ml(&_monitor, Mutex::_no_safepoint_check_flag); + if (_task_queue.is_empty() || time_to_next_task_ms() != 0) { + return NULL; + } + + return _task_queue.pop(); +} - G1CollectionSet* g1cs = g1h->collection_set(); - g1cs->iterate(&cl); +void G1ServiceThread::run_task(G1ServiceTask* task) { + double start = os::elapsedTime(); + double vstart = os::elapsedVTime(); - if (cl.is_complete()) { - policy->revise_young_list_target_length_if_necessary(cl.sampled_rs_length()); + log_debug(gc, task, start)("G1 Service Thread (%s) (run)", task->name()); + task->execute(); + + double duration = os::elapsedTime() - start; + double vduration = os::elapsedVTime() - vstart; + log_debug(gc, task)("G1 Service Thread (%s) (run) %1.3fms (cpu: %1.3fms)", + task->name(), duration * MILLIUNITS, vduration * MILLIUNITS); +} + +void G1ServiceThread::run_service() { + double vtime_start = os::elapsedVTime(); + + // Setup the tasks handeled by the service thread and + // add them to the task list. + G1PeriodicGCTask gc_task("Periodic GC Task"); + register_task(&gc_task); + + G1RemSetSamplingTask remset_task("Remembered Set Sampling Task"); + register_task(&remset_task); + + while (!should_terminate()) { + G1ServiceTask* task = pop_due_task(); + if (task != NULL) { + run_task(task); } + + if (os::supports_vtime()) { + _vtime_accum = (os::elapsedVTime() - vtime_start); + } else { + _vtime_accum = 0.0; + } + sleep_before_next_cycle(); + } +} + +void G1ServiceThread::stop_service() { + MonitorLocker ml(&_monitor, Mutex::_no_safepoint_check_flag); + ml.notify(); +} + +G1ServiceTask::G1ServiceTask(const char* name) : + _time(), + _name(name), + _next(NULL), + _service_thread(NULL) { } + +void G1ServiceTask::set_service_thread(G1ServiceThread* thread) { + _service_thread = thread; +} + +bool G1ServiceTask::is_registered() { + return _service_thread != NULL; +} + +void G1ServiceTask::schedule(jlong delay_ms) { + _service_thread->schedule_task(this, delay_ms); +} + +const char* G1ServiceTask::name() { + return _name; +} + +void G1ServiceTask::set_time(jlong time) { + assert(_next == NULL, "Not allowed to update time while in queue"); + _time = time; +} + +jlong G1ServiceTask::time() { + return _time; +} + +void G1ServiceTask::set_next(G1ServiceTask* next) { + _next = next; +} + +G1ServiceTask* G1ServiceTask::next() { + return _next; +} + +G1ServiceTaskQueue::G1ServiceTaskQueue() : _sentinel() { } + +G1ServiceTask* G1ServiceTaskQueue::pop() { + verify_task_queue(); + + G1ServiceTask* task = _sentinel.next(); + _sentinel.set_next(task->next()); + task->set_next(NULL); + + return task; +} + +G1ServiceTask* G1ServiceTaskQueue::peek() { + verify_task_queue(); + return _sentinel.next(); +} + +bool G1ServiceTaskQueue::is_empty() { + return &_sentinel == _sentinel.next(); +} + +void G1ServiceTaskQueue::add_ordered(G1ServiceTask* task) { + assert(task != NULL, "not a valid task"); + assert(task->next() == NULL, "invariant"); + assert(task->time() != max_jlong, "invalid time for task"); + + G1ServiceTask* current = &_sentinel; + while (task->time() >= current->next()->time()) { + assert(task != current, "Task should only be added once."); + current = current->next(); + } + + // Update the links. + task->set_next(current->next()); + current->set_next(task); + + verify_task_queue(); +} + +#ifdef ASSERT +void G1ServiceTaskQueue::verify_task_queue() { + G1ServiceTask* cur = _sentinel.next(); + + assert(cur != &_sentinel, "Should never try to verify empty queue"); + while (cur != &_sentinel) { + G1ServiceTask* next = cur->next(); + assert(cur->time() <= next->time(), + "Tasks out of order, prev: %s (%1.3fs), next: %s (%1.3fs)", + cur->name(), TimeHelper::counter_to_seconds(cur->time()), next->name(), TimeHelper::counter_to_seconds(next->time())); + + assert(cur != next, "Invariant"); + cur = next; } } +#endif diff --git a/src/hotspot/share/gc/g1/g1ServiceThread.hpp b/src/hotspot/share/gc/g1/g1ServiceThread.hpp index 3454f65d02e..331e254012e 100644 --- a/src/hotspot/share/gc/g1/g1ServiceThread.hpp +++ b/src/hotspot/share/gc/g1/g1ServiceThread.hpp @@ -28,43 +28,104 @@ #include "gc/shared/concurrentGCThread.hpp" #include "runtime/mutex.hpp" +class G1ServiceTaskQueue; +class G1ServiceThread; + +class G1ServiceTask : public CHeapObj { + friend class G1ServiceTaskQueue; + friend class G1ServiceThread; + + // The next absolute time this task should be executed. + jlong _time; + // Name of the task. + const char* _name; + // Next task in the task queue. + G1ServiceTask* _next; + // The service thread this task is registered with. + G1ServiceThread* _service_thread; + + void set_service_thread(G1ServiceThread* thread); + bool is_registered(); + +public: + G1ServiceTask(const char* name); + + jlong time(); + const char* name(); + G1ServiceTask* next(); + + // Do the actual work for the task. To get added back to the + // execution queue a task can call schedule(delay_ms). + virtual void execute() = 0; + +protected: + // Schedule the task on the associated service thread + // using the provided delay in milliseconds. + void schedule(jlong delay_ms); + + // These setters are protected for use by testing and the + // sentinel task only. + void set_time(jlong time); + void set_next(G1ServiceTask* next); +}; + +class G1SentinelTask : public G1ServiceTask { +public: + G1SentinelTask(); + virtual void execute(); +}; + +class G1ServiceTaskQueue { + // The sentinel task is the entry point of this priority queue holding the + // service tasks. The queue is ordered by the time the tasks are scheduled + // to run. To simplify list management the sentinel task has its time set + // to max_jlong, guaranteeing it to be the last task in the queue. + G1SentinelTask _sentinel; + + // Verify that the queue is ordered. + void verify_task_queue() NOT_DEBUG_RETURN; +public: + G1ServiceTaskQueue(); + G1ServiceTask* pop(); + G1ServiceTask* peek(); + void add_ordered(G1ServiceTask* task); + bool is_empty(); +}; + // The G1ServiceThread is used to periodically do a number of different tasks: // - re-assess the validity of the prediction for the // remembered set lengths of the young generation. // - check if a periodic GC should be scheduled. class G1ServiceThread: public ConcurrentGCThread { -private: + friend class G1ServiceTask; + // The monitor is used to ensure thread safety for the task queue + // and allow other threads to signal the service thread to wake up. Monitor _monitor; - - double _last_periodic_gc_attempt_s; + G1ServiceTaskQueue _task_queue; double _vtime_accum; // Accumulated virtual time. - // Sample the current length of remembered sets for young. - // - // At the end of the GC G1 determines the length of the young gen based on - // how much time the next GC can take, and when the next GC may occur - // according to the MMU. - // - // The assumption is that a significant part of the GC is spent on scanning - // the remembered sets (and many other components), so this thread constantly - // reevaluates the prediction for the remembered set scanning costs, and potentially - // G1Policy resizes the young gen. This may do a premature GC or even - // increase the young gen size to keep pause time length goal. - void sample_young_list_rs_length(); - void run_service(); - void check_for_periodic_gc(); - void stop_service(); + // Returns the time in milliseconds until the next task is due. + // Used both to determine if there are tasks ready to run and + // how long to sleep when nothing is ready. + int64_t time_to_next_task_ms(); void sleep_before_next_cycle(); - bool should_start_periodic_gc(); + G1ServiceTask* pop_due_task(); + void run_task(G1ServiceTask* task); + + // Schedule a registered task to run after the given delay. + void schedule_task(G1ServiceTask* task, jlong delay); public: G1ServiceThread(); double vtime_accum() { return _vtime_accum; } + // Register a task with the service thread and schedule it. If + // no delay is specified the task is scheduled to run directly. + void register_task(G1ServiceTask* task, jlong delay = 0); }; #endif // SHARE_GC_G1_G1SERVICETHREAD_HPP diff --git a/src/hotspot/share/gc/g1/g1StringDedup.cpp b/src/hotspot/share/gc/g1/g1StringDedup.cpp index 2da35163fad..122f1a7e9c7 100644 --- a/src/hotspot/share/gc/g1/g1StringDedup.cpp +++ b/src/hotspot/share/gc/g1/g1StringDedup.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,29 +41,23 @@ void G1StringDedup::initialize() { } bool G1StringDedup::is_candidate_from_mark(oop obj) { - if (java_lang_String::is_instance_inlined(obj)) { - bool from_young = G1CollectedHeap::heap()->heap_region_containing(obj)->is_young(); - if (from_young && obj->age() < StringDeduplicationAgeThreshold) { - // Candidate found. String is being evacuated from young to old but has not - // reached the deduplication age threshold, i.e. has not previously been a - // candidate during its life in the young generation. - return true; - } - } - - // Not a candidate - return false; + bool from_young = G1CollectedHeap::heap()->heap_region_containing(obj)->is_young(); + // Candidate if string is being evacuated from young to old but has not + // reached the deduplication age threshold, i.e. has not previously been a + // candidate during its life in the young generation. + return from_young && (obj->age() < StringDeduplicationAgeThreshold); } void G1StringDedup::enqueue_from_mark(oop java_string, uint worker_id) { assert(is_enabled(), "String deduplication not enabled"); + assert(java_lang_String::is_instance(java_string), "not a String"); if (is_candidate_from_mark(java_string)) { G1StringDedupQueue::push(worker_id, java_string); } } bool G1StringDedup::is_candidate_from_evacuation(bool from_young, bool to_young, oop obj) { - if (from_young && java_lang_String::is_instance_inlined(obj)) { + if (from_young) { if (to_young && obj->age() == StringDeduplicationAgeThreshold) { // Candidate found. String is being evacuated from young to young and just // reached the deduplication age threshold. @@ -83,6 +77,7 @@ bool G1StringDedup::is_candidate_from_evacuation(bool from_young, bool to_young, void G1StringDedup::enqueue_from_evacuation(bool from_young, bool to_young, uint worker_id, oop java_string) { assert(is_enabled(), "String deduplication not enabled"); + assert(java_lang_String::is_instance(java_string), "not a String"); if (is_candidate_from_evacuation(from_young, to_young, java_string)) { G1StringDedupQueue::push(worker_id, java_string); } diff --git a/src/hotspot/share/gc/g1/g1StringDedup.hpp b/src/hotspot/share/gc/g1/g1StringDedup.hpp index 7c0d3e46eaf..2f03a890ca6 100644 --- a/src/hotspot/share/gc/g1/g1StringDedup.hpp +++ b/src/hotspot/share/gc/g1/g1StringDedup.hpp @@ -65,8 +65,8 @@ class G1StringDedup : public StringDedup { // Candidate selection policies, returns true if the given object is // candidate for string deduplication. - static bool is_candidate_from_mark(oop obj); - static bool is_candidate_from_evacuation(bool from_young, bool to_young, oop obj); + static bool is_candidate_from_mark(oop java_string); + static bool is_candidate_from_evacuation(bool from_young, bool to_young, oop java_string); public: // Initialize string deduplication. @@ -75,6 +75,7 @@ class G1StringDedup : public StringDedup { // Enqueues a deduplication candidate for later processing by the deduplication // thread. Before enqueuing, these functions apply the appropriate candidate // selection policy to filters out non-candidates. + // Precondition for both is that java_string is a String. static void enqueue_from_mark(oop java_string, uint worker_id); static void enqueue_from_evacuation(bool from_young, bool to_young, unsigned int queue, oop java_string); diff --git a/src/hotspot/share/gc/parallel/psPromotionLAB.inline.hpp b/src/hotspot/share/gc/parallel/psPromotionLAB.inline.hpp index 1c883058310..b852324e877 100644 --- a/src/hotspot/share/gc/parallel/psPromotionLAB.inline.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionLAB.inline.hpp @@ -32,20 +32,14 @@ HeapWord* PSYoungPromotionLAB::allocate(size_t size) { // Can't assert this, when young fills, we keep the LAB around, but flushed. // assert(_state != flushed, "Sanity"); - HeapWord* obj = CollectedHeap::align_allocation_or_fail(top(), end(), SurvivorAlignmentInBytes); - if (obj == NULL) { - return NULL; - } - + HeapWord* obj = top(); HeapWord* new_top = obj + size; // The 'new_top>obj' check is needed to detect overflow of obj+size. if (new_top > obj && new_top <= end()) { set_top(new_top); - assert(is_aligned(obj, SurvivorAlignmentInBytes) && is_object_aligned(new_top), - "checking alignment"); + assert(is_object_aligned(new_top), "checking alignment"); return obj; } else { - set_top(obj); return NULL; } } diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp index 2fe070f7ee4..296415542ad 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.cpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp @@ -711,7 +711,7 @@ oop DefNewGeneration::copy_to_survivor_space(oop old) { // Try allocating obj in to-space (unless too old) if (old->age() < tenuring_threshold()) { - obj = (oop) to()->allocate_aligned(s); + obj = (oop) to()->allocate(s); } // Otherwise try allocating obj tenured diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp index 0ab0df117af..d8223a69f12 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.hpp +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp @@ -311,12 +311,6 @@ class CollectedHeap : public CHeapObj { virtual size_t min_dummy_object_size() const; size_t tlab_alloc_reserve() const; - // Return the address "addr" aligned by "alignment_in_bytes" if such - // an address is below "end". Return NULL otherwise. - inline static HeapWord* align_allocation_or_fail(HeapWord* addr, - HeapWord* end, - unsigned short alignment_in_bytes); - // Some heaps may offer a contiguous region for shared non-blocking // allocation, via inlined code (by exporting the address of the top and // end fields defining the extent of the contiguous allocation region.) diff --git a/src/hotspot/share/gc/shared/collectedHeap.inline.hpp b/src/hotspot/share/gc/shared/collectedHeap.inline.hpp index f68179aac3c..7d1cbb08756 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.inline.hpp +++ b/src/hotspot/share/gc/shared/collectedHeap.inline.hpp @@ -30,43 +30,6 @@ #include "oops/oop.inline.hpp" #include "utilities/align.hpp" -inline HeapWord* CollectedHeap::align_allocation_or_fail(HeapWord* addr, - HeapWord* end, - unsigned short alignment_in_bytes) { - if (alignment_in_bytes <= ObjectAlignmentInBytes) { - return addr; - } - - assert(is_aligned(addr, HeapWordSize), - "Address " PTR_FORMAT " is not properly aligned.", p2i(addr)); - assert(is_aligned(alignment_in_bytes, HeapWordSize), - "Alignment size %u is incorrect.", alignment_in_bytes); - - HeapWord* new_addr = align_up(addr, alignment_in_bytes); - size_t padding = pointer_delta(new_addr, addr); - - if (padding == 0) { - return addr; - } - - if (padding < CollectedHeap::min_fill_size()) { - padding += alignment_in_bytes / HeapWordSize; - assert(padding >= CollectedHeap::min_fill_size(), - "alignment_in_bytes %u is expect to be larger " - "than the minimum object size", alignment_in_bytes); - new_addr = addr + padding; - } - - assert(new_addr > addr, "Unexpected arithmetic overflow " - PTR_FORMAT " not greater than " PTR_FORMAT, p2i(new_addr), p2i(addr)); - if(new_addr < end) { - CollectedHeap::fill_with_object(addr, padding); - return new_addr; - } else { - return NULL; - } -} - inline oop CollectedHeap::obj_allocate(Klass* klass, int size, TRAPS) { ObjAllocator allocator(klass, size, THREAD); return allocator.allocate(); diff --git a/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp b/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp index 32ac7541e43..70043c430b4 100644 --- a/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp +++ b/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.cpp @@ -438,22 +438,3 @@ JVMFlag::Error MaxMetaspaceSizeConstraintFunc(size_t value, bool verbose) { } } -JVMFlag::Error SurvivorAlignmentInBytesConstraintFunc(intx value, bool verbose) { - if (value != 0) { - if (!is_power_of_2(value)) { - JVMFlag::printError(verbose, - "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be " - "power of 2\n", - value); - return JVMFlag::VIOLATES_CONSTRAINT; - } - if (value < ObjectAlignmentInBytes) { - JVMFlag::printError(verbose, - "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be " - "greater than or equal to ObjectAlignmentInBytes (" INTX_FORMAT ")\n", - value, ObjectAlignmentInBytes); - return JVMFlag::VIOLATES_CONSTRAINT; - } - } - return JVMFlag::SUCCESS; -} diff --git a/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.hpp b/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.hpp index 1f9ecbd40f6..5bbfac68b66 100644 --- a/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.hpp +++ b/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.hpp @@ -67,8 +67,7 @@ f(uintx, TLABWasteIncrementConstraintFunc) \ f(uintx, SurvivorRatioConstraintFunc) \ f(size_t, MetaspaceSizeConstraintFunc) \ - f(size_t, MaxMetaspaceSizeConstraintFunc) \ - f(intx, SurvivorAlignmentInBytesConstraintFunc) + f(size_t, MaxMetaspaceSizeConstraintFunc) SHARED_GC_CONSTRAINTS(DECLARE_CONSTRAINT) diff --git a/src/hotspot/share/gc/shared/plab.inline.hpp b/src/hotspot/share/gc/shared/plab.inline.hpp index 38ef672f7c8..b0698da8a33 100644 --- a/src/hotspot/share/gc/shared/plab.inline.hpp +++ b/src/hotspot/share/gc/shared/plab.inline.hpp @@ -30,18 +30,6 @@ #include "memory/allocation.inline.hpp" #include "runtime/atomic.hpp" -inline HeapWord* PLAB::allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes) { - HeapWord* res = CollectedHeap::align_allocation_or_fail(_top, _end, alignment_in_bytes); - if (res == NULL) { - return NULL; - } - - // Set _top so that allocate(), which expects _top to be correctly set, - // can be used below. - _top = res; - return allocate(word_sz); -} - void PLABStats::add_allocated(size_t v) { Atomic::add(&_allocated, v); } diff --git a/src/hotspot/share/gc/shared/pretouchTask.cpp b/src/hotspot/share/gc/shared/pretouchTask.cpp index eb0ffbb5bab..4398d3924cc 100644 --- a/src/hotspot/share/gc/shared/pretouchTask.cpp +++ b/src/hotspot/share/gc/shared/pretouchTask.cpp @@ -28,17 +28,21 @@ #include "runtime/globals.hpp" #include "runtime/os.hpp" -PretouchTask::PretouchTask(const char* task_name, char* start_address, char* end_address, size_t page_size) : +PretouchTask::PretouchTask(const char* task_name, + char* start_address, + char* end_address, + size_t page_size, + size_t chunk_size) : AbstractGangTask(task_name), _cur_addr(start_address), _start_addr(start_address), _end_addr(end_address), - _page_size(0) { -#ifdef LINUX - _page_size = UseTransparentHugePages ? (size_t)os::vm_page_size(): page_size; -#else - _page_size = page_size; -#endif + _page_size(page_size), + _chunk_size(chunk_size) { + + assert(chunk_size >= page_size, + "Chunk size " SIZE_FORMAT " is smaller than page size " SIZE_FORMAT, + chunk_size, page_size); } size_t PretouchTask::chunk_size() { @@ -46,15 +50,13 @@ size_t PretouchTask::chunk_size() { } void PretouchTask::work(uint worker_id) { - size_t const actual_chunk_size = MAX2(chunk_size(), _page_size); - while (true) { - char* touch_addr = Atomic::fetch_and_add(&_cur_addr, actual_chunk_size); + char* touch_addr = Atomic::fetch_and_add(&_cur_addr, _chunk_size); if (touch_addr < _start_addr || touch_addr >= _end_addr) { break; } - char* end_addr = touch_addr + MIN2(actual_chunk_size, pointer_delta(_end_addr, touch_addr, sizeof(char))); + char* end_addr = touch_addr + MIN2(_chunk_size, pointer_delta(_end_addr, touch_addr, sizeof(char))); os::pretouch_memory(touch_addr, end_addr, _page_size); } @@ -62,13 +64,25 @@ void PretouchTask::work(uint worker_id) { void PretouchTask::pretouch(const char* task_name, char* start_address, char* end_address, size_t page_size, WorkGang* pretouch_gang) { - PretouchTask task(task_name, start_address, end_address, page_size); + +#ifdef LINUX + // When using THP we need to always pre-touch using small pages as the OS will + // initially always use small pages. + page_size = UseTransparentHugePages ? (size_t)os::vm_page_size() : page_size; +#endif + size_t chunk_size = MAX2(PretouchTask::chunk_size(), page_size); + + PretouchTask task(task_name, start_address, end_address, page_size, chunk_size); size_t total_bytes = pointer_delta(end_address, start_address, sizeof(char)); + if (total_bytes == 0) { + return; + } + if (pretouch_gang != NULL) { - size_t num_chunks = MAX2((size_t)1, total_bytes / MAX2(PretouchTask::chunk_size(), page_size)); + size_t num_chunks = (total_bytes + chunk_size - 1) / chunk_size; - uint num_workers = MIN2((uint)num_chunks, pretouch_gang->total_workers()); + uint num_workers = (uint)MIN2(num_chunks, (size_t)pretouch_gang->total_workers()); log_debug(gc, heap)("Running %s with %u workers for " SIZE_FORMAT " work units pre-touching " SIZE_FORMAT "B.", task.name(), num_workers, num_chunks, total_bytes); diff --git a/src/hotspot/share/gc/shared/pretouchTask.hpp b/src/hotspot/share/gc/shared/pretouchTask.hpp index 1883afa7c48..49cd48dc9cf 100644 --- a/src/hotspot/share/gc/shared/pretouchTask.hpp +++ b/src/hotspot/share/gc/shared/pretouchTask.hpp @@ -32,9 +32,10 @@ class PretouchTask : public AbstractGangTask { char* const _start_addr; char* const _end_addr; size_t _page_size; + size_t _chunk_size; public: - PretouchTask(const char* task_name, char* start_address, char* end_address, size_t page_size); + PretouchTask(const char* task_name, char* start_address, char* end_address, size_t page_size, size_t chunk_size); virtual void work(uint worker_id); diff --git a/src/hotspot/share/gc/shared/referenceProcessor.cpp b/src/hotspot/share/gc/shared/referenceProcessor.cpp index 820839dae61..d634ffa9efd 100644 --- a/src/hotspot/share/gc/shared/referenceProcessor.cpp +++ b/src/hotspot/share/gc/shared/referenceProcessor.cpp @@ -262,7 +262,7 @@ void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) { _next_discovered = discovered; _referent_addr = java_lang_ref_Reference::referent_addr_raw(_current_discovered); - _referent = java_lang_ref_Reference::referent(_current_discovered); + _referent = java_lang_ref_Reference::unknown_referent_no_keepalive(_current_discovered); assert(Universe::heap()->is_in_or_null(_referent), "Wrong oop found in java.lang.Reference object"); assert(allow_null_referent ? @@ -1058,7 +1058,7 @@ ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list, // cleared concurrently by mutators during (or after) discovery. void ReferenceProcessor::verify_referent(oop obj) { bool da = discovery_is_atomic(); - oop referent = java_lang_ref_Reference::referent(obj); + oop referent = java_lang_ref_Reference::unknown_referent_no_keepalive(obj); assert(da ? oopDesc::is_oop(referent) : oopDesc::is_oop_or_null(referent), "Bad referent " INTPTR_FORMAT " found in Reference " INTPTR_FORMAT " during %satomic discovery ", @@ -1119,7 +1119,8 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) { // known to be strongly reachable. if (is_alive_non_header() != NULL) { verify_referent(obj); - if (is_alive_non_header()->do_object_b(java_lang_ref_Reference::referent(obj))) { + oop referent = java_lang_ref_Reference::unknown_referent_no_keepalive(obj); + if (is_alive_non_header()->do_object_b(referent)) { return false; // referent is reachable } } @@ -1169,7 +1170,7 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) { // .. we are an atomic collector and referent is in our span if (is_subject_to_discovery(obj) || (discovery_is_atomic() && - is_subject_to_discovery(java_lang_ref_Reference::referent(obj)))) { + is_subject_to_discovery(java_lang_ref_Reference::unknown_referent_no_keepalive(obj)))) { } else { return false; } diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp index c267f1c0c3e..7b099a7d01a 100644 --- a/src/hotspot/share/gc/shared/space.cpp +++ b/src/hotspot/share/gc/shared/space.cpp @@ -567,27 +567,6 @@ inline HeapWord* ContiguousSpace::par_allocate_impl(size_t size) { } while (true); } -HeapWord* ContiguousSpace::allocate_aligned(size_t size) { - assert(Heap_lock->owned_by_self() || (SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread()), "not locked"); - HeapWord* end_value = end(); - - HeapWord* obj = CollectedHeap::align_allocation_or_fail(top(), end_value, SurvivorAlignmentInBytes); - if (obj == NULL) { - return NULL; - } - - if (pointer_delta(end_value, obj) >= size) { - HeapWord* new_top = obj + size; - set_top(new_top); - assert(::is_aligned(obj, SurvivorAlignmentInBytes) && is_aligned(new_top), - "checking alignment"); - return obj; - } else { - set_top(obj); - return NULL; - } -} - // Requires locking. HeapWord* ContiguousSpace::allocate(size_t size) { return allocate_impl(size); diff --git a/src/hotspot/share/gc/shared/space.hpp b/src/hotspot/share/gc/shared/space.hpp index 0b760364bbc..48eadafaf80 100644 --- a/src/hotspot/share/gc/shared/space.hpp +++ b/src/hotspot/share/gc/shared/space.hpp @@ -560,7 +560,6 @@ class ContiguousSpace: public CompactibleSpace { // Allocation (return NULL if full) virtual HeapWord* allocate(size_t word_size); virtual HeapWord* par_allocate(size_t word_size); - HeapWord* allocate_aligned(size_t word_size); // Iteration void oop_iterate(OopIterateClosure* cl); diff --git a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp index 9754f495034..f0c034d1401 100644 --- a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp +++ b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp @@ -51,7 +51,9 @@ void ShenandoahLoadReferenceBarrierStub::emit_code(LIR_Assembler* ce) { ShenandoahBarrierSetC1::ShenandoahBarrierSetC1() : _pre_barrier_c1_runtime_code_blob(NULL), - _load_reference_barrier_rt_code_blob(NULL) {} + _load_reference_barrier_normal_rt_code_blob(NULL), + _load_reference_barrier_native_rt_code_blob(NULL), + _load_reference_barrier_weak_rt_code_blob(NULL) {} void ShenandoahBarrierSetC1::pre_barrier(LIRGenerator* gen, CodeEmitInfo* info, DecoratorSet decorators, LIR_Opr addr_opr, LIR_Opr pre_val) { // First we test whether marking is in progress. @@ -107,15 +109,15 @@ void ShenandoahBarrierSetC1::pre_barrier(LIRGenerator* gen, CodeEmitInfo* info, __ branch_destination(slow->continuation()); } -LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier(LIRGenerator* gen, LIR_Opr obj, LIR_Opr addr, bool is_native) { +LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier(LIRGenerator* gen, LIR_Opr obj, LIR_Opr addr, ShenandoahBarrierSet::AccessKind kind) { if (ShenandoahLoadRefBarrier) { - return load_reference_barrier_impl(gen, obj, addr, is_native); + return load_reference_barrier_impl(gen, obj, addr, kind); } else { return obj; } } -LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj, LIR_Opr addr, bool is_native) { +LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj, LIR_Opr addr, ShenandoahBarrierSet::AccessKind kind) { assert(ShenandoahLoadRefBarrier, "Should be enabled"); obj = ensure_in_register(gen, obj, T_OBJECT); @@ -148,7 +150,7 @@ LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, L } __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0)); - CodeStub* slow = new ShenandoahLoadReferenceBarrierStub(obj, addr, result, tmp1, tmp2, is_native); + CodeStub* slow = new ShenandoahLoadReferenceBarrierStub(obj, addr, result, tmp1, tmp2, kind); __ branch(lir_cond_notEqual, slow); __ branch_destination(slow->continuation()); @@ -211,8 +213,8 @@ void ShenandoahBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) { LIR_Opr tmp = gen->new_register(T_OBJECT); BarrierSetC1::load_at_resolved(access, tmp); - bool is_native = ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type); - tmp = load_reference_barrier(gen, tmp, access.resolved_addr(), is_native); + ShenandoahBarrierSet::AccessKind kind = ShenandoahBarrierSet::access_kind(decorators, type); + tmp = load_reference_barrier(gen, tmp, access.resolved_addr(), kind); __ move(tmp, result); } else { BarrierSetC1::load_at_resolved(access, result); @@ -251,14 +253,14 @@ class C1ShenandoahPreBarrierCodeGenClosure : public StubAssemblerCodeGenClosure class C1ShenandoahLoadReferenceBarrierCodeGenClosure : public StubAssemblerCodeGenClosure { private: - const bool _is_native; + const ShenandoahBarrierSet::AccessKind _kind; public: - C1ShenandoahLoadReferenceBarrierCodeGenClosure(bool is_native) : _is_native(is_native) {} + C1ShenandoahLoadReferenceBarrierCodeGenClosure(ShenandoahBarrierSet::AccessKind kind) : _kind(kind) {} virtual OopMapSet* generate_code(StubAssembler* sasm) { ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); - bs->generate_c1_load_reference_barrier_runtime_stub(sasm, _is_native); + bs->generate_c1_load_reference_barrier_runtime_stub(sasm, _kind); return NULL; } }; @@ -269,14 +271,19 @@ void ShenandoahBarrierSetC1::generate_c1_runtime_stubs(BufferBlob* buffer_blob) "shenandoah_pre_barrier_slow", false, &pre_code_gen_cl); if (ShenandoahLoadRefBarrier) { - C1ShenandoahLoadReferenceBarrierCodeGenClosure lrb_code_gen_cl(false); - _load_reference_barrier_rt_code_blob = Runtime1::generate_blob(buffer_blob, -1, + C1ShenandoahLoadReferenceBarrierCodeGenClosure lrb_code_gen_cl(ShenandoahBarrierSet::AccessKind::NORMAL); + _load_reference_barrier_normal_rt_code_blob = Runtime1::generate_blob(buffer_blob, -1, "shenandoah_load_reference_barrier_slow", false, &lrb_code_gen_cl); - C1ShenandoahLoadReferenceBarrierCodeGenClosure lrb_native_code_gen_cl(true); + C1ShenandoahLoadReferenceBarrierCodeGenClosure lrb_native_code_gen_cl(ShenandoahBarrierSet::AccessKind::NATIVE); _load_reference_barrier_native_rt_code_blob = Runtime1::generate_blob(buffer_blob, -1, - "shenandoah_load_reference_barrier_native_slow", - false, &lrb_native_code_gen_cl); + "shenandoah_load_reference_barrier_native_slow", + false, &lrb_native_code_gen_cl); + + C1ShenandoahLoadReferenceBarrierCodeGenClosure lrb_weak_code_gen_cl(ShenandoahBarrierSet::AccessKind::WEAK); + _load_reference_barrier_weak_rt_code_blob = Runtime1::generate_blob(buffer_blob, -1, + "shenandoah_load_reference_barrier_weak_slow", + false, &lrb_weak_code_gen_cl); } } diff --git a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.hpp b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.hpp index e97f3af0926..eb65475e609 100644 --- a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.hpp +++ b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.hpp @@ -94,10 +94,10 @@ class ShenandoahLoadReferenceBarrierStub: public CodeStub { LIR_Opr _result; LIR_Opr _tmp1; LIR_Opr _tmp2; - bool _is_native; + ShenandoahBarrierSet::AccessKind _kind; public: - ShenandoahLoadReferenceBarrierStub(LIR_Opr obj, LIR_Opr addr, LIR_Opr result, LIR_Opr tmp1, LIR_Opr tmp2, bool is_native) : - _obj(obj), _addr(addr), _result(result), _tmp1(tmp1), _tmp2(tmp2), _is_native(is_native) + ShenandoahLoadReferenceBarrierStub(LIR_Opr obj, LIR_Opr addr, LIR_Opr result, LIR_Opr tmp1, LIR_Opr tmp2, ShenandoahBarrierSet::AccessKind kind) : + _obj(obj), _addr(addr), _result(result), _tmp1(tmp1), _tmp2(tmp2), _kind(kind) { assert(_obj->is_register(), "should be register"); assert(_addr->is_register(), "should be register"); @@ -111,7 +111,7 @@ class ShenandoahLoadReferenceBarrierStub: public CodeStub { LIR_Opr result() const { return _result; } LIR_Opr tmp1() const { return _tmp1; } LIR_Opr tmp2() const { return _tmp2; } - bool is_native() const { return _is_native; } + ShenandoahBarrierSet::AccessKind kind() const { return _kind; } virtual void emit_code(LIR_Assembler* e); virtual void visit(LIR_OpVisitState* visitor) { @@ -190,15 +190,16 @@ class LIR_OpShenandoahCompareAndSwap : public LIR_Op { class ShenandoahBarrierSetC1 : public BarrierSetC1 { private: CodeBlob* _pre_barrier_c1_runtime_code_blob; - CodeBlob* _load_reference_barrier_rt_code_blob; + CodeBlob* _load_reference_barrier_normal_rt_code_blob; CodeBlob* _load_reference_barrier_native_rt_code_blob; + CodeBlob* _load_reference_barrier_weak_rt_code_blob; void pre_barrier(LIRGenerator* gen, CodeEmitInfo* info, DecoratorSet decorators, LIR_Opr addr_opr, LIR_Opr pre_val); - LIR_Opr load_reference_barrier(LIRGenerator* gen, LIR_Opr obj, LIR_Opr addr, bool is_native); + LIR_Opr load_reference_barrier(LIRGenerator* gen, LIR_Opr obj, LIR_Opr addr, ShenandoahBarrierSet::AccessKind kind); LIR_Opr storeval_barrier(LIRGenerator* gen, LIR_Opr obj, CodeEmitInfo* info, DecoratorSet decorators); - LIR_Opr load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj, LIR_Opr addr, bool is_native); + LIR_Opr load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj, LIR_Opr addr, ShenandoahBarrierSet::AccessKind kind); LIR_Opr ensure_in_register(LIRGenerator* gen, LIR_Opr obj, BasicType type); @@ -210,15 +211,20 @@ class ShenandoahBarrierSetC1 : public BarrierSetC1 { return _pre_barrier_c1_runtime_code_blob; } - CodeBlob* load_reference_barrier_rt_code_blob() { - assert(_load_reference_barrier_rt_code_blob != NULL, ""); - return _load_reference_barrier_rt_code_blob; + CodeBlob* load_reference_barrier_normal_rt_code_blob() { + assert(_load_reference_barrier_normal_rt_code_blob != NULL, ""); + return _load_reference_barrier_normal_rt_code_blob; } CodeBlob* load_reference_barrier_native_rt_code_blob() { assert(_load_reference_barrier_native_rt_code_blob != NULL, ""); return _load_reference_barrier_native_rt_code_blob; } + + CodeBlob* load_reference_barrier_weak_rt_code_blob() { + assert(_load_reference_barrier_weak_rt_code_blob != NULL, ""); + return _load_reference_barrier_weak_rt_code_blob; + } protected: virtual void store_at_resolved(LIRAccess& access, LIR_Opr value); diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp index 53feeff68f9..d022cc241f0 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp @@ -305,7 +305,8 @@ bool ShenandoahBarrierSetC2::is_shenandoah_lrb_call(Node* call) { address entry_point = call->as_CallLeaf()->entry_point(); return (entry_point == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier)) || (entry_point == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow)) || - (entry_point == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)); + (entry_point == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak)) || + (entry_point == CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak_narrow)); } bool ShenandoahBarrierSetC2::is_shenandoah_marking_if(PhaseTransform *phase, Node* n) { @@ -545,9 +546,8 @@ Node* ShenandoahBarrierSetC2::load_at_resolved(C2Access& access, const Type* val // 2: apply LRB if needed if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) { - load = new ShenandoahLoadReferenceBarrierNode(NULL, - load, - ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type)); + ShenandoahBarrierSet::AccessKind kind = ShenandoahBarrierSet::access_kind(decorators, type); + load = new ShenandoahLoadReferenceBarrierNode(NULL, load, kind); if (access.is_parse_access()) { load = static_cast(access).kit()->gvn().transform(load); } else { @@ -644,7 +644,7 @@ Node* ShenandoahBarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess load_store = kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type())); } #endif - load_store = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, load_store, false)); + load_store = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, load_store, ShenandoahBarrierSet::AccessKind::NORMAL)); return load_store; } return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); @@ -712,7 +712,7 @@ Node* ShenandoahBarrierSetC2::atomic_xchg_at_resolved(C2AtomicParseAccess& acces } Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, val, value_type); if (access.is_oop()) { - result = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, result, false)); + result = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, result, ShenandoahBarrierSet::AccessKind::NORMAL)); shenandoah_write_barrier_pre(kit, false /* do_load */, NULL, NULL, max_juint, NULL, NULL, result /* pre_val */, T_OBJECT); @@ -1059,14 +1059,19 @@ Node* ShenandoahBarrierSetC2::ideal_node(PhaseGVN* phase, Node* n, bool can_resh if (n->Opcode() == Op_CmpP) { Node* in1 = n->in(1); Node* in2 = n->in(2); + + // If one input is NULL, then step over the barriers normal LRB barriers on the other input if (in1->bottom_type() == TypePtr::NULL_PTR && - (in1->Opcode() != Op_ShenandoahLoadReferenceBarrier || !((ShenandoahLoadReferenceBarrierNode*)in1)->is_native())) { + !((in2->Opcode() == Op_ShenandoahLoadReferenceBarrier) && + ((ShenandoahLoadReferenceBarrierNode*)in2)->kind() != ShenandoahBarrierSet::AccessKind::NORMAL)) { in2 = step_over_gc_barrier(in2); } if (in2->bottom_type() == TypePtr::NULL_PTR && - (in2->Opcode() != Op_ShenandoahLoadReferenceBarrier || !((ShenandoahLoadReferenceBarrierNode*)in2)->is_native())) { + !((in1->Opcode() == Op_ShenandoahLoadReferenceBarrier) && + ((ShenandoahLoadReferenceBarrierNode*)in1)->kind() != ShenandoahBarrierSet::AccessKind::NORMAL)) { in1 = step_over_gc_barrier(in1); } + PhaseIterGVN* igvn = phase->is_IterGVN(); if (in1 != n->in(1)) { if (igvn != NULL) { diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp index 6b83c9773b2..9e51e9fbad1 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp @@ -955,7 +955,8 @@ void ShenandoahBarrierC2Support::test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, phase->register_new_node(cset_bool, old_ctrl); } -void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase) { +void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, + ShenandoahBarrierSet::AccessKind kind, PhaseIdealLoop* phase) { IdealLoopTree*loop = phase->get_loop(ctrl); const TypePtr* obj_type = phase->igvn().type(val)->is_oopptr(); @@ -966,13 +967,28 @@ void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node* lo mm->set_memory_at(Compile::AliasIdxRaw, raw_mem); phase->register_new_node(mm, ctrl); - address target = LP64_ONLY(UseCompressedOops) NOT_LP64(false) ? - CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow) : - CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier); - - address calladdr = is_native ? CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native) - : target; - const char* name = is_native ? "load_reference_barrier_native" : "load_reference_barrier"; + address calladdr = NULL; + const char* name = NULL; + switch (kind) { + case ShenandoahBarrierSet::AccessKind::NATIVE: + calladdr = CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak); + name = "load_reference_barrier_native"; + break; + case ShenandoahBarrierSet::AccessKind::WEAK: + calladdr = LP64_ONLY(UseCompressedOops) NOT_LP64(false) ? + CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak_narrow) : + CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak); + name = "load_reference_barrier_weak"; + break; + case ShenandoahBarrierSet::AccessKind::NORMAL: + calladdr = LP64_ONLY(UseCompressedOops) NOT_LP64(false) ? + CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow) : + CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier); + name = "load_reference_barrier"; + break; + default: + ShouldNotReachHere(); + } Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), calladdr, name, TypeRawPtr::BOTTOM); call->init_req(TypeFunc::Control, ctrl); @@ -1335,7 +1351,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) { // even for non-cset objects to prevent ressurrection of such objects. // Wires !in_cset(obj) to slot 2 of region and phis Node* not_cset_ctrl = NULL; - if (!lrb->is_native()) { + if (lrb->kind() == ShenandoahBarrierSet::AccessKind::NORMAL) { test_in_cset(ctrl, not_cset_ctrl, val, raw_mem, phase); } if (not_cset_ctrl != NULL) { @@ -1386,7 +1402,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) { } } } - call_lrb_stub(ctrl, val, addr, result_mem, raw_mem, lrb->is_native(), phase); + call_lrb_stub(ctrl, val, addr, result_mem, raw_mem, lrb->kind(), phase); region->init_req(_evac_path, ctrl); val_phi->init_req(_evac_path, val); raw_mem_phi->init_req(_evac_path, result_mem); @@ -2311,12 +2327,12 @@ void MemoryGraphFixer::collect_memory_nodes() { Node* m = _memory_nodes[c->in(k)->_idx]; assert(m != NULL, "expect memory state"); if (u->in(k) != m) { - phi = NULL; + phi = NodeSentinel; } } } } - if (phi == NULL) { + if (phi == NodeSentinel) { phi = new PhiNode(c, Type::MEMORY, _phase->C->get_adr_type(_alias)); for (uint k = 1; k < c->req(); k++) { Node* m = _memory_nodes[c->in(k)->_idx]; @@ -2325,8 +2341,11 @@ void MemoryGraphFixer::collect_memory_nodes() { } } } - assert(phi != NULL, ""); - regions.map(c->_idx, phi); + if (phi != NULL) { + regions.map(c->_idx, phi); + } else { + assert(c->unique_ctrl_out()->Opcode() == Op_Halt, "expected memory state"); + } } Node* current_region = regions[c->_idx]; if (current_region != prev_region) { @@ -2337,7 +2356,7 @@ void MemoryGraphFixer::collect_memory_nodes() { } } else if (prev_mem == NULL || prev_mem->is_Phi() || ctrl_or_self(prev_mem) != c) { Node* m = _memory_nodes[_phase->idom(c)->_idx]; - assert(m != NULL, "expect memory state"); + assert(m != NULL || c->Opcode() == Op_Halt, "expect memory state"); if (m != prev_mem) { _memory_nodes.map(c->_idx, m); progress = true; @@ -2361,7 +2380,8 @@ void MemoryGraphFixer::collect_memory_nodes() { Node* c = rpo_list.at(i); if (c->is_Region() && (_include_lsm || !c->is_OuterStripMinedLoop())) { Node* n = regions[c->_idx]; - if (n->is_Phi() && n->_idx >= last && n->in(0) == c) { + assert(n != NULL || c->unique_ctrl_out()->Opcode() == Op_Halt, "expected memory state"); + if (n != NULL && n->is_Phi() && n->_idx >= last && n->in(0) == c) { _phase->register_new_node(n, c); } } @@ -2370,10 +2390,12 @@ void MemoryGraphFixer::collect_memory_nodes() { Node* c = rpo_list.at(i); if (c->is_Region() && (_include_lsm || !c->is_OuterStripMinedLoop())) { Node* n = regions[c->_idx]; + assert(n != NULL || c->unique_ctrl_out()->Opcode() == Op_Halt, "expected memory state"); for (DUIterator_Fast imax, i = c->fast_outs(imax); i < imax; i++) { Node* u = c->fast_out(i); if (u->is_Phi() && u->bottom_type() == Type::MEMORY && u != n) { + assert(c->unique_ctrl_out()->Opcode() != Op_Halt, "expected memory state"); if (u->adr_type() == TypePtr::BOTTOM) { fix_memory_uses(u, n, n, c); } else if (_phase->C->get_alias_index(u->adr_type()) == _alias) { @@ -2875,13 +2897,13 @@ void MemoryGraphFixer::fix_memory_uses(Node* mem, Node* replacement, Node* rep_p } } -ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj, bool native) -: Node(ctrl, obj), _native(native) { +ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj, ShenandoahBarrierSet::AccessKind kind) +: Node(ctrl, obj), _kind(kind) { ShenandoahBarrierSetC2::bsc2()->state()->add_load_reference_barrier(this); } -bool ShenandoahLoadReferenceBarrierNode::is_native() const { - return _native; +ShenandoahBarrierSet::AccessKind ShenandoahLoadReferenceBarrierNode::kind() const { + return _kind; } uint ShenandoahLoadReferenceBarrierNode::size_of() const { @@ -2889,12 +2911,26 @@ uint ShenandoahLoadReferenceBarrierNode::size_of() const { } uint ShenandoahLoadReferenceBarrierNode::hash() const { - return Node::hash() + (_native ? 1 : 0); + uint hash = Node::hash(); + switch (_kind) { + case ShenandoahBarrierSet::AccessKind::NORMAL: + hash += 0; + break; + case ShenandoahBarrierSet::AccessKind::WEAK: + hash += 1; + break; + case ShenandoahBarrierSet::AccessKind::NATIVE: + hash += 2; + break; + default: + ShouldNotReachHere(); + } + return hash; } bool ShenandoahLoadReferenceBarrierNode::cmp( const Node &n ) const { return Node::cmp(n) && n.Opcode() == Op_ShenandoahLoadReferenceBarrier && - _native == ((const ShenandoahLoadReferenceBarrierNode&)n)._native; + _kind == ((const ShenandoahLoadReferenceBarrierNode&)n)._kind; } const Type* ShenandoahLoadReferenceBarrierNode::bottom_type() const { diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp index 91c8d167abf..c07b4a1ed72 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_GC_SHENANDOAH_C2_SHENANDOAHSUPPORT_HPP #define SHARE_GC_SHENANDOAH_C2_SHENANDOAHSUPPORT_HPP +#include "gc/shenandoah/shenandoahBarrierSet.hpp" #include "memory/allocation.hpp" #include "opto/addnode.hpp" #include "opto/graphKit.hpp" @@ -60,7 +61,8 @@ class ShenandoahBarrierC2Support : public AllStatic { static void test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase); static void test_gc_state(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl, PhaseIdealLoop* phase, int flags); - static void call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase); + static void call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, + ShenandoahBarrierSet::AccessKind kind, PhaseIdealLoop* phase); static void test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase); static void move_gc_state_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase); static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase); @@ -229,12 +231,12 @@ class ShenandoahLoadReferenceBarrierNode : public Node { }; private: - bool _native; + ShenandoahBarrierSet::AccessKind _kind; public: - ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val, bool native); + ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val, ShenandoahBarrierSet::AccessKind kind); - bool is_native() const; + ShenandoahBarrierSet::AccessKind kind() const; virtual int Opcode() const; virtual const Type* bottom_type() const; virtual const Type* Value(PhaseGVN* phase) const; diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp index 72eba58baa3..dccc0e9e6b5 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp @@ -61,12 +61,6 @@ bool ShenandoahAggressiveHeuristics::should_start_gc() const { return true; } -bool ShenandoahAggressiveHeuristics::should_process_references() { - if (!can_process_references()) return false; - // Randomly process refs with 50% chance. - return (os::random() & 1) == 1; -} - bool ShenandoahAggressiveHeuristics::should_unload_classes() { if (!can_unload_classes_normal()) return false; if (has_metaspace_oom()) return true; diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp index 071b3be8ff6..46956e40ca9 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp @@ -37,8 +37,6 @@ class ShenandoahAggressiveHeuristics : public ShenandoahHeuristics { virtual bool should_start_gc() const; - virtual bool should_process_references(); - virtual bool should_unload_classes(); virtual const char* name() { return "Aggressive"; } diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp index 4ce2366fe0c..7027082cbc1 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp @@ -257,18 +257,6 @@ void ShenandoahHeuristics::record_requested_gc() { _gc_times_learned = 0; } -bool ShenandoahHeuristics::can_process_references() { - if (ShenandoahRefProcFrequency == 0) return false; - return true; -} - -bool ShenandoahHeuristics::should_process_references() { - if (!can_process_references()) return false; - size_t cycle = ShenandoahHeap::heap()->shenandoah_policy()->cycle_counter(); - // Process references every Nth GC cycle. - return cycle % ShenandoahRefProcFrequency == 0; -} - bool ShenandoahHeuristics::can_unload_classes() { if (!ClassUnloading) return false; return true; diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp index 573b2585ce0..fed9296d667 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp @@ -120,9 +120,6 @@ class ShenandoahHeuristics : public CHeapObj { virtual void choose_collection_set(ShenandoahCollectionSet* collection_set); - virtual bool can_process_references(); - virtual bool should_process_references(); - virtual bool can_unload_classes(); virtual bool can_unload_classes_normal(); virtual bool should_unload_classes(); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp index d8027af7105..e13f9321898 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp @@ -36,11 +36,6 @@ bool ShenandoahPassiveHeuristics::should_start_gc() const { return false; } -bool ShenandoahPassiveHeuristics::should_process_references() { - // Always process references, if we can. - return can_process_references(); -} - bool ShenandoahPassiveHeuristics::should_unload_classes() { // Always unload classes, if we can. return can_unload_classes(); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp index 752b0be4dcd..1f259549fdc 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp @@ -31,8 +31,6 @@ class ShenandoahPassiveHeuristics : public ShenandoahHeuristics { public: virtual bool should_start_gc() const; - virtual bool should_process_references(); - virtual bool should_unload_classes(); virtual bool should_degenerate_cycle(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp index d5cc677786e..27c1f988833 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp @@ -68,7 +68,8 @@ void ShenandoahAsserts::print_obj(ShenandoahMessageBuffer& msg, oop obj) { msg.append(" " PTR_FORMAT " - klass " PTR_FORMAT " %s\n", p2i(obj), p2i(obj->klass()), obj->klass()->external_name()); msg.append(" %3s allocated after mark start\n", ctx->allocated_after_mark_start(obj) ? "" : "not"); msg.append(" %3s after update watermark\n", cast_from_oop(obj) >= r->get_update_watermark() ? "" : "not"); - msg.append(" %3s marked \n", ctx->is_marked(obj) ? "" : "not"); + msg.append(" %3s marked strong\n", ctx->is_marked_strong(obj) ? "" : "not"); + msg.append(" %3s marked weak\n", ctx->is_marked_weak(obj) ? "" : "not"); msg.append(" %3s in collection set\n", heap->in_collection_set(obj) ? "" : "not"); msg.append(" mark:%s\n", mw_ss.as_string()); msg.append(" region: %s", ss.as_string()); @@ -175,6 +176,16 @@ void ShenandoahAsserts::assert_in_heap(void* interior_loc, oop obj, const char * } } +void ShenandoahAsserts::assert_in_heap_or_null(void* interior_loc, oop obj, const char *file, int line) { + ShenandoahHeap* heap = ShenandoahHeap::heap(); + + if (obj != NULL && !heap->is_in(obj)) { + print_failure(_safe_unknown, obj, interior_loc, NULL, "Shenandoah assert_in_heap_or_null failed", + "oop must point to a heap address", + file, line); + } +} + void ShenandoahAsserts::assert_correct(void* interior_loc, oop obj, const char* file, int line) { ShenandoahHeap* heap = ShenandoahHeap::heap(); @@ -343,24 +354,6 @@ void ShenandoahAsserts::print_rp_failure(const char *label, BoolObjectClosure* a report_vm_error(file, line, msg.buffer()); } -void ShenandoahAsserts::assert_rp_isalive_not_installed(const char *file, int line) { - ShenandoahHeap* heap = ShenandoahHeap::heap(); - ReferenceProcessor* rp = heap->ref_processor(); - if (rp->is_alive_non_header() != NULL) { - print_rp_failure("Shenandoah assert_rp_isalive_not_installed failed", rp->is_alive_non_header(), - file, line); - } -} - -void ShenandoahAsserts::assert_rp_isalive_installed(const char *file, int line) { - ShenandoahHeap* heap = ShenandoahHeap::heap(); - ReferenceProcessor* rp = heap->ref_processor(); - if (rp->is_alive_non_header() == NULL) { - print_rp_failure("Shenandoah assert_rp_isalive_installed failed", rp->is_alive_non_header(), - file, line); - } -} - void ShenandoahAsserts::assert_locked_or_shenandoah_safepoint(Mutex* lock, const char* file, int line) { if (ShenandoahSafepoint::is_at_shenandoah_safepoint()) { return; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp index 42d0e60bba3..61779b447d6 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp @@ -54,6 +54,7 @@ class ShenandoahAsserts { const char *file, int line); static void assert_in_heap(void* interior_loc, oop obj, const char* file, int line); + static void assert_in_heap_or_null(void* interior_loc, oop obj, const char* file, int line); static void assert_in_correct_region(void* interior_loc, oop obj, const char* file, int line); static void assert_correct(void* interior_loc, oop obj, const char* file, int line); @@ -64,9 +65,6 @@ class ShenandoahAsserts { static void assert_not_in_cset(void* interior_loc, oop obj, const char* file, int line); static void assert_not_in_cset_loc(void* interior_loc, const char* file, int line); - static void assert_rp_isalive_not_installed(const char *file, int line); - static void assert_rp_isalive_installed(const char *file, int line); - static void assert_locked_or_shenandoah_safepoint(Mutex* lock, const char* file, int line); static void assert_heaplocked(const char* file, int line); @@ -76,6 +74,8 @@ class ShenandoahAsserts { #ifdef ASSERT #define shenandoah_assert_in_heap(interior_loc, obj) \ ShenandoahAsserts::assert_in_heap(interior_loc, obj, __FILE__, __LINE__) +#define shenandoah_assert_in_heap_or_null(interior_loc, obj) \ + ShenandoahAsserts::assert_in_heap_or_null(interior_loc, obj, __FILE__, __LINE__) #define shenandoah_assert_in_correct_region(interior_loc, obj) \ ShenandoahAsserts::assert_in_correct_region(interior_loc, obj, __FILE__, __LINE__) @@ -149,6 +149,7 @@ class ShenandoahAsserts { ShenandoahAsserts::assert_heaplocked_or_safepoint(__FILE__, __LINE__) #else #define shenandoah_assert_in_heap(interior_loc, obj) +#define shenandoah_assert_in_heap_or_null(interior_loc, obj) #define shenandoah_assert_in_correct_region(interior_loc, obj) #define shenandoah_assert_correct_if(interior_loc, obj, condition) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp index dc9dd4ee398..adf349d3b24 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp @@ -87,17 +87,6 @@ bool ShenandoahBarrierSet::need_load_reference_barrier(DecoratorSet decorators, return is_reference_type(type); } -bool ShenandoahBarrierSet::use_load_reference_barrier_native(DecoratorSet decorators, BasicType type) { - assert(need_load_reference_barrier(decorators, type), "Should be subset of LRB"); - assert(is_reference_type(type), "Why we here?"); - // Native load reference barrier is only needed for concurrent root processing - if (!ShenandoahConcurrentRoots::can_do_concurrent_roots()) { - return false; - } - - return (decorators & IN_NATIVE) != 0; -} - bool ShenandoahBarrierSet::need_keep_alive_barrier(DecoratorSet decorators,BasicType type) { if (!ShenandoahSATBBarrier) return false; // Only needed for references @@ -109,38 +98,13 @@ bool ShenandoahBarrierSet::need_keep_alive_barrier(DecoratorSet decorators,Basic return (on_weak_ref || unknown) && keep_alive; } -oop ShenandoahBarrierSet::load_reference_barrier_not_null(oop obj) { - if (ShenandoahLoadRefBarrier && _heap->has_forwarded_objects()) { - return load_reference_barrier_impl(obj); - } else { - return obj; - } -} - -oop ShenandoahBarrierSet::load_reference_barrier(oop obj) { - if (obj != NULL) { - return load_reference_barrier_not_null(obj); - } else { - return obj; - } -} - -oop ShenandoahBarrierSet::load_reference_barrier_impl(oop obj) { - assert(ShenandoahLoadRefBarrier, "should be enabled"); - if (!CompressedOops::is_null(obj)) { - bool evac_in_progress = _heap->is_evacuation_in_progress(); - oop fwd = resolve_forwarded_not_null(obj); - if (evac_in_progress && - _heap->in_collection_set(obj) && - obj == fwd) { - Thread *t = Thread::current(); - ShenandoahEvacOOMScope oom_evac_scope(t); - return _heap->evacuate_object(obj, t); - } else { - return fwd; - } +ShenandoahBarrierSet::AccessKind ShenandoahBarrierSet::access_kind(DecoratorSet decorators, BasicType type) { + if ((decorators & IN_NATIVE) != 0) { + return AccessKind::NATIVE; + } else if ((decorators & (ON_WEAK_OOP_REF | ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF)) != 0) { + return AccessKind::WEAK; } else { - return obj; + return AccessKind::NORMAL; } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp index 32086e80584..bdef782037d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp @@ -33,8 +33,19 @@ class ShenandoahBarrierSetAssembler; class ShenandoahBarrierSet: public BarrierSet { -private: +public: + enum class AccessKind { + // Regular in-heap access on reference fields + NORMAL, + + // Off-heap reference access + NATIVE, + + // In-heap reference access on referent fields of j.l.r.Reference objects + WEAK + }; +private: ShenandoahHeap* _heap; BufferNode::Allocator _satb_mark_queue_buffer_allocator; ShenandoahSATBMarkQueueSet _satb_mark_queue_set; @@ -53,8 +64,8 @@ class ShenandoahBarrierSet: public BarrierSet { } static bool need_load_reference_barrier(DecoratorSet decorators, BasicType type); - static bool use_load_reference_barrier_native(DecoratorSet decorators, BasicType type); static bool need_keep_alive_barrier(DecoratorSet decorators, BasicType type); + static AccessKind access_kind(DecoratorSet decorators, BasicType type); void print_on(outputStream* st) const; @@ -87,14 +98,13 @@ class ShenandoahBarrierSet: public BarrierSet { inline void enqueue(oop obj); - oop load_reference_barrier(oop obj); - oop load_reference_barrier_not_null(oop obj); + inline oop load_reference_barrier(oop obj); template inline oop load_reference_barrier_mutator(oop obj, T* load_addr); - template - inline oop load_reference_barrier_native(oop obj, T* load_addr); + template + inline oop load_reference_barrier(oop obj, T* load_addr); private: template @@ -111,8 +121,6 @@ class ShenandoahBarrierSet: public BarrierSet { template inline void arraycopy_work(T* src, size_t count); - oop load_reference_barrier_impl(oop obj); - inline bool need_bulk_update(HeapWord* dst); public: // Callbacks for runtime accesses. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp index e0fc958404c..bf91b199d99 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp @@ -76,23 +76,47 @@ inline oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj, T* load return fwd; } -template -inline oop ShenandoahBarrierSet::load_reference_barrier_native(oop obj, T* load_addr) { - if (CompressedOops::is_null(obj)) { - return NULL; +inline oop ShenandoahBarrierSet::load_reference_barrier(oop obj) { + if (!ShenandoahLoadRefBarrier) { + return obj; + } + if (_heap->has_forwarded_objects() && + _heap->in_collection_set(obj)) { // Subsumes NULL-check + assert(obj != NULL, "cset check must have subsumed NULL-check"); + oop fwd = resolve_forwarded_not_null(obj); + // TODO: It should not be necessary to check evac-in-progress here. + // We do it for mark-compact, which may have forwarded objects, + // and objects in cset and gets here via runtime barriers. + // We can probably fix this as soon as mark-compact has its own + // marking phase. + if (obj == fwd && _heap->is_evacuation_in_progress()) { + Thread* t = Thread::current(); + ShenandoahEvacOOMScope oom_evac_scope(t); + return _heap->evacuate_object(obj, t); + } + return fwd; } + return obj; +} + +template +inline oop ShenandoahBarrierSet::load_reference_barrier(oop obj, T* load_addr) { - ShenandoahMarkingContext* const marking_context = _heap->marking_context(); - if (_heap->is_concurrent_weak_root_in_progress() && !marking_context->is_marked(obj)) { + // Prevent resurrection of unreachable non-strorg references. + if (!HasDecorator::value && obj != NULL && + _heap->is_concurrent_weak_root_in_progress() && + !_heap->marking_context()->is_marked(obj)) { Thread* thr = Thread::current(); if (thr->is_Java_thread()) { return NULL; } else { + // This path is sometimes (rarely) taken by GC threads. + // See e.g.: https://bugs.openjdk.java.net/browse/JDK-8237874 return obj; } } - oop fwd = load_reference_barrier_not_null(obj); + oop fwd = load_reference_barrier(obj); if (ShenandoahSelfFixing && load_addr != NULL && fwd != obj) { // Since we are here and we know the load address, update the reference. ShenandoahHeap::cas_oop(fwd, load_addr, obj); @@ -128,8 +152,7 @@ inline void ShenandoahBarrierSet::satb_barrier(T *field) { } inline void ShenandoahBarrierSet::satb_enqueue(oop value) { - assert(value != NULL, "checked before"); - if (ShenandoahSATBBarrier && _heap->is_concurrent_mark_in_progress()) { + if (value != NULL && ShenandoahSATBBarrier && _heap->is_concurrent_mark_in_progress()) { enqueue(value); } } @@ -142,7 +165,6 @@ inline void ShenandoahBarrierSet::storeval_barrier(oop obj) { inline void ShenandoahBarrierSet::keep_alive_if_weak(DecoratorSet decorators, oop value) { assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known"); - assert(value != NULL, "checked by caller"); const bool on_strong_oop_ref = (decorators & ON_STRONG_OOP_REF) != 0; const bool peek = (decorators & AS_NO_KEEPALIVE) != 0; if (!peek && !on_strong_oop_ref) { @@ -152,7 +174,6 @@ inline void ShenandoahBarrierSet::keep_alive_if_weak(DecoratorSet decorators, oo template inline void ShenandoahBarrierSet::keep_alive_if_weak(oop value) { - assert(value != NULL, "checked by caller"); assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known"); if (!HasDecorator::value && !HasDecorator::value) { @@ -166,10 +187,8 @@ inline oop ShenandoahBarrierSet::AccessBarrier::oop_loa oop value = Raw::oop_load_not_in_heap(addr); if (value != NULL) { ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set(); - value = bs->load_reference_barrier_native(value, addr); - if (value != NULL) { - bs->keep_alive_if_weak(value); - } + value = bs->load_reference_barrier(value, addr); + bs->keep_alive_if_weak(value); } return value; } @@ -178,23 +197,19 @@ template template inline oop ShenandoahBarrierSet::AccessBarrier::oop_load_in_heap(T* addr) { oop value = Raw::oop_load_in_heap(addr); - if (value != NULL) { - ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set(); - value = bs->load_reference_barrier_not_null(value); - bs->keep_alive_if_weak(value); - } + ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set(); + value = bs->load_reference_barrier(value, addr); + bs->keep_alive_if_weak(value); return value; } template inline oop ShenandoahBarrierSet::AccessBarrier::oop_load_in_heap_at(oop base, ptrdiff_t offset) { oop value = Raw::oop_load_in_heap_at(base, offset); - if (value != NULL) { - ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set(); - value = bs->load_reference_barrier_not_null(value); - bs->keep_alive_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength(base, offset), - value); - } + ShenandoahBarrierSet *const bs = ShenandoahBarrierSet::barrier_set(); + DecoratorSet resolved_decorators = AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength(base, offset); + value = bs->load_reference_barrier(value, AccessInternal::oop_field_addr(base, offset)); + bs->keep_alive_if_weak(resolved_decorators, value); return value; } @@ -202,6 +217,7 @@ template template inline void ShenandoahBarrierSet::AccessBarrier::oop_store_not_in_heap(T* addr, oop value) { shenandoah_assert_marked_if(NULL, value, !CompressedOops::is_null(value) && ShenandoahHeap::heap()->is_evacuation_in_progress()); + shenandoah_assert_not_in_cset_if(addr, value, value != NULL && !ShenandoahHeap::heap()->cancelled_gc()); ShenandoahBarrierSet* const bs = ShenandoahBarrierSet::barrier_set(); bs->storeval_barrier(value); bs->satb_barrier(addr); @@ -239,10 +255,8 @@ inline oop ShenandoahBarrierSet::AccessBarrier::oop_ato // Note: We don't need a keep-alive-barrier here. We already enqueue any loaded reference for SATB anyway, // because it must be the previous value. - if (res != NULL) { - res = ShenandoahBarrierSet::barrier_set()->load_reference_barrier_not_null(res); - bs->satb_enqueue(res); - } + res = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(res); + bs->satb_enqueue(res); return res; } @@ -267,10 +281,8 @@ inline oop ShenandoahBarrierSet::AccessBarrier::oop_ato // Note: We don't need a keep-alive-barrier here. We already enqueue any loaded reference for SATB anyway, // because it must be the previous value. - if (previous != NULL) { - previous = ShenandoahBarrierSet::barrier_set()->load_reference_barrier_not_null(previous); - bs->satb_enqueue(previous); - } + previous = ShenandoahBarrierSet::barrier_set()->load_reference_barrier(previous); + bs->satb_enqueue(previous); return previous; } @@ -328,7 +340,7 @@ void ShenandoahBarrierSet::arraycopy_work(T* src, size_t count) { oop witness = ShenandoahHeap::cas_oop(fwd, elem_ptr, o); obj = fwd; } - if (ENQUEUE && !ctx->is_marked(obj)) { + if (ENQUEUE && !ctx->is_marked_strong(obj)) { queue.enqueue_known_active(obj); } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.inline.hpp index fbb34b808c5..a327524a72d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCollectionSet.inline.hpp @@ -40,12 +40,12 @@ bool ShenandoahCollectionSet::is_in(ShenandoahHeapRegion* r) const { } bool ShenandoahCollectionSet::is_in(oop p) const { - shenandoah_assert_in_heap(NULL, p); + shenandoah_assert_in_heap_or_null(NULL, p); return is_in_loc(cast_from_oop(p)); } bool ShenandoahCollectionSet::is_in_loc(void* p) const { - assert(_heap->is_in(p), "Must be in the heap"); + assert(p == NULL || _heap->is_in(p), "Must be in the heap"); uintx index = ((uintx) p) >> _region_size_bytes_shift; // no need to subtract the bottom of the heap from p, // _biased_cset_map is biased diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp index 815fde581b4..5331ca26d48 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp @@ -31,8 +31,6 @@ #include "gc/shared/weakProcessor.inline.hpp" #include "gc/shared/gcTimer.hpp" #include "gc/shared/gcTrace.hpp" -#include "gc/shared/referenceProcessor.hpp" -#include "gc/shared/referenceProcessorPhaseTimes.hpp" #include "gc/shared/strongRootsScope.hpp" #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp" @@ -40,6 +38,7 @@ #include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp" #include "gc/shenandoah/shenandoahMarkCompact.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" +#include "gc/shenandoah/shenandoahReferenceProcessor.hpp" #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" #include "gc/shenandoah/shenandoahOopClosures.inline.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" @@ -61,7 +60,7 @@ class ShenandoahInitMarkRootsClosure : public OopClosure { template inline void do_oop_work(T* p) { - ShenandoahConcurrentMark::mark_through_ref(p, _heap, _queue, _mark_context); + ShenandoahConcurrentMark::mark_through_ref(p, _heap, _queue, _mark_context, false); } public: @@ -74,11 +73,12 @@ class ShenandoahInitMarkRootsClosure : public OopClosure { void do_oop(oop* p) { do_oop_work(p); } }; -ShenandoahMarkRefsSuperClosure::ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : +ShenandoahMarkRefsSuperClosure::ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) : MetadataVisitingOopIterateClosure(rp), _queue(q), _heap(ShenandoahHeap::heap()), - _mark_context(_heap->marking_context()) + _mark_context(_heap->marking_context()), + _weak(false) { } template @@ -153,14 +153,8 @@ class ShenandoahConcurrentMarkingTask : public AbstractGangTask { ShenandoahConcurrentWorkerSession worker_session(worker_id); ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers); ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id); - ReferenceProcessor* rp; - if (heap->process_references()) { - rp = heap->ref_processor(); - shenandoah_assert_rp_isalive_installed(); - } else { - rp = NULL; - } - + ShenandoahReferenceProcessor* rp = heap->ref_processor(); + assert(rp != NULL, "need reference processor"); _cm->mark_loop(worker_id, _terminator, rp, true, // cancellable ShenandoahStringDedup::is_enabled()); // perform string dedup @@ -206,7 +200,7 @@ class ShenandoahProcessConcurrentRootsTask : public AbstractGangTask { private: ShenandoahConcurrentRootScanner _rs; ShenandoahConcurrentMark* const _cm; - ReferenceProcessor* _rp; + ShenandoahReferenceProcessor* _rp; public: ShenandoahProcessConcurrentRootsTask(ShenandoahConcurrentMark* cm, @@ -222,12 +216,7 @@ ShenandoahProcessConcurrentRootsTask::ShenandoahProcessConcurrentRootsTask(Sh AbstractGangTask("Shenandoah Process Concurrent Roots"), _rs(nworkers, phase), _cm(cm), - _rp(NULL) { - ShenandoahHeap* heap = ShenandoahHeap::heap(); - if (heap->process_references()) { - _rp = heap->ref_processor(); - shenandoah_assert_rp_isalive_installed(); - } + _rp(ShenandoahHeap::heap()->ref_processor()) { } template @@ -253,13 +242,7 @@ class ShenandoahFinalMarkingTask : public AbstractGangTask { ShenandoahHeap* heap = ShenandoahHeap::heap(); ShenandoahParallelWorkerSession worker_session(worker_id); - ReferenceProcessor* rp; - if (heap->process_references()) { - rp = heap->ref_processor(); - shenandoah_assert_rp_isalive_installed(); - } else { - rp = NULL; - } + ShenandoahReferenceProcessor* rp = heap->ref_processor(); // First drain remaining SATB buffers. // Notice that this is not strictly necessary for mark-compact. But since @@ -303,9 +286,12 @@ void ShenandoahConcurrentMark::mark_roots(ShenandoahPhaseTimings::Phase root_pha assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint"); ShenandoahHeap* heap = ShenandoahHeap::heap(); - ShenandoahGCPhase phase(root_phase); + ShenandoahReferenceProcessor* ref_processor = heap->ref_processor(); + ref_processor->reset_thread_locals(); + ref_processor->set_soft_reference_policy(_heap->soft_ref_policy()->should_clear_all_soft_refs()); + WorkGang* workers = heap->workers(); uint nworkers = workers->active_workers(); @@ -407,21 +393,21 @@ void ShenandoahConcurrentMark::initialize(uint workers) { // Mark concurrent roots during concurrent phases class ShenandoahMarkConcurrentRootsTask : public AbstractGangTask { private: - SuspendibleThreadSetJoiner _sts_joiner; + SuspendibleThreadSetJoiner _sts_joiner; ShenandoahConcurrentRootScanner _rs; - ShenandoahObjToScanQueueSet* const _queue_set; - ReferenceProcessor* const _rp; + ShenandoahObjToScanQueueSet* const _queue_set; + ShenandoahReferenceProcessor* const _rp; public: ShenandoahMarkConcurrentRootsTask(ShenandoahObjToScanQueueSet* qs, - ReferenceProcessor* rp, + ShenandoahReferenceProcessor* rp, ShenandoahPhaseTimings::Phase phase, uint nworkers); void work(uint worker_id); }; ShenandoahMarkConcurrentRootsTask::ShenandoahMarkConcurrentRootsTask(ShenandoahObjToScanQueueSet* qs, - ReferenceProcessor* rp, + ShenandoahReferenceProcessor* rp, ShenandoahPhaseTimings::Phase phase, uint nworkers) : AbstractGangTask("Shenandoah Concurrent Mark Roots"), @@ -442,19 +428,7 @@ void ShenandoahConcurrentMark::mark_from_roots() { WorkGang* workers = _heap->workers(); uint nworkers = workers->active_workers(); - ReferenceProcessor* rp = NULL; - if (_heap->process_references()) { - rp = _heap->ref_processor(); - rp->set_active_mt_degree(nworkers); - - // enable ("weak") refs discovery - rp->enable_discovery(true /*verify_no_refs*/); - rp->setup_policy(_heap->soft_ref_policy()->should_clear_all_soft_refs()); - } - - shenandoah_assert_rp_isalive_not_installed(); - ShenandoahIsAliveSelector is_alive; - ReferenceProcessorIsAliveMutator fix_isalive(_heap->ref_processor(), is_alive.is_alive_closure()); + ShenandoahReferenceProcessor* rp = _heap->ref_processor(); task_queues()->reserve(nworkers); @@ -480,10 +454,6 @@ void ShenandoahConcurrentMark::finish_mark_from_roots(bool full_gc) { uint nworkers = _heap->workers()->active_workers(); { - shenandoah_assert_rp_isalive_not_installed(); - ShenandoahIsAliveSelector is_alive; - ReferenceProcessorIsAliveMutator fix_isalive(_heap->ref_processor(), is_alive.is_alive_closure()); - // Full GC does not execute concurrent cycle. Degenerated cycle may bypass concurrent cycle. // In those cases, concurrent roots might not be scanned, scan them here. Ideally, this // should piggyback to ShenandoahFinalMarkingTask, but it makes time tracking very hard. @@ -524,343 +494,11 @@ void ShenandoahConcurrentMark::finish_mark_from_roots(bool full_gc) { assert(task_queues()->is_empty(), "Should be empty"); } - // When we're done marking everything, we process weak references. - if (_heap->process_references()) { - weak_refs_work(full_gc); - } - assert(task_queues()->is_empty(), "Should be empty"); TASKQUEUE_STATS_ONLY(task_queues()->print_taskqueue_stats()); TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats()); } -// Weak Reference Closures -class ShenandoahCMDrainMarkingStackClosure: public VoidClosure { - uint _worker_id; - TaskTerminator* _terminator; - bool _reset_terminator; - -public: - ShenandoahCMDrainMarkingStackClosure(uint worker_id, TaskTerminator* t, bool reset_terminator = false): - _worker_id(worker_id), - _terminator(t), - _reset_terminator(reset_terminator) { - } - - void do_void() { - assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint"); - - ShenandoahHeap* sh = ShenandoahHeap::heap(); - ShenandoahConcurrentMark* scm = sh->concurrent_mark(); - assert(sh->process_references(), "why else would we be here?"); - ReferenceProcessor* rp = sh->ref_processor(); - - shenandoah_assert_rp_isalive_installed(); - - scm->mark_loop(_worker_id, _terminator, rp, - false, // not cancellable - false); // do not do strdedup - - if (_reset_terminator) { - _terminator->reset_for_reuse(); - } - } -}; - -class ShenandoahCMKeepAliveClosure : public OopClosure { -private: - ShenandoahObjToScanQueue* _queue; - ShenandoahHeap* _heap; - ShenandoahMarkingContext* const _mark_context; - - template - inline void do_oop_work(T* p) { - ShenandoahConcurrentMark::mark_through_ref(p, _heap, _queue, _mark_context); - } - -public: - ShenandoahCMKeepAliveClosure(ShenandoahObjToScanQueue* q) : - _queue(q), - _heap(ShenandoahHeap::heap()), - _mark_context(_heap->marking_context()) {} - - void do_oop(narrowOop* p) { do_oop_work(p); } - void do_oop(oop* p) { do_oop_work(p); } -}; - -class ShenandoahCMKeepAliveUpdateClosure : public OopClosure { -private: - ShenandoahObjToScanQueue* _queue; - ShenandoahHeap* _heap; - ShenandoahMarkingContext* const _mark_context; - - template - inline void do_oop_work(T* p) { - ShenandoahConcurrentMark::mark_through_ref(p, _heap, _queue, _mark_context); - } - -public: - ShenandoahCMKeepAliveUpdateClosure(ShenandoahObjToScanQueue* q) : - _queue(q), - _heap(ShenandoahHeap::heap()), - _mark_context(_heap->marking_context()) {} - - void do_oop(narrowOop* p) { do_oop_work(p); } - void do_oop(oop* p) { do_oop_work(p); } -}; - -class ShenandoahWeakUpdateClosure : public OopClosure { -private: - ShenandoahHeap* const _heap; - - template - inline void do_oop_work(T* p) { - oop o = _heap->maybe_update_with_forwarded(p); - shenandoah_assert_marked_except(p, o, o == NULL); - } - -public: - ShenandoahWeakUpdateClosure() : _heap(ShenandoahHeap::heap()) {} - - void do_oop(narrowOop* p) { do_oop_work(p); } - void do_oop(oop* p) { do_oop_work(p); } -}; - -class ShenandoahRefProcTaskProxy : public AbstractGangTask { -private: - AbstractRefProcTaskExecutor::ProcessTask& _proc_task; - TaskTerminator* _terminator; - -public: - ShenandoahRefProcTaskProxy(AbstractRefProcTaskExecutor::ProcessTask& proc_task, - TaskTerminator* t) : - AbstractGangTask("Shenandoah Process Weak References"), - _proc_task(proc_task), - _terminator(t) { - } - - void work(uint worker_id) { - Thread* current_thread = Thread::current(); - ResourceMark rm(current_thread); - HandleMark hm(current_thread); - assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint"); - ShenandoahHeap* heap = ShenandoahHeap::heap(); - ShenandoahParallelWorkerSession worker_session(worker_id); - ShenandoahCMDrainMarkingStackClosure complete_gc(worker_id, _terminator); - if (heap->has_forwarded_objects()) { - ShenandoahForwardedIsAliveClosure is_alive; - ShenandoahCMKeepAliveUpdateClosure keep_alive(heap->concurrent_mark()->get_queue(worker_id)); - _proc_task.work(worker_id, is_alive, keep_alive, complete_gc); - } else { - ShenandoahIsAliveClosure is_alive; - ShenandoahCMKeepAliveClosure keep_alive(heap->concurrent_mark()->get_queue(worker_id)); - _proc_task.work(worker_id, is_alive, keep_alive, complete_gc); - } - } -}; - -class ShenandoahRefProcTaskExecutor : public AbstractRefProcTaskExecutor { -private: - WorkGang* _workers; - -public: - ShenandoahRefProcTaskExecutor(WorkGang* workers) : - _workers(workers) { - } - - // Executes a task using worker threads. - void execute(ProcessTask& task, uint ergo_workers) { - assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a safepoint"); - - ShenandoahHeap* heap = ShenandoahHeap::heap(); - ShenandoahConcurrentMark* cm = heap->concurrent_mark(); - ShenandoahPushWorkerQueuesScope scope(_workers, cm->task_queues(), - ergo_workers, - /* do_check = */ false); - uint nworkers = _workers->active_workers(); - cm->task_queues()->reserve(nworkers); - TaskTerminator terminator(nworkers, cm->task_queues()); - ShenandoahRefProcTaskProxy proc_task_proxy(task, &terminator); - _workers->run_task(&proc_task_proxy); - } -}; - -void ShenandoahConcurrentMark::weak_refs_work(bool full_gc) { - assert(_heap->process_references(), "sanity"); - - ShenandoahPhaseTimings::Phase phase_root = - full_gc ? - ShenandoahPhaseTimings::full_gc_weakrefs : - ShenandoahPhaseTimings::weakrefs; - - ShenandoahGCPhase phase(phase_root); - - ReferenceProcessor* rp = _heap->ref_processor(); - - // NOTE: We cannot shortcut on has_discovered_references() here, because - // we will miss marking JNI Weak refs then, see implementation in - // ReferenceProcessor::process_discovered_references. - weak_refs_work_doit(full_gc); - - rp->verify_no_references_recorded(); - assert(!rp->discovery_enabled(), "Post condition"); - -} - -void ShenandoahConcurrentMark::weak_refs_work_doit(bool full_gc) { - ReferenceProcessor* rp = _heap->ref_processor(); - - ShenandoahPhaseTimings::Phase phase_process = - full_gc ? - ShenandoahPhaseTimings::full_gc_weakrefs_process : - ShenandoahPhaseTimings::weakrefs_process; - - shenandoah_assert_rp_isalive_not_installed(); - ShenandoahIsAliveSelector is_alive; - ReferenceProcessorIsAliveMutator fix_isalive(rp, is_alive.is_alive_closure()); - - WorkGang* workers = _heap->workers(); - uint nworkers = workers->active_workers(); - - rp->setup_policy(_heap->soft_ref_policy()->should_clear_all_soft_refs()); - rp->set_active_mt_degree(nworkers); - - assert(task_queues()->is_empty(), "Should be empty"); - - // complete_gc and keep_alive closures instantiated here are only needed for - // single-threaded path in RP. They share the queue 0 for tracking work, which - // simplifies implementation. Since RP may decide to call complete_gc several - // times, we need to be able to reuse the terminator. - uint serial_worker_id = 0; - TaskTerminator terminator(1, task_queues()); - ShenandoahCMDrainMarkingStackClosure complete_gc(serial_worker_id, &terminator, /* reset_terminator = */ true); - - ShenandoahRefProcTaskExecutor executor(workers); - - ReferenceProcessorPhaseTimes pt(_heap->gc_timer(), rp->num_queues()); - - { - // Note: Don't emit JFR event for this phase, to avoid overflow nesting phase level. - // Reference Processor emits 2 levels JFR event, that can get us over the JFR - // event nesting level limits, in case of degenerated GC gets upgraded to - // full GC. - ShenandoahTimingsTracker phase_timing(phase_process); - - if (_heap->has_forwarded_objects()) { - ShenandoahCMKeepAliveUpdateClosure keep_alive(get_queue(serial_worker_id)); - const ReferenceProcessorStats& stats = - rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive, - &complete_gc, &executor, - &pt); - _heap->tracer()->report_gc_reference_stats(stats); - } else { - ShenandoahCMKeepAliveClosure keep_alive(get_queue(serial_worker_id)); - const ReferenceProcessorStats& stats = - rp->process_discovered_references(is_alive.is_alive_closure(), &keep_alive, - &complete_gc, &executor, - &pt); - _heap->tracer()->report_gc_reference_stats(stats); - } - - pt.print_all_references(); - - assert(task_queues()->is_empty(), "Should be empty"); - } -} - -class ShenandoahCancelledGCYieldClosure : public YieldClosure { -private: - ShenandoahHeap* const _heap; -public: - ShenandoahCancelledGCYieldClosure() : _heap(ShenandoahHeap::heap()) {}; - virtual bool should_return() { return _heap->cancelled_gc(); } -}; - -class ShenandoahPrecleanCompleteGCClosure : public VoidClosure { -public: - void do_void() { - ShenandoahHeap* sh = ShenandoahHeap::heap(); - ShenandoahConcurrentMark* scm = sh->concurrent_mark(); - assert(sh->process_references(), "why else would we be here?"); - TaskTerminator terminator(1, scm->task_queues()); - - ReferenceProcessor* rp = sh->ref_processor(); - shenandoah_assert_rp_isalive_installed(); - - scm->mark_loop(0, &terminator, rp, - false, // not cancellable - false); // do not do strdedup - } -}; - -class ShenandoahPrecleanTask : public AbstractGangTask { -private: - ReferenceProcessor* _rp; - -public: - ShenandoahPrecleanTask(ReferenceProcessor* rp) : - AbstractGangTask("Shenandoah Precleaning"), - _rp(rp) {} - - void work(uint worker_id) { - assert(worker_id == 0, "The code below is single-threaded, only one worker is expected"); - ShenandoahParallelWorkerSession worker_session(worker_id); - - ShenandoahHeap* sh = ShenandoahHeap::heap(); - assert(!sh->has_forwarded_objects(), "No forwarded objects expected here"); - - ShenandoahObjToScanQueue* q = sh->concurrent_mark()->get_queue(worker_id); - - ShenandoahCancelledGCYieldClosure yield; - ShenandoahPrecleanCompleteGCClosure complete_gc; - - ShenandoahIsAliveClosure is_alive; - ShenandoahCMKeepAliveClosure keep_alive(q); - ResourceMark rm; - _rp->preclean_discovered_references(&is_alive, &keep_alive, - &complete_gc, &yield, - NULL); - } -}; - -void ShenandoahConcurrentMark::preclean_weak_refs() { - // Pre-cleaning weak references before diving into STW makes sense at the - // end of concurrent mark. This will filter out the references which referents - // are alive. Note that ReferenceProcessor already filters out these on reference - // discovery, and the bulk of work is done here. This phase processes leftovers - // that missed the initial filtering, i.e. when referent was marked alive after - // reference was discovered by RP. - - assert(_heap->process_references(), "sanity"); - - // Shortcut if no references were discovered to avoid winding up threads. - ReferenceProcessor* rp = _heap->ref_processor(); - if (!rp->has_discovered_references()) { - return; - } - - assert(task_queues()->is_empty(), "Should be empty"); - - ReferenceProcessorMTDiscoveryMutator fix_mt_discovery(rp, false); - - shenandoah_assert_rp_isalive_not_installed(); - ShenandoahIsAliveSelector is_alive; - ReferenceProcessorIsAliveMutator fix_isalive(rp, is_alive.is_alive_closure()); - - // Execute precleaning in the worker thread: it will give us GCLABs, String dedup - // queues and other goodies. When upstream ReferenceProcessor starts supporting - // parallel precleans, we can extend this to more threads. - WorkGang* workers = _heap->workers(); - uint nworkers = workers->active_workers(); - assert(nworkers == 1, "This code uses only a single worker"); - task_queues()->reserve(nworkers); - - ShenandoahPrecleanTask task(rp); - workers->run_task(&task); - - assert(task_queues()->is_empty(), "Should be empty"); -} - void ShenandoahConcurrentMark::cancel() { // Clean up marking stacks. ShenandoahObjToScanQueueSet* queues = task_queues(); @@ -876,7 +514,7 @@ ShenandoahObjToScanQueue* ShenandoahConcurrentMark::get_queue(uint worker_id) { } template -void ShenandoahConcurrentMark::mark_loop_prework(uint w, TaskTerminator *t, ReferenceProcessor *rp, +void ShenandoahConcurrentMark::mark_loop_prework(uint w, TaskTerminator *t, ShenandoahReferenceProcessor* rp, bool strdedup) { ShenandoahObjToScanQueue* q = get_queue(w); @@ -934,6 +572,8 @@ void ShenandoahConcurrentMark::mark_loop_work(T* cl, ShenandoahLiveData* live_da ShenandoahObjToScanQueue* q; ShenandoahMarkTask t; + _heap->ref_processor()->set_mark_closure(worker_id, cl); + /* * Process outstanding queues, if any. * diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp index 554e45c818e..2e8538234ee 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp @@ -32,6 +32,7 @@ #include "gc/shenandoah/shenandoahTaskqueue.hpp" class ShenandoahStrDedupQueue; +class ShenandoahReferenceProcessor; class ShenandoahConcurrentMark: public CHeapObj { private: @@ -49,10 +50,10 @@ class ShenandoahConcurrentMark: public CHeapObj { inline void do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveData* live_data, ShenandoahMarkTask* task); template - inline void do_chunked_array_start(ShenandoahObjToScanQueue* q, T* cl, oop array); + inline void do_chunked_array_start(ShenandoahObjToScanQueue* q, T* cl, oop array, bool weak); template - inline void do_chunked_array(ShenandoahObjToScanQueue* q, T* cl, oop array, int chunk, int pow); + inline void do_chunked_array(ShenandoahObjToScanQueue* q, T* cl, oop array, int chunk, int pow, bool weak); inline void count_liveness(ShenandoahLiveData* live_data, oop obj); @@ -60,10 +61,10 @@ class ShenandoahConcurrentMark: public CHeapObj { void mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint worker_id, TaskTerminator *t); template - void mark_loop_prework(uint worker_id, TaskTerminator *terminator, ReferenceProcessor *rp, bool strdedup); + void mark_loop_prework(uint worker_id, TaskTerminator *terminator, ShenandoahReferenceProcessor* rp, bool strdedup); public: - void mark_loop(uint worker_id, TaskTerminator* terminator, ReferenceProcessor *rp, + void mark_loop(uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor* rp, bool cancellable, bool strdedup) { if (cancellable) { mark_loop_prework(worker_id, terminator, rp, strdedup); @@ -73,7 +74,7 @@ class ShenandoahConcurrentMark: public CHeapObj { } template - static inline void mark_through_ref(T* p, ShenandoahHeap* heap, ShenandoahObjToScanQueue* q, ShenandoahMarkingContext* const mark_context); + static inline void mark_through_ref(T* p, ShenandoahHeap* heap, ShenandoahObjToScanQueue* q, ShenandoahMarkingContext* const mark_context, bool weak); void mark_from_roots(); void finish_mark_from_roots(bool full_gc); @@ -82,15 +83,6 @@ class ShenandoahConcurrentMark: public CHeapObj { void update_roots(ShenandoahPhaseTimings::Phase root_phase); void update_thread_roots(ShenandoahPhaseTimings::Phase root_phase); -// ---------- Weak references -// -private: - void weak_refs_work(bool full_gc); - void weak_refs_work_doit(bool full_gc); - -public: - void preclean_weak_refs(); - // ---------- Helpers // Used from closures, need to be public // diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp index fb1e0b0b2fd..837c00de2b0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2015, 2020, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,10 @@ void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, Shena shenandoah_assert_marked(NULL, obj); shenandoah_assert_not_in_cset_except(NULL, obj, _heap->cancelled_gc()); + // Are we in weak subgraph scan? + bool weak = task->is_weak(); + cl->set_weak(weak); + if (task->is_not_chunked()) { if (obj->is_instance()) { // Case 1: Normal oop, process as usual. @@ -52,7 +56,7 @@ void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, Shena } else if (obj->is_objArray()) { // Case 2: Object array instance and no chunk is set. Must be the first // time we visit it, start the chunked processing. - do_chunked_array_start(q, cl, obj); + do_chunked_array_start(q, cl, obj, weak); } else { // Case 3: Primitive array. Do nothing, no oops there. We use the same // performance tweak TypeArrayKlass::oop_oop_iterate_impl is using: @@ -61,10 +65,14 @@ void ShenandoahConcurrentMark::do_task(ShenandoahObjToScanQueue* q, T* cl, Shena assert (obj->is_typeArray(), "should be type array"); } // Count liveness the last: push the outstanding work to the queues first - count_liveness(live_data, obj); + // Avoid double-counting objects that are visited twice due to upgrade + // from final- to strong mark. + if (task->count_liveness()) { + count_liveness(live_data, obj); + } } else { // Case 4: Array chunk, has sensible chunk id. Process it. - do_chunked_array(q, cl, obj, task->chunk(), task->pow()); + do_chunked_array(q, cl, obj, task->chunk(), task->pow(), weak); } } @@ -98,7 +106,7 @@ inline void ShenandoahConcurrentMark::count_liveness(ShenandoahLiveData* live_da } template -inline void ShenandoahConcurrentMark::do_chunked_array_start(ShenandoahObjToScanQueue* q, T* cl, oop obj) { +inline void ShenandoahConcurrentMark::do_chunked_array_start(ShenandoahObjToScanQueue* q, T* cl, oop obj, bool weak) { assert(obj->is_objArray(), "expect object array"); objArrayOop array = objArrayOop(obj); int len = array->length(); @@ -129,7 +137,7 @@ inline void ShenandoahConcurrentMark::do_chunked_array_start(ShenandoahObjToScan pow--; chunk = 2; last_idx = (1 << pow); - bool pushed = q->push(ShenandoahMarkTask(array, 1, pow)); + bool pushed = q->push(ShenandoahMarkTask(array, true, weak, 1, pow)); assert(pushed, "overflow queue should always succeed pushing"); } @@ -142,7 +150,7 @@ inline void ShenandoahConcurrentMark::do_chunked_array_start(ShenandoahObjToScan int right_chunk = chunk*2; int left_chunk_end = left_chunk * (1 << pow); if (left_chunk_end < len) { - bool pushed = q->push(ShenandoahMarkTask(array, left_chunk, pow)); + bool pushed = q->push(ShenandoahMarkTask(array, true, weak, left_chunk, pow)); assert(pushed, "overflow queue should always succeed pushing"); chunk = right_chunk; last_idx = left_chunk_end; @@ -160,7 +168,7 @@ inline void ShenandoahConcurrentMark::do_chunked_array_start(ShenandoahObjToScan } template -inline void ShenandoahConcurrentMark::do_chunked_array(ShenandoahObjToScanQueue* q, T* cl, oop obj, int chunk, int pow) { +inline void ShenandoahConcurrentMark::do_chunked_array(ShenandoahObjToScanQueue* q, T* cl, oop obj, int chunk, int pow, bool weak) { assert(obj->is_objArray(), "expect object array"); objArrayOop array = objArrayOop(obj); @@ -171,7 +179,7 @@ inline void ShenandoahConcurrentMark::do_chunked_array(ShenandoahObjToScanQueue* while ((1 << pow) > (int)ObjArrayMarkingStride && (chunk*2 < ShenandoahMarkTask::chunk_size())) { pow--; chunk *= 2; - bool pushed = q->push(ShenandoahMarkTask(array, chunk - 1, pow)); + bool pushed = q->push(ShenandoahMarkTask(array, true, weak, chunk - 1, pow)); assert(pushed, "overflow queue should always succeed pushing"); } @@ -215,13 +223,13 @@ class ShenandoahSATBBufferClosure : public SATBBufferClosure { void do_buffer_impl(void **buffer, size_t size) { for (size_t i = 0; i < size; ++i) { oop *p = (oop *) &buffer[i]; - ShenandoahConcurrentMark::mark_through_ref(p, _heap, _queue, _mark_context); + ShenandoahConcurrentMark::mark_through_ref(p, _heap, _queue, _mark_context, false); } } }; template -inline void ShenandoahConcurrentMark::mark_through_ref(T *p, ShenandoahHeap* heap, ShenandoahObjToScanQueue* q, ShenandoahMarkingContext* const mark_context) { +inline void ShenandoahConcurrentMark::mark_through_ref(T *p, ShenandoahHeap* heap, ShenandoahObjToScanQueue* q, ShenandoahMarkingContext* const mark_context, bool weak) { T o = RawAccess<>::oop_load(p); if (!CompressedOops::is_null(o)) { oop obj = CompressedOops::decode_not_null(o); @@ -252,8 +260,15 @@ inline void ShenandoahConcurrentMark::mark_through_ref(T *p, ShenandoahHeap* hea shenandoah_assert_not_forwarded(p, obj); shenandoah_assert_not_in_cset_except(p, obj, heap->cancelled_gc()); - if (mark_context->mark(obj)) { - bool pushed = q->push(ShenandoahMarkTask(obj)); + bool skip_live = false; + bool marked; + if (weak) { + marked = mark_context->mark_weak(obj); + } else { + marked = mark_context->mark_strong(obj, /* was_upgraded = */ skip_live); + } + if (marked) { + bool pushed = q->push(ShenandoahMarkTask(obj, skip_live, weak)); assert(pushed, "overflow queue should always succeed pushing"); if ((STRING_DEDUP == ENQUEUE_DEDUP) && ShenandoahStringDedup::is_candidate(obj)) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index 5c46deeab42..b698da1f38b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp @@ -141,7 +141,6 @@ void ShenandoahControlThread::run_service() { policy->record_explicit_to_concurrent(); mode = default_mode; // Unload and clean up everything - heap->set_process_references(heuristics->can_process_references()); heap->set_unload_classes(heuristics->can_unload_classes()); } else { policy->record_explicit_to_full(); @@ -158,7 +157,6 @@ void ShenandoahControlThread::run_service() { mode = default_mode; // Unload and clean up everything - heap->set_process_references(heuristics->can_process_references()); heap->set_unload_classes(heuristics->can_unload_classes()); } else { policy->record_implicit_to_full(); @@ -172,7 +170,6 @@ void ShenandoahControlThread::run_service() { } // Ask policy if this cycle wants to process references or unload classes - heap->set_process_references(heuristics->should_process_references()); heap->set_unload_classes(heuristics->should_unload_classes()); } @@ -404,14 +401,12 @@ void ShenandoahControlThread::service_concurrent_normal_cycle(GCCause::Cause cau heap->entry_mark(); if (check_cancellation_or_degen(ShenandoahHeap::_degenerated_mark)) return; - // If not cancelled, can try to concurrently pre-clean - heap->entry_preclean(); - // Complete marking under STW, and start evacuation heap->vmop_entry_final_mark(); // Process weak roots that might still point to regions that would be broken by cleanup if (heap->is_concurrent_weak_root_in_progress()) { + heap->entry_weak_refs(); heap->entry_weak_roots(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 67adf336996..c36ed910315 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -55,6 +55,7 @@ #include "gc/shenandoah/shenandoahPacer.inline.hpp" #include "gc/shenandoah/shenandoahPadding.hpp" #include "gc/shenandoah/shenandoahParallelCleaning.inline.hpp" +#include "gc/shenandoah/shenandoahReferenceProcessor.hpp" #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" #include "gc/shenandoah/shenandoahStringDedup.hpp" #include "gc/shenandoah/shenandoahTaskqueue.hpp" @@ -206,10 +207,10 @@ jint ShenandoahHeap::initialize() { // Reserve and commit memory for bitmap(s) // - _bitmap_size = MarkBitMap::compute_size(heap_rs.size()); + _bitmap_size = ShenandoahMarkBitMap::compute_size(heap_rs.size()); _bitmap_size = align_up(_bitmap_size, bitmap_page_size); - size_t bitmap_bytes_per_region = reg_size_bytes / MarkBitMap::heap_map_factor(); + size_t bitmap_bytes_per_region = reg_size_bytes / ShenandoahMarkBitMap::heap_map_factor(); guarantee(bitmap_bytes_per_region != 0, "Bitmap bytes per region should not be zero"); @@ -393,9 +394,6 @@ jint ShenandoahHeap::initialize() { _control_thread = new ShenandoahControlThread(); - _ref_proc_mt_processing = ParallelRefProcEnabled && (ParallelGCThreads > 1); - _ref_proc_mt_discovery = _max_workers > 1; - ShenandoahInitLogger::print(); return JNI_OK; @@ -475,7 +473,7 @@ ShenandoahHeap::ShenandoahHeap(ShenandoahCollectorPolicy* policy) : _gc_timer(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()), _soft_ref_policy(), _log_min_obj_alignment_in_bytes(LogMinObjAlignmentInBytes), - _ref_processor(NULL), + _ref_processor(new ShenandoahReferenceProcessor(MAX2(_max_workers, 1U))), _marking_context(NULL), _bitmap_size(0), _bitmap_regions_per_slice(0), @@ -615,8 +613,6 @@ void ShenandoahHeap::post_initialize() { _scm->initialize(_max_workers); _full_gc->initialize(_gc_timer); - ref_processing_init(); - _heuristics->initialize(); JFR_ONLY(ShenandoahJFRSupport::register_jfr_type_serializers()); @@ -1791,13 +1787,9 @@ void ShenandoahHeap::op_final_mark() { concurrent_mark()->cancel(); set_concurrent_mark_in_progress(false); - if (process_references()) { - // Abandon reference processing right away: pre-cleaning must have failed. - ReferenceProcessor *rp = ref_processor(); - rp->disable_discovery(); - rp->abandon_partial_discovery(); - rp->verify_no_references_recorded(); - } + // Abandon reference processing right away: pre-cleaning must have failed. + ShenandoahReferenceProcessor* rp = ref_processor(); + rp->abandon_partial_discovery(); } } @@ -2004,6 +1996,15 @@ class ShenandoahConcurrentWeakRootsEvacUpdateTask : public AbstractGangTask { } }; +void ShenandoahHeap::op_weak_refs() { + // Concurrent weak refs processing + { + ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_weak_refs_work); + ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::conc_weak_refs_work); + ref_processor()->process_references(workers(), true /* concurrent */); + } +} + void ShenandoahHeap::op_weak_roots() { if (is_concurrent_weak_root_in_progress()) { // Concurrent weak root processing @@ -2077,13 +2078,6 @@ void ShenandoahHeap::op_reset() { parallel_heap_region_iterate(&cl); } -void ShenandoahHeap::op_preclean() { - if (ShenandoahPacing) { - pacer()->setup_for_preclean(); - } - concurrent_mark()->preclean_weak_refs(); -} - void ShenandoahHeap::op_full(GCCause::Cause cause) { ShenandoahMetricsSnapshot metrics; metrics.snap_before(); @@ -2125,7 +2119,6 @@ void ShenandoahHeap::op_degenerated(ShenandoahDegenPoint point) { // // Note that we can only do this for "outside-cycle" degens, otherwise we would risk // changing the cycle parameters mid-cycle during concurrent -> degenerated handover. - set_process_references(heuristics()->can_process_references()); set_unload_classes(heuristics()->can_unload_classes()); op_reset(); @@ -2150,6 +2143,12 @@ void ShenandoahHeap::op_degenerated(ShenandoahDegenPoint point) { ShenandoahCodeRoots::disarm_nmethods(); } + { + ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_weak_refs_work); + ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::conc_weak_refs_work); + ref_processor()->process_references(workers(), false /* concurrent */); + } + op_cleanup_early(); case _degenerated_evac: @@ -2310,22 +2309,6 @@ void ShenandoahHeap::set_concurrent_weak_root_in_progress(bool in_progress) { } } -void ShenandoahHeap::ref_processing_init() { - assert(_max_workers > 0, "Sanity"); - - _ref_processor = - new ReferenceProcessor(&_subject_to_discovery, // is_subject_to_discovery - _ref_proc_mt_processing, // MT processing - _max_workers, // Degree of MT processing - _ref_proc_mt_discovery, // MT discovery - _max_workers, // Degree of MT discovery - false, // Reference discovery is not atomic - NULL, // No closure, should be installed before use - true); // Scale worker threads - - shenandoah_assert_rp_isalive_not_installed(); -} - GCTracer* ShenandoahHeap::tracer() { return shenandoah_policy()->tracer(); } @@ -2461,18 +2444,10 @@ void ShenandoahHeap::set_has_forwarded_objects(bool cond) { set_gc_state_mask(HAS_FORWARDED, cond); } -void ShenandoahHeap::set_process_references(bool pr) { - _process_references.set_cond(pr); -} - void ShenandoahHeap::set_unload_classes(bool uc) { _unload_classes.set_cond(uc); } -bool ShenandoahHeap::process_references() const { - return _process_references.is_set(); -} - bool ShenandoahHeap::unload_classes() const { return _unload_classes.is_set(); } @@ -3067,6 +3042,19 @@ void ShenandoahHeap::entry_updaterefs() { op_updaterefs(); } +void ShenandoahHeap::entry_weak_refs() { + static const char* msg = "Concurrent weak references"; + ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_weak_refs); + EventMark em("%s", msg); + + ShenandoahWorkerScope scope(workers(), + ShenandoahWorkerPolicy::calc_workers_for_conc_refs_processing(), + "concurrent weak references"); + + try_inject_alloc_failure(); + op_weak_refs(); +} + void ShenandoahHeap::entry_weak_roots() { static const char* msg = "Concurrent weak roots"; ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_weak_roots); @@ -3153,22 +3141,6 @@ void ShenandoahHeap::entry_reset() { op_reset(); } -void ShenandoahHeap::entry_preclean() { - if (ShenandoahPreclean && process_references()) { - static const char* msg = "Concurrent precleaning"; - ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_preclean); - EventMark em("%s", msg); - - ShenandoahWorkerScope scope(workers(), - ShenandoahWorkerPolicy::calc_workers_for_conc_preclean(), - "concurrent preclean", - /* check_workers = */ false); - - try_inject_alloc_failure(); - op_preclean(); - } -} - void ShenandoahHeap::entry_uncommit(double shrink_before, size_t shrink_until) { static const char *msg = "Concurrent uncommit"; ShenandoahConcurrentPhase gc_phase(msg, ShenandoahPhaseTimings::conc_uncommit, true /* log_heap_usage */); @@ -3245,14 +3217,9 @@ void ShenandoahHeap::deduplicate_string(oop str) { const char* ShenandoahHeap::init_mark_event_message() const { assert(!has_forwarded_objects(), "Should not have forwarded objects here"); - bool proc_refs = process_references(); bool unload_cls = unload_classes(); - if (proc_refs && unload_cls) { - return "Pause Init Mark (process weakrefs) (unload classes)"; - } else if (proc_refs) { - return "Pause Init Mark (process weakrefs)"; - } else if (unload_cls) { + if (unload_cls) { return "Pause Init Mark (unload classes)"; } else { return "Pause Init Mark"; @@ -3262,14 +3229,9 @@ const char* ShenandoahHeap::init_mark_event_message() const { const char* ShenandoahHeap::final_mark_event_message() const { assert(!has_forwarded_objects(), "Should not have forwarded objects here"); - bool proc_refs = process_references(); bool unload_cls = unload_classes(); - if (proc_refs && unload_cls) { - return "Pause Final Mark (process weakrefs) (unload classes)"; - } else if (proc_refs) { - return "Pause Final Mark (process weakrefs)"; - } else if (unload_cls) { + if (unload_cls) { return "Pause Final Mark (unload classes)"; } else { return "Pause Final Mark"; @@ -3279,14 +3241,9 @@ const char* ShenandoahHeap::final_mark_event_message() const { const char* ShenandoahHeap::conc_mark_event_message() const { assert(!has_forwarded_objects(), "Should not have forwarded objects here"); - bool proc_refs = process_references(); bool unload_cls = unload_classes(); - if (proc_refs && unload_cls) { - return "Concurrent marking (process weakrefs) (unload classes)"; - } else if (proc_refs) { - return "Concurrent marking (process weakrefs)"; - } else if (unload_cls) { + if (unload_cls) { return "Concurrent marking (unload classes)"; } else { return "Concurrent marking"; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index 494166a640e..3a109a22673 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -42,7 +42,6 @@ class ConcurrentGCTimer; class ObjectIterateScanRootClosure; -class ReferenceProcessor; class ShenandoahCollectorPolicy; class ShenandoahControlThread; class ShenandoahGCSession; @@ -60,7 +59,7 @@ class ShenandoahFreeSet; class ShenandoahConcurrentMark; class ShenandoahMarkCompact; class ShenandoahMonitoringSupport; -class ShenandoahObjToScanQueueSet; +class ShenandoahReferenceProcessor; class ShenandoahPacer; class ShenandoahVerifier; class ShenandoahWorkGang; @@ -390,7 +389,7 @@ class ShenandoahHeap : public CollectedHeap { // for concurrent operation. void entry_reset(); void entry_mark(); - void entry_preclean(); + void entry_weak_refs(); void entry_weak_roots(); void entry_class_unloading(); void entry_strong_roots(); @@ -415,7 +414,7 @@ class ShenandoahHeap : public CollectedHeap { void op_reset(); void op_mark(); - void op_preclean(); + void op_weak_refs(); void op_weak_roots(); void op_class_unloading(); void op_strong_roots(); @@ -494,20 +493,10 @@ class ShenandoahHeap : public CollectedHeap { // ---------- Reference processing // private: - AlwaysTrueClosure _subject_to_discovery; - ReferenceProcessor* _ref_processor; - ShenandoahSharedFlag _process_references; - bool _ref_proc_mt_discovery; - bool _ref_proc_mt_processing; - - void ref_processing_init(); + ShenandoahReferenceProcessor* const _ref_processor; public: - ReferenceProcessor* ref_processor() { return _ref_processor; } - bool ref_processor_mt_discovery() { return _ref_proc_mt_discovery; } - bool ref_processor_mt_processing() { return _ref_proc_mt_processing; } - void set_process_references(bool pr); - bool process_references() const; + ShenandoahReferenceProcessor* ref_processor() { return _ref_processor; } // ---------- Class Unloading // diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp index 3bb97e01f59..6c49253e2c9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp @@ -401,7 +401,6 @@ inline void ShenandoahHeap::marked_object_iterate(ShenandoahHeapRegion* region, ShenandoahMarkingContext* const ctx = complete_marking_context(); assert(ctx->is_complete(), "sanity"); - MarkBitMap* mark_bit_map = ctx->mark_bit_map(); HeapWord* tams = ctx->top_at_mark_start(region); size_t skip_bitmap_delta = 1; @@ -413,7 +412,7 @@ inline void ShenandoahHeap::marked_object_iterate(ShenandoahHeapRegion* region, // Try to scan the initial candidate. If the candidate is above the TAMS, it would // fail the subsequent "< limit_bitmap" checks, and fall through to Step 2. - HeapWord* cb = mark_bit_map->get_next_marked_addr(start, end); + HeapWord* cb = ctx->get_next_marked_addr(start, end); intx dist = ShenandoahMarkScanPrefetch; if (dist > 0) { @@ -440,7 +439,7 @@ inline void ShenandoahHeap::marked_object_iterate(ShenandoahHeapRegion* region, slots[avail++] = cb; cb += skip_bitmap_delta; if (cb < limit_bitmap) { - cb = mark_bit_map->get_next_marked_addr(cb, limit_bitmap); + cb = ctx->get_next_marked_addr(cb, limit_bitmap); } } @@ -463,7 +462,7 @@ inline void ShenandoahHeap::marked_object_iterate(ShenandoahHeapRegion* region, cl->do_object(obj); cb += skip_bitmap_delta; if (cb < limit_bitmap) { - cb = mark_bit_map->get_next_marked_addr(cb, limit_bitmap); + cb = ctx->get_next_marked_addr(cb, limit_bitmap); } } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahInitLogger.cpp b/src/hotspot/share/gc/shenandoah/shenandoahInitLogger.cpp index 2c2bc91cfff..9f0233dd08c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahInitLogger.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahInitLogger.cpp @@ -57,10 +57,6 @@ void ShenandoahInitLogger::print_heap() { log_info(gc, init)("Humongous Object Threshold: " SIZE_FORMAT "%s", byte_size_in_exact_unit(ShenandoahHeapRegion::humongous_threshold_bytes()), exact_unit_for_byte_size(ShenandoahHeapRegion::humongous_threshold_bytes())); - - log_info(gc, init)("Reference Processing: %s discovery, %s processing", - heap->ref_processor_mt_discovery() ? "Parallel" : "Serial", - heap->ref_processor_mt_processing() ? "Parallel" : "Serial"); } void ShenandoahInitLogger::print() { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.cpp new file mode 100644 index 00000000000..75af01c0cc7 --- /dev/null +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Red Hat, Inc. and/or its affiliates. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc/shenandoah/shenandoahMarkBitMap.inline.hpp" +#include "gc/shenandoah/shenandoahHeap.inline.hpp" +#include "utilities/globalDefinitions.hpp" + +ShenandoahMarkBitMap::ShenandoahMarkBitMap(MemRegion heap, MemRegion storage) : + _shift(LogMinObjAlignment), + _covered(heap), + _map((BitMap::bm_word_t*) storage.start()), + _size((heap.word_size() * 2) >> _shift) { +} + +size_t ShenandoahMarkBitMap::compute_size(size_t heap_size) { + return ReservedSpace::allocation_align_size_up(heap_size / mark_distance()); +} + +size_t ShenandoahMarkBitMap::mark_distance() { + return MinObjAlignmentInBytes * BitsPerByte / 2; +} + +HeapWord* ShenandoahMarkBitMap::get_next_marked_addr(const HeapWord* addr, + const HeapWord* limit) const { + assert(limit != NULL, "limit must not be NULL"); + // Round addr up to a possible object boundary to be safe. + size_t const addr_offset = address_to_index(align_up(addr, HeapWordSize << LogMinObjAlignment)); + size_t const limit_offset = address_to_index(limit); + size_t const nextOffset = get_next_one_offset(addr_offset, limit_offset); + return index_to_address(nextOffset); +} + +void ShenandoahMarkBitMap::clear_range_within_word(idx_t beg, idx_t end) { + // With a valid range (beg <= end), this test ensures that end != 0, as + // required by inverted_bit_mask_for_range. Also avoids an unnecessary write. + if (beg != end) { + bm_word_t mask = inverted_bit_mask_for_range(beg, end); + *word_addr(beg) &= mask; + } +} + +void ShenandoahMarkBitMap::clear_range(idx_t beg, idx_t end) { + verify_range(beg, end); + + idx_t beg_full_word = to_words_align_up(beg); + idx_t end_full_word = to_words_align_down(end); + + if (beg_full_word < end_full_word) { + // The range includes at least one full word. + clear_range_within_word(beg, bit_index(beg_full_word)); + clear_range_of_words(beg_full_word, end_full_word); + clear_range_within_word(bit_index(end_full_word), end); + } else { + // The range spans at most 2 partial words. + idx_t boundary = MIN2(bit_index(beg_full_word), end); + clear_range_within_word(beg, boundary); + clear_range_within_word(boundary, end); + } +} + +bool ShenandoahMarkBitMap::is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word) { + // There is little point to call large version on small ranges. + // Need to check carefully, keeping potential idx_t over/underflow in mind, + // because beg_full_word > end_full_word can occur when beg and end are in + // the same word. + // The threshold should be at least one word. + STATIC_ASSERT(small_range_words >= 1); + return beg_full_word + small_range_words >= end_full_word; +} + + +void ShenandoahMarkBitMap::clear_large_range(idx_t beg, idx_t end) { + verify_range(beg, end); + + idx_t beg_full_word = to_words_align_up(beg); + idx_t end_full_word = to_words_align_down(end); + + if (is_small_range_of_words(beg_full_word, end_full_word)) { + clear_range(beg, end); + return; + } + + // The range includes at least one full word. + clear_range_within_word(beg, bit_index(beg_full_word)); + clear_large_range_of_words(beg_full_word, end_full_word); + clear_range_within_word(bit_index(end_full_word), end); +} + +void ShenandoahMarkBitMap::clear_range_large(MemRegion mr) { + MemRegion intersection = mr.intersection(_covered); + assert(!intersection.is_empty(), + "Given range from " PTR_FORMAT " to " PTR_FORMAT " is completely outside the heap", + p2i(mr.start()), p2i(mr.end())); + // convert address range into offset range + size_t beg = address_to_index(intersection.start()); + size_t end = address_to_index(intersection.end()); + clear_large_range(beg, end); +} + +#ifdef ASSERT +void ShenandoahMarkBitMap::check_mark(HeapWord* addr) const { + assert(ShenandoahHeap::heap()->is_in(addr), + "Trying to access bitmap " PTR_FORMAT " for address " PTR_FORMAT " not in the heap.", + p2i(this), p2i(addr)); +} + +void ShenandoahMarkBitMap::verify_index(idx_t bit) const { + assert(bit < _size, + "BitMap index out of bounds: " SIZE_FORMAT " >= " SIZE_FORMAT, + bit, _size); +} + +void ShenandoahMarkBitMap::verify_limit(idx_t bit) const { + assert(bit <= _size, + "BitMap limit out of bounds: " SIZE_FORMAT " > " SIZE_FORMAT, + bit, _size); +} + +void ShenandoahMarkBitMap::verify_range(idx_t beg, idx_t end) const { + assert(beg <= end, + "BitMap range error: " SIZE_FORMAT " > " SIZE_FORMAT, beg, end); + verify_limit(end); +} +#endif diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.hpp new file mode 100644 index 00000000000..a37523f8197 --- /dev/null +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.hpp @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Red Hat, Inc. and/or its affiliates. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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_VM_GC_SHENANDOAH_SHENANDOAHMARKBITMAP_HPP +#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHMARKBITMAP_HPP + +#include "memory/memRegion.hpp" +#include "runtime/atomic.hpp" +#include "utilities/globalDefinitions.hpp" + +class ShenandoahMarkBitMap { +public: + typedef size_t idx_t; // Type used for bit and word indices. + typedef uintptr_t bm_word_t; // Element type of array that represents the + // bitmap, with BitsPerWord bits per element. + +private: + // Values for get_next_bit_impl flip parameter. + static const bm_word_t find_ones_flip = 0; + static const bm_word_t find_zeros_flip = ~(bm_word_t)0; + + int const _shift; + MemRegion _covered; + + bm_word_t* _map; // First word in bitmap + idx_t _size; // Size of bitmap (in bits) + + // Threshold for performing small range operation, even when large range + // operation was requested. Measured in words. + static const size_t small_range_words = 32; + + static bool is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word); + + inline size_t address_to_index(const HeapWord* addr) const; + inline HeapWord* index_to_address(size_t offset) const; + + void check_mark(HeapWord* addr) const NOT_DEBUG_RETURN; + + // Return a mask that will select the specified bit, when applied to the word + // containing the bit. + static bm_word_t bit_mask(idx_t bit) { return (bm_word_t)1 << bit_in_word(bit); } + + // Return the bit number of the first bit in the specified word. + static idx_t bit_index(idx_t word) { return word << LogBitsPerWord; } + + // Return the position of bit within the word that contains it (e.g., if + // bitmap words are 32 bits, return a number 0 <= n <= 31). + static idx_t bit_in_word(idx_t bit) { return bit & (BitsPerWord - 1); } + + bm_word_t* map() { return _map; } + const bm_word_t* map() const { return _map; } + bm_word_t map(idx_t word) const { return _map[word]; } + + // Return a pointer to the word containing the specified bit. + bm_word_t* word_addr(idx_t bit) { + return map() + to_words_align_down(bit); + } + + const bm_word_t* word_addr(idx_t bit) const { + return map() + to_words_align_down(bit); + } + + static inline const bm_word_t load_word_ordered(const volatile bm_word_t* const addr, atomic_memory_order memory_order); + + bool at(idx_t index) const { + verify_index(index); + return (*word_addr(index) & bit_mask(index)) != 0; + } + + // Assumes relevant validity checking for bit has already been done. + static idx_t raw_to_words_align_up(idx_t bit) { + return raw_to_words_align_down(bit + (BitsPerWord - 1)); + } + + // Assumes relevant validity checking for bit has already been done. + static idx_t raw_to_words_align_down(idx_t bit) { + return bit >> LogBitsPerWord; + } + + // Word-aligns bit and converts it to a word offset. + // precondition: bit <= size() + idx_t to_words_align_up(idx_t bit) const { + verify_limit(bit); + return raw_to_words_align_up(bit); + } + + // Word-aligns bit and converts it to a word offset. + // precondition: bit <= size() + inline idx_t to_words_align_down(idx_t bit) const { + verify_limit(bit); + return raw_to_words_align_down(bit); + } + + // Helper for get_next_{zero,one}_bit variants. + // - flip designates whether searching for 1s or 0s. Must be one of + // find_{zeros,ones}_flip. + // - aligned_right is true if r_index is a priori on a bm_word_t boundary. + template + inline idx_t get_next_bit_impl(idx_t l_index, idx_t r_index) const; + + inline idx_t get_next_one_offset (idx_t l_index, idx_t r_index) const; + + void clear_large_range (idx_t beg, idx_t end); + + // Verify bit is less than size(). + void verify_index(idx_t bit) const NOT_DEBUG_RETURN; + // Verify bit is not greater than size(). + void verify_limit(idx_t bit) const NOT_DEBUG_RETURN; + // Verify [beg,end) is a valid range, e.g. beg <= end <= size(). + void verify_range(idx_t beg, idx_t end) const NOT_DEBUG_RETURN; + +public: + static size_t compute_size(size_t heap_size); + // Returns the amount of bytes on the heap between two marks in the bitmap. + static size_t mark_distance(); + // Returns how many bytes (or bits) of the heap a single byte (or bit) of the + // mark bitmap corresponds to. This is the same as the mark distance above. + static size_t heap_map_factor() { + return mark_distance(); + } + + ShenandoahMarkBitMap(MemRegion heap, MemRegion storage); + + // Mark word as 'strong' if it hasn't been marked strong yet. + // Return true if the word has been marked strong, false if it has already been + // marked strong or if another thread has beat us by marking it + // strong. + // Words that have been marked final before or by a concurrent thread will be + // upgraded to strong. In this case, this method also returns true. + inline bool mark_strong(HeapWord* w, bool& was_upgraded); + + // Mark word as 'weak' if it hasn't been marked weak or strong yet. + // Return true if the word has been marked weak, false if it has already been + // marked strong or weak or if another thread has beat us by marking it + // strong or weak. + inline bool mark_weak(HeapWord* heap_addr); + + inline bool is_marked(HeapWord* addr) const; + inline bool is_marked_strong(HeapWord* w) const; + inline bool is_marked_weak(HeapWord* addr) const; + + // Return the address corresponding to the next marked bit at or after + // "addr", and before "limit", if "limit" is non-NULL. If there is no + // such bit, returns "limit" if that is non-NULL, or else "endWord()". + HeapWord* get_next_marked_addr(const HeapWord* addr, + const HeapWord* limit) const; + + bm_word_t inverted_bit_mask_for_range(idx_t beg, idx_t end) const; + void clear_range_within_word (idx_t beg, idx_t end); + void clear_range (idx_t beg, idx_t end); + void clear_range_large(MemRegion mr); + + void clear_range_of_words(idx_t beg, idx_t end); + void clear_large_range_of_words(idx_t beg, idx_t end); + static void clear_range_of_words(bm_word_t* map, idx_t beg, idx_t end); + +}; + +#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHMARKBITMAP_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.inline.hpp new file mode 100644 index 00000000000..b9e0bb61f54 --- /dev/null +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.inline.hpp @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Red Hat, Inc. and/or its affiliates. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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_VM_GC_SHENANDOAH_SHENANDOAHMARKBITMAP_INLINE_HPP +#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHMARKBITMAP_INLINE_HPP + +#include "gc/shenandoah/shenandoahMarkBitMap.hpp" +#include "runtime/atomic.hpp" +#include "utilities/count_trailing_zeros.hpp" + +inline size_t ShenandoahMarkBitMap::address_to_index(const HeapWord* addr) const { + return (pointer_delta(addr, _covered.start()) << 1) >> _shift; +} + +inline HeapWord* ShenandoahMarkBitMap::index_to_address(size_t offset) const { + return _covered.start() + ((offset >> 1) << _shift); +} + +inline bool ShenandoahMarkBitMap::mark_strong(HeapWord* heap_addr, bool& was_upgraded) { + check_mark(heap_addr); + + idx_t bit = address_to_index(heap_addr); + verify_index(bit); + volatile bm_word_t* const addr = word_addr(bit); + const bm_word_t mask = bit_mask(bit); + const bm_word_t mask_weak = (bm_word_t)1 << (bit_in_word(bit) + 1); + bm_word_t old_val = load_word_ordered(addr, memory_order_conservative); + + do { + const bm_word_t new_val = old_val | mask; + if (new_val == old_val) { + assert(!was_upgraded, "Should be false already"); + return false; // Someone else beat us to it. + } + const bm_word_t cur_val = Atomic::cmpxchg(addr, old_val, new_val, memory_order_conservative); + if (cur_val == old_val) { + was_upgraded = (cur_val & mask_weak) != 0; + return true; // Success. + } + old_val = cur_val; // The value changed, try again. + } while (true); +} + +inline bool ShenandoahMarkBitMap::mark_weak(HeapWord* heap_addr) { + check_mark(heap_addr); + + idx_t bit = address_to_index(heap_addr); + verify_index(bit); + volatile bm_word_t* const addr = word_addr(bit); + const bm_word_t mask_weak = (bm_word_t)1 << (bit_in_word(bit) + 1); + const bm_word_t mask_strong = (bm_word_t)1 << bit_in_word(bit); + bm_word_t old_val = load_word_ordered(addr, memory_order_conservative); + + do { + if ((old_val & mask_strong) != 0) { + return false; // Already marked strong + } + const bm_word_t new_val = old_val | mask_weak; + if (new_val == old_val) { + return false; // Someone else beat us to it. + } + const bm_word_t cur_val = Atomic::cmpxchg(addr, old_val, new_val, memory_order_conservative); + if (cur_val == old_val) { + return true; // Success. + } + old_val = cur_val; // The value changed, try again. + } while (true); +} + +inline bool ShenandoahMarkBitMap::is_marked_strong(HeapWord* addr) const { + check_mark(addr); + return at(address_to_index(addr)); +} + +inline bool ShenandoahMarkBitMap::is_marked_weak(HeapWord* addr) const { + check_mark(addr); + return at(address_to_index(addr) + 1); +} + +inline bool ShenandoahMarkBitMap::is_marked(HeapWord* addr) const { + check_mark(addr); + idx_t index = address_to_index(addr); + verify_index(index); + bm_word_t mask = (bm_word_t)3 << bit_in_word(index); + return (*word_addr(index) & mask) != 0; +} + +inline const ShenandoahMarkBitMap::bm_word_t ShenandoahMarkBitMap::load_word_ordered(const volatile bm_word_t* const addr, atomic_memory_order memory_order) { + if (memory_order == memory_order_relaxed || memory_order == memory_order_release) { + return Atomic::load(addr); + } else { + assert(memory_order == memory_order_acq_rel || + memory_order == memory_order_acquire || + memory_order == memory_order_conservative, + "unexpected memory ordering"); + return Atomic::load_acquire(addr); + } +} + +template +inline ShenandoahMarkBitMap::idx_t ShenandoahMarkBitMap::get_next_bit_impl(idx_t l_index, idx_t r_index) const { + STATIC_ASSERT(flip == find_ones_flip || flip == find_zeros_flip); + verify_range(l_index, r_index); + assert(!aligned_right || is_aligned(r_index, BitsPerWord), "r_index not aligned"); + + // The first word often contains an interesting bit, either due to + // density or because of features of the calling algorithm. So it's + // important to examine that first word with a minimum of fuss, + // minimizing setup time for later words that will be wasted if the + // first word is indeed interesting. + + // The benefit from aligned_right being true is relatively small. + // It saves an operation in the setup for the word search loop. + // It also eliminates the range check on the final result. + // However, callers often have a comparison with r_index, and + // inlining often allows the two comparisons to be combined; it is + // important when !aligned_right that return paths either return + // r_index or a value dominated by a comparison with r_index. + // aligned_right is still helpful when the caller doesn't have a + // range check because features of the calling algorithm guarantee + // an interesting bit will be present. + + if (l_index < r_index) { + // Get the word containing l_index, and shift out low bits. + idx_t index = to_words_align_down(l_index); + bm_word_t cword = (map(index) ^ flip) >> bit_in_word(l_index); + if ((cword & 1) != 0) { + // The first bit is similarly often interesting. When it matters + // (density or features of the calling algorithm make it likely + // the first bit is set), going straight to the next clause compares + // poorly with doing this check first; count_trailing_zeros can be + // relatively expensive, plus there is the additional range check. + // But when the first bit isn't set, the cost of having tested for + // it is relatively small compared to the rest of the search. + return l_index; + } else if (cword != 0) { + // Flipped and shifted first word is non-zero. + idx_t result = l_index + count_trailing_zeros(cword); + if (aligned_right || (result < r_index)) return result; + // Result is beyond range bound; return r_index. + } else { + // Flipped and shifted first word is zero. Word search through + // aligned up r_index for a non-zero flipped word. + idx_t limit = aligned_right + ? to_words_align_down(r_index) // Miniscule savings when aligned. + : to_words_align_up(r_index); + while (++index < limit) { + cword = map(index) ^ flip; + if (cword != 0) { + idx_t result = bit_index(index) + count_trailing_zeros(cword); + if (aligned_right || (result < r_index)) return result; + // Result is beyond range bound; return r_index. + assert((index + 1) == limit, "invariant"); + break; + } + } + // No bits in range; return r_index. + } + } + return r_index; +} + +inline ShenandoahMarkBitMap::idx_t ShenandoahMarkBitMap::get_next_one_offset(idx_t l_offset, idx_t r_offset) const { + return get_next_bit_impl(l_offset, r_offset); +} + +// Returns a bit mask for a range of bits [beg, end) within a single word. Each +// bit in the mask is 0 if the bit is in the range, 1 if not in the range. The +// returned mask can be used directly to clear the range, or inverted to set the +// range. Note: end must not be 0. +inline ShenandoahMarkBitMap::bm_word_t +ShenandoahMarkBitMap::inverted_bit_mask_for_range(idx_t beg, idx_t end) const { + assert(end != 0, "does not work when end == 0"); + assert(beg == end || to_words_align_down(beg) == to_words_align_down(end - 1), + "must be a single-word range"); + bm_word_t mask = bit_mask(beg) - 1; // low (right) bits + if (bit_in_word(end) != 0) { + mask |= ~(bit_mask(end) - 1); // high (left) bits + } + return mask; +} + +inline void ShenandoahMarkBitMap::clear_range_of_words(bm_word_t* map, idx_t beg, idx_t end) { + for (idx_t i = beg; i < end; ++i) map[i] = 0; +} + +inline void ShenandoahMarkBitMap::clear_large_range_of_words(idx_t beg, idx_t end) { + assert(beg <= end, "underflow"); + memset(_map + beg, 0, (end - beg) * sizeof(bm_word_t)); +} + +inline void ShenandoahMarkBitMap::clear_range_of_words(idx_t beg, idx_t end) { + clear_range_of_words(_map, beg, end); +} + + +#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHMARKBITMAP_INLINE_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp index 9993a9c612b..846b42c73ad 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp @@ -38,6 +38,7 @@ #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" +#include "gc/shenandoah/shenandoahReferenceProcessor.hpp" #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" #include "gc/shenandoah/shenandoahTaskqueue.inline.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" @@ -129,10 +130,8 @@ void ShenandoahMarkCompact::do_it(GCCause::Cause gc_cause) { assert(!heap->marking_context()->is_complete(), "sanity"); // e. Abandon reference discovery and clear all discovered references. - ReferenceProcessor* rp = heap->ref_processor(); - rp->disable_discovery(); + ShenandoahReferenceProcessor* rp = heap->ref_processor(); rp->abandon_partial_discovery(); - rp->verify_no_references_recorded(); // f. Set back forwarded objects bit back, in case some steps above dropped it. heap->set_has_forwarded_objects(has_forwarded_objects); @@ -241,18 +240,16 @@ void ShenandoahMarkCompact::phase1_mark_heap() { ShenandoahConcurrentMark* cm = heap->concurrent_mark(); - heap->set_process_references(heap->heuristics()->can_process_references()); heap->set_unload_classes(heap->heuristics()->can_unload_classes()); - ReferenceProcessor* rp = heap->ref_processor(); + ShenandoahReferenceProcessor* rp = heap->ref_processor(); // enable ("weak") refs discovery - rp->enable_discovery(true /*verify_no_refs*/); - rp->setup_policy(true); // forcefully purge all soft references - rp->set_active_mt_degree(heap->workers()->active_workers()); + rp->set_soft_reference_policy(true); // forcefully purge all soft references cm->mark_roots(ShenandoahPhaseTimings::full_gc_scan_roots); cm->finish_mark_from_roots(/* full_gc = */ true); heap->mark_complete_marking_context(); + rp->process_references(heap->workers(), false /* concurrent */); heap->parallel_cleaning(true /* full_gc */); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp index eea57c3dd5d..df5c2f114db 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp @@ -29,11 +29,11 @@ #include "gc/shenandoah/shenandoahMarkingContext.hpp" ShenandoahMarkingContext::ShenandoahMarkingContext(MemRegion heap_region, MemRegion bitmap_region, size_t num_regions) : + _mark_bit_map(heap_region, bitmap_region), _top_bitmaps(NEW_C_HEAP_ARRAY(HeapWord*, num_regions, mtGC)), _top_at_mark_starts_base(NEW_C_HEAP_ARRAY(HeapWord*, num_regions, mtGC)), _top_at_mark_starts(_top_at_mark_starts_base - ((uintx) heap_region.start() >> ShenandoahHeapRegion::region_size_bytes_shift())) { - _mark_bit_map.initialize(heap_region, bitmap_region); } bool ShenandoahMarkingContext::is_bitmap_clear() const { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.hpp index 8274afa2c19..a17f9680032 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.hpp @@ -25,7 +25,8 @@ #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHMARKINGCONTEXT_HPP #define SHARE_GC_SHENANDOAH_SHENANDOAHMARKINGCONTEXT_HPP -#include "gc/shared/markBitMap.hpp" +#include "gc/shenandoah/shenandoahMarkBitMap.hpp" +#include "gc/shenandoah/shenandoahSharedVariables.hpp" #include "memory/allocation.hpp" #include "memory/memRegion.hpp" #include "oops/oopsHierarchy.hpp" @@ -35,7 +36,7 @@ */ class ShenandoahMarkingContext : public CHeapObj { private: - MarkBitMap _mark_bit_map; + ShenandoahMarkBitMap _mark_bit_map; HeapWord** const _top_bitmaps; HeapWord** const _top_at_mark_starts_base; @@ -51,15 +52,19 @@ class ShenandoahMarkingContext : public CHeapObj { * been marked by this thread. Returns false if the object has already been marked, * or if a competing thread succeeded in marking this object. */ - inline bool mark(oop obj); + inline bool mark_strong(oop obj, bool& was_upgraded); + inline bool mark_weak(oop obj); - inline bool is_marked(oop obj) const; + // Simple versions of marking accessors, to be used outside of marking (e.g. no possible concurrent updates) + inline bool is_marked(oop) const; + inline bool is_marked_strong(oop obj) const; + inline bool is_marked_weak(oop obj) const; + + inline HeapWord* get_next_marked_addr(HeapWord* addr, HeapWord* limit) const; inline bool allocated_after_mark_start(oop obj) const; inline bool allocated_after_mark_start(HeapWord* addr) const; - inline MarkBitMap* mark_bit_map(); - inline HeapWord* top_at_mark_start(ShenandoahHeapRegion* r) const; inline void capture_top_at_mark_start(ShenandoahHeapRegion* r); inline void reset_top_at_mark_start(ShenandoahHeapRegion* r); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp index 338f30f86b1..5cb3bd5c353 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp @@ -25,19 +25,33 @@ #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHMARKINGCONTEXT_INLINE_HPP #define SHARE_GC_SHENANDOAH_SHENANDOAHMARKINGCONTEXT_INLINE_HPP +#include "gc/shenandoah/shenandoahMarkBitMap.inline.hpp" #include "gc/shenandoah/shenandoahMarkingContext.hpp" -inline MarkBitMap* ShenandoahMarkingContext::mark_bit_map() { - return &_mark_bit_map; +inline bool ShenandoahMarkingContext::mark_strong(oop obj, bool& was_upgraded) { + shenandoah_assert_not_forwarded(NULL, obj); + return (! allocated_after_mark_start(obj)) && _mark_bit_map.mark_strong(cast_from_oop(obj), was_upgraded); } -inline bool ShenandoahMarkingContext::mark(oop obj) { +inline bool ShenandoahMarkingContext::mark_weak(oop obj) { shenandoah_assert_not_forwarded(NULL, obj); - return (! allocated_after_mark_start(obj)) && _mark_bit_map.par_mark(obj); + return (! allocated_after_mark_start(obj)) && _mark_bit_map.mark_weak(cast_from_oop(obj)); } inline bool ShenandoahMarkingContext::is_marked(oop obj) const { - return allocated_after_mark_start(obj) || _mark_bit_map.is_marked(obj); + return allocated_after_mark_start(obj) || _mark_bit_map.is_marked(cast_from_oop(obj)); +} + +inline bool ShenandoahMarkingContext::is_marked_strong(oop obj) const { + return allocated_after_mark_start(obj) || _mark_bit_map.is_marked_strong(cast_from_oop(obj)); +} + +inline bool ShenandoahMarkingContext::is_marked_weak(oop obj) const { + return allocated_after_mark_start(obj) || _mark_bit_map.is_marked_weak(cast_from_oop(obj)); +} + +inline HeapWord* ShenandoahMarkingContext::get_next_marked_addr(HeapWord* start, HeapWord* limit) const { + return _mark_bit_map.get_next_marked_addr(start, limit); } inline bool ShenandoahMarkingContext::allocated_after_mark_start(oop obj) const { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp b/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp index a175fc1743f..e9dceaad071 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp @@ -49,13 +49,22 @@ class ShenandoahMarkRefsSuperClosure : public MetadataVisitingOopIterateClosure ShenandoahObjToScanQueue* _queue; ShenandoahHeap* _heap; ShenandoahMarkingContext* const _mark_context; + bool _weak; protected: template void work(T *p); public: - ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp); + ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp); + + bool is_weak() const { + return _weak; + } + + void set_weak(bool weak) { + _weak = weak; + } }; class ShenandoahMarkUpdateRefsClosure : public ShenandoahMarkRefsSuperClosure { @@ -64,7 +73,7 @@ class ShenandoahMarkUpdateRefsClosure : public ShenandoahMarkRefsSuperClosure { inline void do_oop_work(T* p) { work(p); } public: - ShenandoahMarkUpdateRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahMarkUpdateRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) : ShenandoahMarkRefsSuperClosure(q, rp) {}; virtual void do_oop(narrowOop* p) { do_oop_work(p); } @@ -78,7 +87,7 @@ class ShenandoahMarkUpdateRefsDedupClosure : public ShenandoahMarkRefsSuperClosu inline void do_oop_work(T* p) { work(p); } public: - ShenandoahMarkUpdateRefsDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahMarkUpdateRefsDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) : ShenandoahMarkRefsSuperClosure(q, rp) {}; virtual void do_oop(narrowOop* p) { do_oop_work(p); } @@ -92,7 +101,7 @@ class ShenandoahMarkUpdateRefsMetadataClosure : public ShenandoahMarkRefsSuperCl inline void do_oop_work(T* p) { work(p); } public: - ShenandoahMarkUpdateRefsMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahMarkUpdateRefsMetadataClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) : ShenandoahMarkRefsSuperClosure(q, rp) {}; virtual void do_oop(narrowOop* p) { do_oop_work(p); } @@ -106,7 +115,7 @@ class ShenandoahMarkUpdateRefsMetadataDedupClosure : public ShenandoahMarkRefsSu inline void do_oop_work(T* p) { work(p); } public: - ShenandoahMarkUpdateRefsMetadataDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahMarkUpdateRefsMetadataDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) : ShenandoahMarkRefsSuperClosure(q, rp) {}; virtual void do_oop(narrowOop* p) { do_oop_work(p); } @@ -120,7 +129,7 @@ class ShenandoahMarkRefsClosure : public ShenandoahMarkRefsSuperClosure { inline void do_oop_work(T* p) { work(p); } public: - ShenandoahMarkRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahMarkRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) : ShenandoahMarkRefsSuperClosure(q, rp) {}; virtual void do_oop(narrowOop* p) { do_oop_work(p); } @@ -134,7 +143,7 @@ class ShenandoahMarkRefsDedupClosure : public ShenandoahMarkRefsSuperClosure { inline void do_oop_work(T* p) { work(p); } public: - ShenandoahMarkRefsDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahMarkRefsDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) : ShenandoahMarkRefsSuperClosure(q, rp) {}; virtual void do_oop(narrowOop* p) { do_oop_work(p); } @@ -148,7 +157,7 @@ class ShenandoahMarkResolveRefsClosure : public ShenandoahMarkRefsSuperClosure { inline void do_oop_work(T* p) { work(p); } public: - ShenandoahMarkResolveRefsClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahMarkResolveRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) : ShenandoahMarkRefsSuperClosure(q, rp) {}; virtual void do_oop(narrowOop* p) { do_oop_work(p); } @@ -162,7 +171,7 @@ class ShenandoahMarkRefsMetadataClosure : public ShenandoahMarkRefsSuperClosure inline void do_oop_work(T* p) { work(p); } public: - ShenandoahMarkRefsMetadataClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahMarkRefsMetadataClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) : ShenandoahMarkRefsSuperClosure(q, rp) {}; virtual void do_oop(narrowOop* p) { do_oop_work(p); } @@ -176,7 +185,7 @@ class ShenandoahMarkRefsMetadataDedupClosure : public ShenandoahMarkRefsSuperClo inline void do_oop_work(T* p) { work(p); } public: - ShenandoahMarkRefsMetadataDedupClosure(ShenandoahObjToScanQueue* q, ReferenceProcessor* rp) : + ShenandoahMarkRefsMetadataDedupClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) : ShenandoahMarkRefsSuperClosure(q, rp) {}; virtual void do_oop(narrowOop* p) { do_oop_work(p); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.inline.hpp index 1adebeaac0e..3476f65a7fe 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.inline.hpp @@ -30,7 +30,7 @@ template inline void ShenandoahMarkRefsSuperClosure::work(T *p) { - ShenandoahConcurrentMark::mark_through_ref(p, _heap, _queue, _mark_context); + ShenandoahConcurrentMark::mark_through_ref(p, _heap, _queue, _mark_context, _weak); } template diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp index 30c875551f8..d8866ebd6dd 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp @@ -153,16 +153,6 @@ void ShenandoahPacer::setup_for_idle() { * the allocators unnecessarily, allow them to run unimpeded. */ -void ShenandoahPacer::setup_for_preclean() { - assert(ShenandoahPacing, "Only be here when pacing is enabled"); - - size_t initial = _heap->max_capacity(); - restart_with(initial, 1.0); - - log_info(gc, ergo)("Pacer for Precleaning. Non-Taxable: " SIZE_FORMAT "%s", - byte_size_in_proper_unit(initial), proper_unit_for_byte_size(initial)); -} - void ShenandoahPacer::setup_for_reset() { assert(ShenandoahPacing, "Only be here when pacing is enabled"); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPacer.hpp b/src/hotspot/share/gc/shenandoah/shenandoahPacer.hpp index d177581ac78..6b2dd53ff76 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.hpp @@ -79,7 +79,6 @@ class ShenandoahPacer : public CHeapObj { void setup_for_updaterefs(); void setup_for_reset(); - void setup_for_preclean(); inline void report_mark(size_t words); inline void report_evac(size_t words); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp index 797fcb84789..b65746c3791 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp @@ -113,6 +113,7 @@ bool ShenandoahPhaseTimings::is_worker_phase(Phase phase) { case heap_iteration_roots: case conc_mark_roots: case conc_weak_roots_work: + case conc_weak_refs_work: case conc_strong_roots: return true; default: diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp index b1d702a3a50..9452cb63777 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp @@ -60,8 +60,6 @@ class outputStream; f(conc_mark_roots, " Roots ") \ SHENANDOAH_PAR_PHASE_DO(conc_mark_roots, " CM: ", f) \ \ - f(conc_preclean, "Concurrent Precleaning") \ - \ f(final_mark_gross, "Pause Final Mark (G)") \ f(final_mark, "Pause Final Mark (N)") \ f(update_roots, " Update Roots") \ @@ -82,6 +80,9 @@ class outputStream; f(init_evac, " Initial Evacuation") \ SHENANDOAH_PAR_PHASE_DO(evac_, " E: ", f) \ \ + f(conc_weak_refs, "Concurrent Weak References") \ + f(conc_weak_refs_work, " Process") \ + SHENANDOAH_PAR_PHASE_DO(conc_weak_refs_work_, " CWRF: ", f) \ f(conc_weak_roots, "Concurrent Weak Roots") \ f(conc_weak_roots_work, " Roots") \ SHENANDOAH_PAR_PHASE_DO(conc_weak_roots_work_, " CWR: ", f) \ diff --git a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp new file mode 100644 index 00000000000..9cdfa5d6e65 --- /dev/null +++ b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp @@ -0,0 +1,593 @@ +/* + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Red Hat, Inc. and/or its affiliates. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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/javaClasses.hpp" +#include "gc/shenandoah/shenandoahOopClosures.hpp" +#include "gc/shenandoah/shenandoahReferenceProcessor.hpp" +#include "gc/shenandoah/shenandoahThreadLocalData.hpp" +#include "gc/shenandoah/shenandoahUtils.hpp" +#include "runtime/atomic.hpp" +#include "logging/log.hpp" + +static ReferenceType reference_type(oop reference) { + return InstanceKlass::cast(reference->klass())->reference_type(); +} + +static const char* reference_type_name(ReferenceType type) { + switch (type) { + case REF_SOFT: + return "Soft"; + + case REF_WEAK: + return "Weak"; + + case REF_FINAL: + return "Final"; + + case REF_PHANTOM: + return "Phantom"; + + default: + ShouldNotReachHere(); + return NULL; + } +} + +template +static void set_oop_field(T* field, oop value); + +template <> +void set_oop_field(oop* field, oop value) { + *field = value; +} + +template <> +void set_oop_field(narrowOop* field, oop value) { + *field = CompressedOops::encode(value); +} + +static oop lrb(oop obj) { + if (obj != NULL && ShenandoahHeap::heap()->marking_context()->is_marked(obj)) { + return ShenandoahBarrierSet::barrier_set()->load_reference_barrier(obj); + } else { + return obj; + } +} + +template +static volatile T* reference_referent_addr(oop reference) { + return (volatile T*)java_lang_ref_Reference::referent_addr_raw(reference); +} + +template +static oop reference_referent(oop reference) { + T heap_oop = Atomic::load(reference_referent_addr(reference)); + return CompressedOops::decode(heap_oop); +} + +static void reference_set_referent(oop reference, oop referent) { + java_lang_ref_Reference::set_referent_raw(reference, referent); +} + +template +static T* reference_discovered_addr(oop reference) { + return reinterpret_cast(java_lang_ref_Reference::discovered_addr_raw(reference)); +} + +template +static oop reference_discovered(oop reference) { + T heap_oop = *reference_discovered_addr(reference); + return lrb(CompressedOops::decode(heap_oop)); +} + +template +static void reference_set_discovered(oop reference, oop discovered); + +template <> +void reference_set_discovered(oop reference, oop discovered) { + *reference_discovered_addr(reference) = discovered; +} + +template <> +void reference_set_discovered(oop reference, oop discovered) { + *reference_discovered_addr(reference) = CompressedOops::encode(discovered); +} + +template +static bool reference_cas_discovered(oop reference, oop discovered); + +template<> +bool reference_cas_discovered(oop reference, oop discovered) { + volatile narrowOop* addr = reinterpret_cast(java_lang_ref_Reference::discovered_addr_raw(reference)); + narrowOop compare = CompressedOops::encode(NULL); + narrowOop exchange = CompressedOops::encode(discovered); + return Atomic::cmpxchg(addr, compare, exchange) == compare; +} + +template<> +bool reference_cas_discovered(oop reference, oop discovered) { + volatile oop* addr = reinterpret_cast(java_lang_ref_Reference::discovered_addr_raw(reference)); + return Atomic::cmpxchg(addr, oop(NULL), discovered) == NULL; +} + +template +static T* reference_next_addr(oop reference) { + return reinterpret_cast(java_lang_ref_Reference::next_addr_raw(reference)); +} + +template +static oop reference_next(oop reference) { + T heap_oop = RawAccess<>::oop_load(reference_next_addr(reference)); + return lrb(CompressedOops::decode(heap_oop)); +} + +static void reference_set_next(oop reference, oop next) { + java_lang_ref_Reference::set_next_raw(reference, next); +} + +static void soft_reference_update_clock() { + const jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; + java_lang_ref_SoftReference::set_clock(now); +} + +ShenandoahRefProcThreadLocal::ShenandoahRefProcThreadLocal() : + _discovered_list(NULL), + _encountered_count(), + _discovered_count(), + _enqueued_count() { +} + +void ShenandoahRefProcThreadLocal::reset() { + _discovered_list = NULL; + _mark_closure = NULL; + for (uint i = 0; i < reference_type_count; i++) { + _encountered_count[i] = 0; + _discovered_count[i] = 0; + _enqueued_count[i] = 0; + } +} + +template +T* ShenandoahRefProcThreadLocal::discovered_list_addr() { + return reinterpret_cast(&_discovered_list); +} + +template <> +oop ShenandoahRefProcThreadLocal::discovered_list_head() const { + return *reinterpret_cast(&_discovered_list); +} + +template <> +oop ShenandoahRefProcThreadLocal::discovered_list_head() const { + return CompressedOops::decode(*reinterpret_cast(&_discovered_list)); +} + +template <> +void ShenandoahRefProcThreadLocal::set_discovered_list_head(oop head) { + *discovered_list_addr() = CompressedOops::encode(head); +} + +template <> +void ShenandoahRefProcThreadLocal::set_discovered_list_head(oop head) { + *discovered_list_addr() = head; +} + +ShenandoahReferenceProcessor::ShenandoahReferenceProcessor(uint max_workers) : + _soft_reference_policy(NULL), + _ref_proc_thread_locals(NEW_C_HEAP_ARRAY(ShenandoahRefProcThreadLocal, max_workers, mtGC)), + _pending_list(NULL), + _pending_list_tail(&_pending_list), + _iterate_discovered_list_id(0U) { + for (size_t i = 0; i < max_workers; i++) { + _ref_proc_thread_locals[i].reset(); + } +} + +void ShenandoahReferenceProcessor::reset_thread_locals() { + uint max_workers = ShenandoahHeap::heap()->max_workers(); + for (uint i = 0; i < max_workers; i++) { + _ref_proc_thread_locals[i].reset(); + } +} + +void ShenandoahReferenceProcessor::set_mark_closure(uint worker_id, ShenandoahMarkRefsSuperClosure* mark_closure) { + _ref_proc_thread_locals[worker_id].set_mark_closure(mark_closure); +} + +void ShenandoahReferenceProcessor::set_soft_reference_policy(bool clear) { + static AlwaysClearPolicy always_clear_policy; + static LRUMaxHeapPolicy lru_max_heap_policy; + + if (clear) { + log_info(gc, ref)("Clearing All SoftReferences"); + _soft_reference_policy = &always_clear_policy; + } else { + _soft_reference_policy = &lru_max_heap_policy; + } + + _soft_reference_policy->setup(); +} + +template +bool ShenandoahReferenceProcessor::is_inactive(oop reference, oop referent, ReferenceType type) const { + if (type == REF_FINAL) { + // A FinalReference is inactive if its next field is non-null. An application can't + // call enqueue() or clear() on a FinalReference. + return reference_next(reference) != NULL; + } else { + // A non-FinalReference is inactive if the referent is null. The referent can only + // be null if the application called Reference.enqueue() or Reference.clear(). + return referent == NULL; + } +} + +bool ShenandoahReferenceProcessor::is_strongly_live(oop referent) const { + return ShenandoahHeap::heap()->marking_context()->is_marked_strong(referent); +} + +bool ShenandoahReferenceProcessor::is_softly_live(oop reference, ReferenceType type) const { + if (type != REF_SOFT) { + // Not a SoftReference + return false; + } + + // Ask SoftReference policy + const jlong clock = java_lang_ref_SoftReference::clock(); + assert(clock != 0, "Clock not initialized"); + assert(_soft_reference_policy != NULL, "Policy not initialized"); + return !_soft_reference_policy->should_clear_reference(reference, clock); +} + +template +bool ShenandoahReferenceProcessor::should_discover(oop reference, ReferenceType type) const { + T* referent_addr = (T*) java_lang_ref_Reference::referent_addr_raw(reference); + T heap_oop = RawAccess<>::oop_load(referent_addr); + oop referent = CompressedOops::decode_not_null(heap_oop); + + if (is_inactive(reference, referent, type)) { + log_trace(gc,ref)("Reference inactive: " PTR_FORMAT, p2i(reference)); + return false; + } + + if (is_strongly_live(referent)) { + log_trace(gc,ref)("Reference strongly live: " PTR_FORMAT, p2i(reference)); + return false; + } + + if (is_softly_live(reference, type)) { + log_trace(gc,ref)("Reference softly live: " PTR_FORMAT, p2i(reference)); + return false; + } + + return true; +} + +template +bool ShenandoahReferenceProcessor::should_drop(oop reference, ReferenceType type) const { + const oop referent = reference_referent(reference); + if (referent == NULL) { + // Reference has been cleared, by a call to Reference.enqueue() + // or Reference.clear() from the application, which means we + // should drop the reference. + return true; + } + + // Check if the referent is still alive, in which case we should + // drop the reference. + if (type == REF_PHANTOM) { + return ShenandoahHeap::heap()->complete_marking_context()->is_marked(referent); + } else { + return ShenandoahHeap::heap()->complete_marking_context()->is_marked_strong(referent); + } +} + +template +void ShenandoahReferenceProcessor::make_inactive(oop reference, ReferenceType type) const { + if (type == REF_FINAL) { + // Don't clear referent. It is needed by the Finalizer thread to make the call + // to finalize(). A FinalReference is instead made inactive by self-looping the + // next field. An application can't call FinalReference.enqueue(), so there is + // no race to worry about when setting the next field. + assert(reference_next(reference) == NULL, "Already inactive"); + assert(ShenandoahHeap::heap()->marking_context()->is_marked(reference_referent(reference)), "only make inactive final refs with alive referents"); + reference_set_next(reference, reference); + } else { + // Clear referent + reference_set_referent(reference, NULL); + } +} + +template +bool ShenandoahReferenceProcessor::discover(oop reference, ReferenceType type, uint worker_id) { + if (!should_discover(reference, type)) { + // Not discovered + return false; + } + + if (reference_discovered(reference) != NULL) { + // Already discovered. This can happen if the reference is marked finalizable first, and then strong, + // in which case it will be seen 2x by marking. + log_trace(gc,ref)("Reference already discovered: " PTR_FORMAT, p2i(reference)); + return true; + } + + if (type == REF_FINAL) { + ShenandoahMarkRefsSuperClosure* cl = _ref_proc_thread_locals[worker_id].mark_closure(); + bool weak = cl->is_weak(); + cl->set_weak(true); + if (UseCompressedOops) { + cl->do_oop(reinterpret_cast(java_lang_ref_Reference::referent_addr_raw(reference))); + } else { + cl->do_oop(reinterpret_cast(java_lang_ref_Reference::referent_addr_raw(reference))); + } + cl->set_weak(weak); + } + + // Add reference to discovered list + assert(worker_id != ShenandoahThreadLocalData::INVALID_WORKER_ID, "need valid worker ID"); + ShenandoahRefProcThreadLocal& refproc_data = _ref_proc_thread_locals[worker_id]; + oop discovered_head = refproc_data.discovered_list_head(); + if (discovered_head == NULL) { + // Self-loop tail of list. We distinguish discovered from not-discovered references by looking at their + // discovered field: if it is NULL, then it is not-yet discovered, otherwise it is discovered + discovered_head = reference; + } + if (reference_cas_discovered(reference, discovered_head)) { + refproc_data.set_discovered_list_head(reference); + assert(refproc_data.discovered_list_head() == reference, "reference must be new discovered head"); + log_trace(gc, ref)("Discovered Reference: " PTR_FORMAT " (%s)", p2i(reference), reference_type_name(type)); + _ref_proc_thread_locals[worker_id].inc_discovered(type); + } + return true; +} + +bool ShenandoahReferenceProcessor::discover_reference(oop reference, ReferenceType type) { + if (!RegisterReferences) { + // Reference processing disabled + return false; + } + + log_trace(gc, ref)("Encountered Reference: " PTR_FORMAT " (%s)", p2i(reference), reference_type_name(type)); + uint worker_id = ShenandoahThreadLocalData::worker_id(Thread::current()); + _ref_proc_thread_locals->inc_encountered(type); + + if (UseCompressedOops) { + return discover(reference, type, worker_id); + } else { + return discover(reference, type, worker_id); + } +} + +template +oop ShenandoahReferenceProcessor::drop(oop reference, ReferenceType type) { + log_trace(gc, ref)("Dropped Reference: " PTR_FORMAT " (%s)", p2i(reference), reference_type_name(type)); + + assert(reference_referent(reference) == NULL || + ShenandoahHeap::heap()->marking_context()->is_marked(reference_referent(reference)), "only drop references with alive referents"); + + // Unlink and return next in list + oop next = reference_discovered(reference); + reference_set_discovered(reference, NULL); + return next; +} + +template +T* ShenandoahReferenceProcessor::keep(oop reference, ReferenceType type, uint worker_id) { + log_trace(gc, ref)("Enqueued Reference: " PTR_FORMAT " (%s)", p2i(reference), reference_type_name(type)); + + // Update statistics + _ref_proc_thread_locals[worker_id].inc_enqueued(type); + + // Make reference inactive + make_inactive(reference, type); + + // Return next in list + return reference_discovered_addr(reference); +} + +template +void ShenandoahReferenceProcessor::process_references(ShenandoahRefProcThreadLocal& refproc_data, uint worker_id) {; + log_trace(gc, ref)("Processing discovered list #%u : " PTR_FORMAT, worker_id, p2i(refproc_data.discovered_list_head())); + T* list = refproc_data.discovered_list_addr(); + // The list head is basically a GC root, we need to resolve and update it, + // otherwise we will later swap a from-space ref into Universe::pending_list(). + if (!CompressedOops::is_null(*list)) { + oop first_resolved = lrb(CompressedOops::decode_not_null(*list)); + set_oop_field(list, first_resolved); + } + T* p = list; + while (true) { + const oop reference = lrb(CompressedOops::decode(*p)); + if (reference == NULL) { + break; + } + log_trace(gc, ref)("Processing reference: " PTR_FORMAT, p2i(reference)); + const ReferenceType type = reference_type(reference); + + if (should_drop(reference, type)) { + set_oop_field(p, drop(reference, type)); + } else { + p = keep(reference, type, worker_id); + } + + const oop discovered = lrb(reference_discovered(reference)); + if (reference == discovered) { + // Reset terminating self-loop to NULL + reference_set_discovered(reference, oop(NULL)); + break; + } + } + + // Prepend discovered references to internal pending list + if (!CompressedOops::is_null(*list)) { + oop head = lrb(CompressedOops::decode_not_null(*list)); + shenandoah_assert_not_in_cset_except(&head, head, ShenandoahHeap::heap()->cancelled_gc() || !ShenandoahLoadRefBarrier); + oop prev = Atomic::xchg(&_pending_list, head); + RawAccess<>::oop_store(p, prev); + if (prev == NULL) { + // First to prepend to list, record tail + _pending_list_tail = reinterpret_cast(p); + } + + // Clear discovered list + set_oop_field(list, oop(NULL)); + } +} + +void ShenandoahReferenceProcessor::work() { + // Process discovered references + uint max_workers = ShenandoahHeap::heap()->max_workers(); + uint worker_id = Atomic::add(&_iterate_discovered_list_id, 1U) - 1; + while (worker_id < max_workers) { + if (UseCompressedOops) { + process_references(_ref_proc_thread_locals[worker_id], worker_id); + } else { + process_references(_ref_proc_thread_locals[worker_id], worker_id); + } + worker_id = Atomic::add(&_iterate_discovered_list_id, 1U) - 1; + } +} + +class ShenandoahReferenceProcessorTask : public AbstractGangTask { +private: + ShenandoahReferenceProcessor* const _reference_processor; + +public: + ShenandoahReferenceProcessorTask(ShenandoahReferenceProcessor* reference_processor) : + AbstractGangTask("ShenandoahReferenceProcessorTask"), + _reference_processor(reference_processor) { + } + + virtual void work(uint worker_id) { + ShenandoahConcurrentWorkerSession worker_session(worker_id); + _reference_processor->work(); + } +}; + +void ShenandoahReferenceProcessor::process_references(WorkGang* workers, bool concurrent) { + + Atomic::release_store_fence(&_iterate_discovered_list_id, 0U); + + // Process discovered lists + ShenandoahReferenceProcessorTask task(this); + workers->run_task(&task); + + // Update SoftReference clock + soft_reference_update_clock(); + + // Collect, log and trace statistics + collect_statistics(); + + enqueue_references(concurrent); +} + +void ShenandoahReferenceProcessor::enqueue_references_locked() { + // Prepend internal pending list to external pending list + shenandoah_assert_not_in_cset_except(&_pending_list, _pending_list, ShenandoahHeap::heap()->cancelled_gc() || !ShenandoahLoadRefBarrier); + if (UseCompressedOops) { + *reinterpret_cast(_pending_list_tail) = CompressedOops::encode(Universe::swap_reference_pending_list(_pending_list)); + } else { + *reinterpret_cast(_pending_list_tail) = Universe::swap_reference_pending_list(_pending_list); + } +} + +void ShenandoahReferenceProcessor::enqueue_references(bool concurrent) { + if (_pending_list == NULL) { + // Nothing to enqueue + return; + } + + if (!concurrent) { + // When called from mark-compact or degen-GC, the locking is done by the VMOperation, + enqueue_references_locked(); + } else { + // Heap_lock protects external pending list + MonitorLocker ml(Heap_lock, Mutex::_no_safepoint_check_flag); + + enqueue_references_locked(); + + // Notify ReferenceHandler thread + ml.notify_all(); + } + + // Reset internal pending list + _pending_list = NULL; + _pending_list_tail = &_pending_list; +} + +template +void ShenandoahReferenceProcessor::clean_discovered_list(T* list) { + T discovered = *list; + while (!CompressedOops::is_null(discovered)) { + oop discovered_ref = CompressedOops::decode_not_null(discovered); + set_oop_field(list, oop(NULL)); + list = reference_discovered_addr(discovered_ref); + discovered = *list; + } +} + +void ShenandoahReferenceProcessor::abandon_partial_discovery() { + uint max_workers = ShenandoahHeap::heap()->max_workers(); + for (uint index = 0; index < max_workers; index++) { + if (UseCompressedOops) { + clean_discovered_list(_ref_proc_thread_locals[index].discovered_list_addr()); + } else { + clean_discovered_list(_ref_proc_thread_locals[index].discovered_list_addr()); + } + } + if (_pending_list != NULL) { + oop pending = _pending_list; + _pending_list = NULL; + if (UseCompressedOops) { + narrowOop* list = reference_discovered_addr(pending); + clean_discovered_list(list); + } else { + oop* list = reference_discovered_addr(pending); + clean_discovered_list(list); + } + } + _pending_list_tail = &_pending_list; +} + +void ShenandoahReferenceProcessor::collect_statistics() { + Counters encountered = {}; + Counters discovered = {}; + Counters enqueued = {}; + uint max_workers = ShenandoahHeap::heap()->max_workers(); + for (uint i = 0; i < max_workers; i++) { + for (size_t type = 0; type < reference_type_count; type++) { + encountered[type] += _ref_proc_thread_locals[i].encountered((ReferenceType)type); + discovered[type] += _ref_proc_thread_locals[i].discovered((ReferenceType)type); + enqueued[type] += _ref_proc_thread_locals[i].enqueued((ReferenceType)type); + } + } + log_info(gc,ref)("Encountered references: Soft: " SIZE_FORMAT ", Weak: " SIZE_FORMAT ", Final: " SIZE_FORMAT ", Phantom: " SIZE_FORMAT, + encountered[REF_SOFT], encountered[REF_WEAK], encountered[REF_FINAL], encountered[REF_PHANTOM]); + log_info(gc,ref)("Discovered references: Soft: " SIZE_FORMAT ", Weak: " SIZE_FORMAT ", Final: " SIZE_FORMAT ", Phantom: " SIZE_FORMAT, + discovered[REF_SOFT], discovered[REF_WEAK], discovered[REF_FINAL], discovered[REF_PHANTOM]); + log_info(gc,ref)("Enqueued references: Soft: " SIZE_FORMAT ", Weak: " SIZE_FORMAT ", Final: " SIZE_FORMAT ", Phantom: " SIZE_FORMAT, + enqueued[REF_SOFT], enqueued[REF_WEAK], enqueued[REF_FINAL], enqueued[REF_PHANTOM]); +} \ No newline at end of file diff --git a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.hpp b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.hpp new file mode 100644 index 00000000000..40dbbc37f6e --- /dev/null +++ b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.hpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Red Hat, Inc. and/or its affiliates. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please 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_VM_GC_SHENANDOAH_SHENANDOAHREFERENCEPROCESSOR_HPP +#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHREFERENCEPROCESSOR_HPP + +#include "gc/shared/referenceDiscoverer.hpp" +#include "memory/allocation.hpp" + +class ShenandoahMarkRefsSuperClosure; +class WorkGang; + +static const size_t reference_type_count = REF_PHANTOM + 1; +typedef size_t Counters[reference_type_count]; + +/* + * Shenandoah concurrent reference processing + * + * Concurrent reference processing is made up of two main phases: + * 1. Concurrent reference marking: Discover all j.l.r.Reference objects and determine reachability of all live objects. + * 2. Concurrent reference processing: For all discoved j.l.r.References, determine whether to keep them alive or clean + * them. Also, clean and enqueue relevant references concurrently. + * + * Concurrent reference marking: + * The goal here is to establish the kind of reachability for all objects on the heap. We distinguish two kinds of + * reachability: + * - An object is 'strongly reachable' if it can be found by searching transitively from GC roots. + * - An object is 'finalizably reachable' if it is not strongly reachable, but can be found by searching + * from the referents of FinalReferences. + * + * These reachabilities are implemented in shenandoahMarkBitMap.* + * Conceptually, marking starts with a strong wavefront at the GC roots. Whenever a Reference object is encountered, + * it may be discovered by the ShenandoahReferenceProcessor. If it is discovered, it + * gets added to the discovered list, and that wavefront stops there, except when it's a FinalReference, in which + * case the wavefront switches to finalizable marking and marks through the referent. When a Reference is not + * discovered, e.g. if it's a SoftReference that is not eligible for discovery, then marking continues as if the + * Reference was a regular object. Whenever a strong wavefront encounters an object that is already marked + * finalizable, then the object's reachability is upgraded to strong. + * + * Concurrent reference processing: + * This happens after the concurrent marking phase and the final marking pause, when reachability for all objects + * has been established. + * The discovered list is scanned and for each reference is decided what to do: + * - If the referent is reachable (finalizable for PhantomReference, strong for all others), then the Reference + * is dropped from the discovered list and otherwise ignored + * - Otherwise its referent becomes cleared and the Reference added to the pending list, from which it will later + * be processed (e.g. enqueued in its ReferenceQueue) by the Java ReferenceHandler thread. + * + * In order to prevent resurrection by Java threads calling Reference.get() concurrently while we are clearing + * referents, we employ a special barrier, the native LRB, which returns NULL when the referent is unreachable. + */ + +class ShenandoahRefProcThreadLocal : public CHeapObj { +private: + void* _discovered_list; + ShenandoahMarkRefsSuperClosure* _mark_closure; + Counters _encountered_count; + Counters _discovered_count; + Counters _enqueued_count; + +public: + ShenandoahRefProcThreadLocal(); + + ShenandoahRefProcThreadLocal(const ShenandoahRefProcThreadLocal&) = delete; // non construction-copyable + ShenandoahRefProcThreadLocal& operator=(const ShenandoahRefProcThreadLocal&) = delete; // non copyable + + void reset(); + + ShenandoahMarkRefsSuperClosure* mark_closure() const { + return _mark_closure; + } + + void set_mark_closure(ShenandoahMarkRefsSuperClosure* mark_closure) { + _mark_closure = mark_closure; + } + + template + T* discovered_list_addr(); + template + oop discovered_list_head() const; + template + void set_discovered_list_head(oop head); + + size_t encountered(ReferenceType type) const { + return _encountered_count[type]; + } + size_t discovered(ReferenceType type) const { + return _discovered_count[type]; + } + size_t enqueued(ReferenceType type) const { + return _enqueued_count[type]; + } + + void inc_encountered(ReferenceType type) { + _encountered_count[type]++; + } + void inc_discovered(ReferenceType type) { + _discovered_count[type]++; + } + void inc_enqueued(ReferenceType type) { + _enqueued_count[type]++; + } +}; + +class ShenandoahReferenceProcessor : public ReferenceDiscoverer { +private: + ReferencePolicy* _soft_reference_policy; + + ShenandoahRefProcThreadLocal* _ref_proc_thread_locals; + + oop _pending_list; + void* _pending_list_tail; // T* + + volatile uint _iterate_discovered_list_id; + + template + bool is_inactive(oop reference, oop referent, ReferenceType type) const; + bool is_strongly_live(oop referent) const; + bool is_softly_live(oop reference, ReferenceType type) const; + + template + bool should_discover(oop reference, ReferenceType type) const; + template + bool should_drop(oop reference, ReferenceType type) const; + + template + void make_inactive(oop reference, ReferenceType type) const; + + template + bool discover(oop reference, ReferenceType type, uint worker_id); + + template + oop drop(oop reference, ReferenceType type); + template + T* keep(oop reference, ReferenceType type, uint worker_id); + + template + void process_references(ShenandoahRefProcThreadLocal& refproc_data, uint worker_id); + void enqueue_references_locked(); + void enqueue_references(bool concurrent); + + void collect_statistics(); + + template + void clean_discovered_list(T* list); + +public: + ShenandoahReferenceProcessor(uint max_workers); + + void reset_thread_locals(); + void set_mark_closure(uint worker_id, ShenandoahMarkRefsSuperClosure* mark_closure); + + void set_soft_reference_policy(bool clear); + + bool discover_reference(oop obj, ReferenceType type) override; + + void process_references(WorkGang* workers, bool concurrent); + + void work(); + + void abandon_partial_discovery(); +}; + +#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHREFERENCEPROCESSOR_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp index 38135a5e33d..5fb69eb9b0f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.cpp @@ -66,6 +66,10 @@ JRT_LEAF(void, ShenandoahRuntime::shenandoah_clone_barrier(oopDesc* src)) ShenandoahBarrierSet::barrier_set()->clone_barrier(s); JRT_END -JRT_LEAF(oopDesc*, ShenandoahRuntime::load_reference_barrier_native(oopDesc * src, oop* load_addr)) - return (oopDesc*) ShenandoahBarrierSet::barrier_set()->load_reference_barrier_native(oop(src), load_addr); +JRT_LEAF(oopDesc*, ShenandoahRuntime::load_reference_barrier_weak(oopDesc * src, oop* load_addr)) + return (oopDesc*) ShenandoahBarrierSet::barrier_set()->load_reference_barrier(oop(src), load_addr); +JRT_END + +JRT_LEAF(oopDesc*, ShenandoahRuntime::load_reference_barrier_weak_narrow(oopDesc * src, narrowOop* load_addr)) + return (oopDesc*) ShenandoahBarrierSet::barrier_set()->load_reference_barrier(oop(src), load_addr); JRT_END diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp index a0b2582d4e7..c0446d32168 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp @@ -41,7 +41,8 @@ class ShenandoahRuntime : public AllStatic { static oopDesc* load_reference_barrier(oopDesc* src, oop* load_addr); static oopDesc* load_reference_barrier_narrow(oopDesc* src, narrowOop* load_addr); - static oopDesc* load_reference_barrier_native(oopDesc* src, oop* load_addr); + static oopDesc* load_reference_barrier_weak(oopDesc* src, oop* load_addr); + static oopDesc* load_reference_barrier_weak_narrow(oopDesc* src, narrowOop* load_addr); static void shenandoah_clone_barrier(oopDesc* src); }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.hpp b/src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.hpp index 3ad8f779e1f..bc38a0936eb 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.hpp @@ -74,11 +74,15 @@ class BufferedOverflowTaskQueue: public OverflowTaskQueue // that the block has the size of 2^pow. This requires for pow to have only 5 bits (2^32) to encode // all possible arrays. // -// |---------oop---------|-pow-|--chunk---| +// |xx-------oop---------|-pow-|--chunk---| // 0 49 54 64 // // By definition, chunk == 0 means "no chunk", i.e. chunking starts from 1. // +// Lower bits of oop are reserved to handle "skip_live" and "strong" properties. Since this encoding +// stores uncompressed oops, those bits are always available. These bits default to zero for "skip_live" +// and "weak". This aligns with their frequent values: strong/counted-live references. +// // This encoding gives a few interesting benefits: // // a) Encoding/decoding regular oops is very simple, because the upper bits are zero in that task: @@ -145,7 +149,9 @@ class ShenandoahMarkTask static const uint8_t pow_shift = oop_bits; static const uint8_t chunk_shift = oop_bits + pow_bits; - static const uintptr_t oop_extract_mask = right_n_bits(oop_bits); + static const uintptr_t oop_extract_mask = right_n_bits(oop_bits) - 3; + static const uintptr_t skip_live_extract_mask = 1 << 0; + static const uintptr_t weak_extract_mask = 1 << 1; static const uintptr_t chunk_pow_extract_mask = ~right_n_bits(oop_bits); static const int chunk_range_mask = right_n_bits(chunk_bits); @@ -169,9 +175,24 @@ class ShenandoahMarkTask return (int) ((val >> pow_shift) & pow_range_mask); } - inline uintptr_t encode_oop(oop obj) const { + inline bool decode_weak(uintptr_t val) const { + return (val & weak_extract_mask) != 0; + } + + inline bool decode_cnt_live(uintptr_t val) const { + return (val & skip_live_extract_mask) == 0; + } + + inline uintptr_t encode_oop(oop obj, bool skip_live, bool weak) const { STATIC_ASSERT(oop_shift == 0); - return cast_from_oop(obj); + uintptr_t encoded = cast_from_oop(obj); + if (skip_live) { + encoded |= skip_live_extract_mask; + } + if (weak) { + encoded |= weak_extract_mask; + } + return encoded; } inline uintptr_t encode_chunk(int chunk) const { @@ -183,19 +204,23 @@ class ShenandoahMarkTask } public: - ShenandoahMarkTask(oop o = NULL) { - uintptr_t enc = encode_oop(o); - assert(decode_oop(enc) == o, "oop encoding should work: " PTR_FORMAT, p2i(o)); - assert(decode_not_chunked(enc), "task should not be chunked"); + ShenandoahMarkTask(oop o = NULL, bool skip_live = false, bool weak = false) { + uintptr_t enc = encode_oop(o, skip_live, weak); + assert(decode_oop(enc) == o, "oop encoding should work: " PTR_FORMAT, p2i(o)); + assert(decode_cnt_live(enc) == !skip_live, "skip_live encoding should work"); + assert(decode_weak(enc) == weak, "weak encoding should work"); + assert(decode_not_chunked(enc), "task should not be chunked"); _obj = enc; } - ShenandoahMarkTask(oop o, int chunk, int pow) { - uintptr_t enc_oop = encode_oop(o); + ShenandoahMarkTask(oop o, bool skip_live, bool weak, int chunk, int pow) { + uintptr_t enc_oop = encode_oop(o, skip_live, weak); uintptr_t enc_chunk = encode_chunk(chunk); uintptr_t enc_pow = encode_pow(pow); uintptr_t enc = enc_oop | enc_chunk | enc_pow; assert(decode_oop(enc) == o, "oop encoding should work: " PTR_FORMAT, p2i(o)); + assert(decode_cnt_live(enc) == !skip_live, "skip_live should be true for chunked tasks"); + assert(decode_weak(enc) == weak, "weak encoding should work"); assert(decode_chunk(enc) == chunk, "chunk encoding should work: %d", chunk); assert(decode_pow(enc) == pow, "pow encoding should work: %d", pow); assert(!decode_not_chunked(enc), "task should be chunked"); @@ -210,6 +235,8 @@ class ShenandoahMarkTask inline int pow() const { return decode_pow(_obj); } inline bool is_not_chunked() const { return decode_not_chunked(_obj); } + inline bool is_weak() const { return decode_weak(_obj); } + inline bool count_liveness() const { return decode_cnt_live(_obj); } DEBUG_ONLY(bool is_valid() const;) // Tasks to be pushed/popped must be valid. @@ -225,20 +252,23 @@ class ShenandoahMarkTask class ShenandoahMarkTask { private: - enum { - chunk_bits = 10, - pow_bits = 5, - }; + static const uint8_t chunk_bits = 10; + static const uint8_t pow_bits = 5; + + static const int chunk_max = nth_bit(chunk_bits) - 1; + static const int pow_max = nth_bit(pow_bits) - 1; oop _obj; + bool _skip_live; + bool _weak; int _chunk; int _pow; public: - ShenandoahMarkTask(oop o = NULL, int chunk = 0, int pow = 0): - _obj(o), _chunk(chunk), _pow(pow) { - assert(0 <= chunk && chunk < nth_bit(chunk_bits), "chunk is sane: %d", chunk); - assert(0 <= pow && pow < nth_bit(pow_bits), "pow is sane: %d", pow); + ShenandoahMarkTask(oop o = NULL, bool skip_live = false, bool weak = false, int chunk = 0, int pow = 0): + _obj(o), _skip_live(skip_live), _weak(weak), _chunk(chunk), _pow(pow) { + assert(0 <= chunk && chunk <= chunk_max, "chunk is in range: %d", chunk); + assert(0 <= pow && pow <= pow_max, "pow is in range: %d", pow); } // Trivially copyable. @@ -247,6 +277,8 @@ class ShenandoahMarkTask inline int chunk() const { return _chunk; } inline int pow() const { return _pow; } inline bool is_not_chunked() const { return _chunk == 0; } + inline bool is_weak() const { return _weak; } + inline bool count_liveness() const { return !_skip_live; } DEBUG_ONLY(bool is_valid() const;) // Tasks to be pushed/popped must be valid. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp index 9624d4c5e8a..b3a4aef6426 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp @@ -59,9 +59,9 @@ class VM_ShenandoahInitMark: public VM_ShenandoahOperation { virtual void doit(); }; -class VM_ShenandoahFinalMarkStartEvac: public VM_ShenandoahReferenceOperation { +class VM_ShenandoahFinalMarkStartEvac: public VM_ShenandoahOperation { public: - VM_ShenandoahFinalMarkStartEvac() : VM_ShenandoahReferenceOperation() {}; + VM_ShenandoahFinalMarkStartEvac() : VM_ShenandoahOperation() {}; VM_Operation::VMOp_Type type() const { return VMOp_ShenandoahFinalMarkStartEvac; } const char* name() const { return "Shenandoah Final Mark and Start Evacuation"; } virtual void doit(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp index 9eb5d43fd3c..fa464496ec0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp @@ -47,6 +47,17 @@ #undef verify_oop #endif +static bool is_instance_ref_klass(Klass* k) { + return k->is_instance_klass() && InstanceKlass::cast(k)->reference_type() != REF_NONE; +} + +class ShenandoahIgnoreReferenceDiscoverer : public ReferenceDiscoverer { +public: + virtual bool discover_reference(oop obj, ReferenceType type) { + return true; + } +}; + class ShenandoahVerifyOopClosure : public BasicOopIterateClosure { private: const char* _phase; @@ -68,7 +79,12 @@ class ShenandoahVerifyOopClosure : public BasicOopIterateClosure { _map(map), _ld(ld), _interior_loc(NULL), - _loc(NULL) { } + _loc(NULL) { + if (options._verify_marked == ShenandoahVerifier::_verify_marked_complete_except_references || + options._verify_marked == ShenandoahVerifier::_verify_marked_disable) { + set_ref_discoverer_internal(new ShenandoahIgnoreReferenceDiscoverer()); + } + } private: void check(ShenandoahAsserts::SafeLevel level, oop obj, bool test, const char* label) { @@ -82,7 +98,9 @@ class ShenandoahVerifyOopClosure : public BasicOopIterateClosure { T o = RawAccess<>::oop_load(p); if (!CompressedOops::is_null(o)) { oop obj = CompressedOops::decode_not_null(o); - + if (is_instance_ref_klass(obj->klass())) { + obj = ShenandoahForwarding::get_forwardee(obj); + } // Single threaded verification can use faster non-atomic stack and bitmap // methods. // @@ -208,6 +226,10 @@ class ShenandoahVerifyOopClosure : public BasicOopIterateClosure { check(ShenandoahAsserts::_safe_all, obj, _heap->complete_marking_context()->is_marked(obj), "Must be marked in complete bitmap"); break; + case ShenandoahVerifier::_verify_marked_complete_except_references: + check(ShenandoahAsserts::_safe_all, obj, _heap->complete_marking_context()->is_marked(obj), + "Must be marked in complete bitmap, except j.l.r.Reference referents"); + break; default: assert(false, "Unhandled mark verification"); } @@ -526,19 +548,19 @@ class ShenandoahVerifierMarkedRegionTask : public AbstractGangTask { virtual void work_regular(ShenandoahHeapRegion *r, ShenandoahVerifierStack &stack, ShenandoahVerifyOopClosure &cl) { size_t processed = 0; - MarkBitMap* mark_bit_map = _heap->complete_marking_context()->mark_bit_map(); - HeapWord* tams = _heap->complete_marking_context()->top_at_mark_start(r); + ShenandoahMarkingContext* ctx = _heap->complete_marking_context(); + HeapWord* tams = ctx->top_at_mark_start(r); // Bitmaps, before TAMS if (tams > r->bottom()) { HeapWord* start = r->bottom(); - HeapWord* addr = mark_bit_map->get_next_marked_addr(start, tams); + HeapWord* addr = ctx->get_next_marked_addr(start, tams); while (addr < tams) { verify_and_follow(addr, stack, cl, &processed); addr += 1; if (addr < tams) { - addr = mark_bit_map->get_next_marked_addr(addr, tams); + addr = ctx->get_next_marked_addr(addr, tams); } } } @@ -566,9 +588,10 @@ class ShenandoahVerifierMarkedRegionTask : public AbstractGangTask { // Verify everything reachable from that object too, hopefully realizing // everything was already marked, and never touching further: - cl.verify_oops_from(obj); - (*processed)++; - + if (!is_instance_ref_klass(obj->klass())) { + cl.verify_oops_from(obj); + (*processed)++; + } while (!stack.is_empty()) { ShenandoahVerifierTask task = stack.pop(); cl.verify_oops_from(task.obj()); @@ -718,7 +741,7 @@ void ShenandoahVerifier::verify_at_safepoint(const char *label, // version size_t count_marked = 0; - if (ShenandoahVerifyLevel >= 4 && marked == _verify_marked_complete) { + if (ShenandoahVerifyLevel >= 4 && (marked == _verify_marked_complete || marked == _verify_marked_complete_except_references)) { guarantee(_heap->marking_context()->is_complete(), "Marking context should be complete"); ShenandoahVerifierMarkedRegionTask task(_verification_bit_map, ld, label, options); _heap->workers()->run_task(&task); @@ -793,11 +816,11 @@ void ShenandoahVerifier::verify_after_concmark() { verify_at_safepoint( "After Mark", _verify_forwarded_none, // no forwarded references - _verify_marked_complete, // bitmaps as precise as we can get + _verify_marked_complete_except_references, // bitmaps as precise as we can get, except dangling j.l.r.Refs _verify_cset_none, // no references to cset anymore _verify_liveness_complete, // liveness data must be complete here _verify_regions_disable, // trash regions not yet recycled - _verify_gcstate_stable, // mark should have stabilized the heap + _verify_gcstate_stable, // mark should have stabilized the heap _verify_all_weak_roots ); } @@ -810,12 +833,12 @@ void ShenandoahVerifier::verify_before_evacuation() { verify_at_safepoint( "Before Evacuation", - _verify_forwarded_none, // no forwarded references - _verify_marked_complete, // walk over marked objects too - _verify_cset_disable, // non-forwarded references to cset expected - _verify_liveness_complete, // liveness data must be complete here - _verify_regions_disable, // trash regions not yet recycled - _verify_gcstate_stable, // mark should have stabilized the heap + _verify_forwarded_none, // no forwarded references + _verify_marked_complete_except_references, // walk over marked objects too + _verify_cset_disable, // non-forwarded references to cset expected + _verify_liveness_complete, // liveness data must be complete here + _verify_regions_disable, // trash regions not yet recycled + _verify_gcstate_stable, // mark should have stabilized the heap verify_weak_roots ); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp index bb5d8ff9708..b9844715197 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp @@ -65,7 +65,11 @@ class ShenandoahVerifier : public CHeapObj { _verify_marked_incomplete, // Objects should be marked in "complete" bitmap. - _verify_marked_complete + _verify_marked_complete, + + // Objects should be marked in "complete" bitmap, except j.l.r.Reference referents, which + // may be dangling after marking but before conc-weakrefs-processing. + _verify_marked_complete_except_references } VerifyMarked; typedef enum { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp index 54cd8cfcc00..867dbc6aa8c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp @@ -32,6 +32,7 @@ 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; @@ -63,13 +64,23 @@ uint ShenandoahWorkerPolicy::calc_workers_for_final_marking() { return _prev_par_marking; } +// 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; +} + // 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()); + WorkerPolicy::calc_active_conc_workers(ConcGCThreads, + active_workers, + Threads::number_of_non_daemon_threads()); return _prev_conc_root_proc; } @@ -123,11 +134,6 @@ uint ShenandoahWorkerPolicy::calc_workers_for_final_update_ref() { return _prev_par_update_ref; } -uint ShenandoahWorkerPolicy::calc_workers_for_conc_preclean() { - // Precleaning is single-threaded - return 1; -} - uint ShenandoahWorkerPolicy::calc_workers_for_conc_cleanup() { uint active_workers = (_prev_conc_cleanup == 0) ? ConcGCThreads : _prev_conc_cleanup; _prev_conc_cleanup = diff --git a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp index 6a7abbd8fef..10a6fec6535 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp @@ -32,6 +32,7 @@ class ShenandoahWorkerPolicy : AllStatic { 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; @@ -53,6 +54,9 @@ class ShenandoahWorkerPolicy : AllStatic { // Calculate workers for concurrent root processing static uint calc_workers_for_conc_root_processing(); + // Calculate workers for concurrent refs processing + static uint calc_workers_for_conc_refs_processing(); + // Calculate workers for concurrent evacuation (concurrent GC) static uint calc_workers_for_conc_evac(); @@ -68,9 +72,6 @@ class ShenandoahWorkerPolicy : AllStatic { // Calculate workers for parallel/final reference update static uint calc_workers_for_final_update_ref(); - // Calculate workers for concurrent precleaning - static uint calc_workers_for_conc_preclean(); - // Calculate workers for concurrent cleanup static uint calc_workers_for_conc_cleanup(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp index 5417cb5a9fc..113e90cb0f3 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp @@ -76,13 +76,6 @@ " compact - run GC more frequently and with deeper targets to " \ "free up more memory.") \ \ - product(uintx, ShenandoahRefProcFrequency, 5, EXPERIMENTAL, \ - "Process process weak (soft, phantom, finalizers) references " \ - "every Nth cycle. Normally affects concurrent GC cycles only, " \ - "as degenerated and full GCs would try to process references " \ - "regardless. Set to zero to disable reference processing " \ - "completely.") \ - \ 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 " \ @@ -313,11 +306,6 @@ "Forcefully flush non-empty SATB buffers at this interval. " \ "Time is in milliseconds.") \ \ - product(bool, ShenandoahPreclean, true, DIAGNOSTIC, \ - "Do concurrent preclean phase before final mark: process " \ - "definitely alive references to avoid dealing with them during " \ - "pause.") \ - \ product(bool, ShenandoahSuspendibleWorkers, false, EXPERIMENTAL, \ "Suspend concurrent GC worker threads at safepoints") \ \ diff --git a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp index f52fcd940ca..bfb8a17e872 100644 --- a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp +++ b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp @@ -55,7 +55,7 @@ bool ZBarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) { // Heal oops and disarm ZNMethodOopClosure cl; - ZNMethod::nmethod_oops_do(nm, &cl); + ZNMethod::nmethod_oops_do_inner(nm, &cl); disarm(nm); return true; diff --git a/src/hotspot/share/gc/z/zForwardingAllocator.inline.hpp b/src/hotspot/share/gc/z/zForwardingAllocator.inline.hpp index ed191bb025c..eea8110b1a5 100644 --- a/src/hotspot/share/gc/z/zForwardingAllocator.inline.hpp +++ b/src/hotspot/share/gc/z/zForwardingAllocator.inline.hpp @@ -25,6 +25,7 @@ #define SHARE_GC_Z_ZFORWARDINGALLOCATOR_INLINE_HPP #include "gc/z/zForwardingAllocator.hpp" +#include "runtime/atomic.hpp" #include "utilities/debug.hpp" inline size_t ZForwardingAllocator::size() const { @@ -36,9 +37,8 @@ inline bool ZForwardingAllocator::is_full() const { } inline void* ZForwardingAllocator::alloc(size_t size) { - char* const addr = _top; - _top += size; - assert(_top <= _end, "Allocation should never fail"); + char* const addr = Atomic::fetch_and_add(&_top, size); + assert(addr + size <= _end, "Allocation should never fail"); return addr; } diff --git a/src/hotspot/share/gc/z/zForwardingTable.inline.hpp b/src/hotspot/share/gc/z/zForwardingTable.inline.hpp index 3561711c43b..be2fbe3ee3b 100644 --- a/src/hotspot/share/gc/z/zForwardingTable.inline.hpp +++ b/src/hotspot/share/gc/z/zForwardingTable.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,34 @@ #define SHARE_GC_Z_ZFORWARDINGTABLE_INLINE_HPP #include "gc/z/zAddress.inline.hpp" +#include "gc/z/zForwarding.inline.hpp" #include "gc/z/zForwardingTable.hpp" +#include "gc/z/zGlobals.hpp" #include "gc/z/zGranuleMap.inline.hpp" +#include "utilities/debug.hpp" + +inline ZForwardingTable::ZForwardingTable() : + _map(ZAddressOffsetMax) {} inline ZForwarding* ZForwardingTable::get(uintptr_t addr) const { assert(!ZAddress::is_null(addr), "Invalid address"); return _map.get(ZAddress::offset(addr)); } +inline void ZForwardingTable::insert(ZForwarding* forwarding) { + const uintptr_t offset = forwarding->start(); + const size_t size = forwarding->size(); + + assert(_map.get(offset) == NULL, "Invalid entry"); + _map.put(offset, size, forwarding); +} + +inline void ZForwardingTable::remove(ZForwarding* forwarding) { + const uintptr_t offset = forwarding->start(); + const size_t size = forwarding->size(); + + assert(_map.get(offset) == forwarding, "Invalid entry"); + _map.put(offset, size, NULL); +} + #endif // SHARE_GC_Z_ZFORWARDINGTABLE_INLINE_HPP diff --git a/src/hotspot/share/gc/z/zHeap.cpp b/src/hotspot/share/gc/z/zHeap.cpp index 97743a41921..86778981947 100644 --- a/src/hotspot/share/gc/z/zHeap.cpp +++ b/src/hotspot/share/gc/z/zHeap.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "gc/shared/locationPrinter.hpp" #include "gc/z/zAddress.inline.hpp" +#include "gc/z/zArray.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zHeap.inline.hpp" #include "gc/z/zHeapIterator.hpp" @@ -65,7 +66,7 @@ ZHeap::ZHeap() : _reference_processor(&_workers), _weak_roots_processor(&_workers), _relocate(&_workers), - _relocation_set(), + _relocation_set(&_workers), _unload(&_workers), _serviceability(min_capacity(), max_capacity()) { // Install global heap instance @@ -220,6 +221,17 @@ void ZHeap::free_page(ZPage* page, bool reclaimed) { _page_allocator.free_page(page, reclaimed); } +void ZHeap::free_pages(const ZArray* pages, bool reclaimed) { + // Remove page table entries + ZArrayIterator iter(pages); + for (ZPage* page; iter.next(&page);) { + _page_table.remove(page); + } + + // Free pages + _page_allocator.free_pages(pages, reclaimed); +} + void ZHeap::flip_to_marked() { ZVerifyViewsFlip flip(&_page_allocator); ZAddress::flip_to_marked(); @@ -349,6 +361,16 @@ void ZHeap::process_non_strong_references() { _reference_processor.enqueue_references(); } +void ZHeap::free_garbage_pages(ZRelocationSetSelector* selector, int bulk) { + // Freeing garbage pages in bulk is an optimization to avoid grabbing + // the page allocator lock, and trying to satisfy stalled allocations + // too frequently. + if (selector->should_free_garbage_pages(bulk)) { + free_pages(selector->garbage_pages(), true /* reclaimed */); + selector->clear_garbage_pages(); + } +} + void ZHeap::select_relocation_set() { // Do not allow pages to be deleted _page_allocator.enable_deferred_delete(); @@ -369,16 +391,22 @@ void ZHeap::select_relocation_set() { // Register garbage page selector.register_garbage_page(page); - // Reclaim page immediately - free_page(page, true /* reclaimed */); + // Reclaim garbage pages in bulk + free_garbage_pages(&selector, 64 /* bulk */); } } + // Reclaim remaining garbage pages + free_garbage_pages(&selector, 0 /* bulk */); + // Allow pages to be deleted _page_allocator.disable_deferred_delete(); - // Select pages to relocate - selector.select(&_relocation_set); + // Select relocation set + selector.select(); + + // Install relocation set + _relocation_set.install(&selector); // Setup forwarding table ZRelocationSetIterator rs_iter(&_relocation_set); diff --git a/src/hotspot/share/gc/z/zHeap.hpp b/src/hotspot/share/gc/z/zHeap.hpp index 338002a89c6..47bebc745f3 100644 --- a/src/hotspot/share/gc/z/zHeap.hpp +++ b/src/hotspot/share/gc/z/zHeap.hpp @@ -25,6 +25,7 @@ #define SHARE_GC_Z_ZHEAP_HPP #include "gc/z/zAllocationFlags.hpp" +#include "gc/z/zArray.hpp" #include "gc/z/zForwardingTable.hpp" #include "gc/z/zMark.hpp" #include "gc/z/zObjectAllocator.hpp" @@ -40,6 +41,7 @@ class ThreadClosure; class ZPage; +class ZRelocationSetSelector; class ZHeap { friend class VMStructs; @@ -63,6 +65,8 @@ class ZHeap { void flip_to_marked(); void flip_to_remapped(); + void free_garbage_pages(ZRelocationSetSelector* selector, int bulk); + void out_of_memory(); public: @@ -110,6 +114,7 @@ class ZHeap { ZPage* alloc_page(uint8_t type, size_t size, ZAllocationFlags flags); void undo_alloc_page(ZPage* page); void free_page(ZPage* page, bool reclaimed); + void free_pages(const ZArray* pages, bool reclaimed); // Object allocation uintptr_t alloc_tlab(size_t size); diff --git a/src/hotspot/share/gc/z/zHeapIterator.cpp b/src/hotspot/share/gc/z/zHeapIterator.cpp index 367e276a35a..4434e53fbb1 100644 --- a/src/hotspot/share/gc/z/zHeapIterator.cpp +++ b/src/hotspot/share/gc/z/zHeapIterator.cpp @@ -23,12 +23,14 @@ #include "precompiled.hpp" #include "classfile/classLoaderData.hpp" +#include "gc/shared/barrierSetNMethod.hpp" #include "gc/shared/taskqueue.inline.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zGranuleMap.inline.hpp" #include "gc/z/zHeapIterator.hpp" #include "gc/z/zLock.inline.hpp" +#include "gc/z/zNMethod.hpp" #include "gc/z/zOop.inline.hpp" #include "memory/iterator.inline.hpp" #include "utilities/bitMap.inline.hpp" @@ -92,8 +94,8 @@ class ZHeapIteratorContext { } }; -template -class ZHeapIteratorRootOopClosure : public ZRootsIteratorClosure { +template +class ZHeapIteratorRootOopClosure : public OopClosure { private: const ZHeapIteratorContext& _context; @@ -102,11 +104,7 @@ class ZHeapIteratorRootOopClosure : public ZRootsIteratorClosure { return NativeAccess::oop_load(p); } - if (Concurrent) { - return NativeAccess::oop_load(p); - } - - return RawAccess<>::oop_load(p); + return NativeAccess::oop_load(p); } public: @@ -121,22 +119,6 @@ class ZHeapIteratorRootOopClosure : public ZRootsIteratorClosure { virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } - - virtual void do_thread(Thread* thread) { - CodeBlobToOopClosure code_cl(this, false /* fix_oop_relocations */); - thread->oops_do(this, &code_cl); - } - - virtual ZNMethodEntry nmethod_entry() const { - if (ClassUnloading) { - // All encountered nmethods should have been "entered" during stack walking - return ZNMethodEntry::VerifyDisarmed; - } else { - // All nmethods are considered roots and will be visited. - // Make sure that the unvisited gets fixed and disarmed before proceeding. - return ZNMethodEntry::PreBarrier; - } - } }; template @@ -180,7 +162,7 @@ ZHeapIterator::ZHeapIterator(uint nworkers, bool visit_weaks) : _bitmaps_lock(), _queues(nworkers), _array_queues(nworkers), - _concurrent_roots(), + _concurrent_roots(ClassLoaderData::_claim_other), _weak_roots(), _concurrent_weak_roots(), _terminator(nworkers, &_queues) { @@ -255,10 +237,70 @@ bool ZHeapIterator::mark_object(oop obj) { return bitmap->try_set_bit(index); } -template -void ZHeapIterator::push_roots(const ZHeapIteratorContext& context, RootsIterator& iter) { - ZHeapIteratorRootOopClosure cl(context); - iter.oops_do(&cl); +typedef ClaimingCLDToOopClosure ZHeapIteratorCLDCLosure; + +class ZHeapIteratorNMethodClosure : public NMethodClosure { +private: + OopClosure* const _cl; + BarrierSetNMethod* const _bs_nm; + +public: + ZHeapIteratorNMethodClosure(OopClosure* cl) : + _cl(cl), + _bs_nm(BarrierSet::barrier_set()->barrier_set_nmethod()) {} + + virtual void do_nmethod(nmethod* nm) { + // If ClassUnloading is turned off, all nmethods are considered strong, + // not only those on the call stacks. The heap iteration might happen + // before the concurrent processign of the code cache, make sure that + // all nmethods have been processed before visiting the oops. + _bs_nm->nmethod_entry_barrier(nm); + + ZNMethod::nmethod_oops_do(nm, _cl); + } +}; + +class ZHeapIteratorThreadClosure : public ThreadClosure { +private: + OopClosure* const _cl; + CodeBlobToNMethodClosure _cb_cl; + +public: + ZHeapIteratorThreadClosure(OopClosure* cl, NMethodClosure* nm_cl) : + _cl(cl), + _cb_cl(nm_cl) {} + + void do_thread(Thread* thread) { + thread->oops_do(_cl, &_cb_cl); + } +}; + +void ZHeapIterator::push_strong_roots(const ZHeapIteratorContext& context) { + ZHeapIteratorRootOopClosure cl(context); + ZHeapIteratorCLDCLosure cld_cl(&cl); + ZHeapIteratorNMethodClosure nm_cl(&cl); + ZHeapIteratorThreadClosure thread_cl(&cl, &nm_cl); + + _concurrent_roots.apply(&cl, + &cld_cl, + &thread_cl, + &nm_cl); +} + +void ZHeapIterator::push_weak_roots(const ZHeapIteratorContext& context) { + ZHeapIteratorRootOopClosure cl(context); + _concurrent_weak_roots.apply(&cl); + + AlwaysTrueClosure is_alive; + _weak_roots.apply(&is_alive, &cl); +} + +template +void ZHeapIterator::push_roots(const ZHeapIteratorContext& context) { + push_strong_roots(context); + if (VisitWeaks) { + push_weak_roots(context); + } } template @@ -343,14 +385,9 @@ void ZHeapIterator::drain_and_steal(const ZHeapIteratorContext& context, ObjectC } template -void ZHeapIterator::object_iterate_inner(const ZHeapIteratorContext& context, ObjectClosure* cl) { - push_roots(context, _concurrent_roots); - if (VisitWeaks) { - push_roots(context, _weak_roots); - push_roots(context, _concurrent_weak_roots); - } - - drain_and_steal(context, cl); +void ZHeapIterator::object_iterate_inner(const ZHeapIteratorContext& context, ObjectClosure* object_cl) { + push_roots(context); + drain_and_steal(context, object_cl); } void ZHeapIterator::object_iterate(ObjectClosure* cl, uint worker_id) { diff --git a/src/hotspot/share/gc/z/zHeapIterator.hpp b/src/hotspot/share/gc/z/zHeapIterator.hpp index 598cb7d7c59..002e9ab949b 100644 --- a/src/hotspot/share/gc/z/zHeapIterator.hpp +++ b/src/hotspot/share/gc/z/zHeapIterator.hpp @@ -46,23 +46,26 @@ class ZHeapIterator : public ParallelObjectIterator { friend class ZHeapIteratorContext; private: - const bool _visit_weaks; - ZStatTimerDisable _timer_disable; - ZHeapIteratorBitMaps _bitmaps; - ZLock _bitmaps_lock; - ZHeapIteratorQueues _queues; - ZHeapIteratorArrayQueues _array_queues; - ZConcurrentRootsIteratorClaimOther _concurrent_roots; - ZWeakRootsIterator _weak_roots; - ZConcurrentWeakRootsIterator _concurrent_weak_roots; - TaskTerminator _terminator; + const bool _visit_weaks; + ZStatTimerDisable _timer_disable; + ZHeapIteratorBitMaps _bitmaps; + ZLock _bitmaps_lock; + ZHeapIteratorQueues _queues; + ZHeapIteratorArrayQueues _array_queues; + ZConcurrentRootsIterator _concurrent_roots; + ZWeakRootsIterator _weak_roots; + ZConcurrentWeakRootsIterator _concurrent_weak_roots; + TaskTerminator _terminator; ZHeapIteratorBitMap* object_bitmap(oop obj); bool mark_object(oop obj); - template - void push_roots(const ZHeapIteratorContext& context, RootsIterator& iter); + void push_strong_roots(const ZHeapIteratorContext& context); + void push_weak_roots(const ZHeapIteratorContext& context); + + template + void push_roots(const ZHeapIteratorContext& context); template void follow_object(const ZHeapIteratorContext& context, oop obj); diff --git a/src/hotspot/share/gc/z/zMark.cpp b/src/hotspot/share/gc/z/zMark.cpp index df47f690228..d4c4bbdfde5 100644 --- a/src/hotspot/share/gc/z/zMark.cpp +++ b/src/hotspot/share/gc/z/zMark.cpp @@ -23,12 +23,15 @@ #include "precompiled.hpp" #include "classfile/classLoaderDataGraph.hpp" +#include "code/nmethod.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/z/zBarrier.inline.hpp" +#include "gc/z/zLock.inline.hpp" #include "gc/z/zMark.inline.hpp" #include "gc/z/zMarkCache.inline.hpp" #include "gc/z/zMarkStack.inline.hpp" #include "gc/z/zMarkTerminate.inline.hpp" +#include "gc/z/zNMethod.hpp" #include "gc/z/zOopClosures.inline.hpp" #include "gc/z/zPage.hpp" #include "gc/z/zPageTable.inline.hpp" @@ -572,50 +575,79 @@ void ZMark::work(uint64_t timeout_in_micros) { stacks->free(&_allocator); } -class ZMarkConcurrentRootsIteratorClosure : public ZRootsIteratorClosure { -public: - ZMarkConcurrentRootsIteratorClosure() { - ZThreadLocalAllocBuffer::reset_statistics(); +class ZMarkOopClosure : public OopClosure { + virtual void do_oop(oop* p) { + ZBarrier::mark_barrier_on_oop_field(p, false /* finalizable */); } - ~ZMarkConcurrentRootsIteratorClosure() { - ZThreadLocalAllocBuffer::publish_statistics(); + virtual void do_oop(narrowOop* p) { + ShouldNotReachHere(); } +}; - virtual ZNMethodEntry nmethod_entry() const { - // Only apply closure to armed nmethods, and then disarm them. - return ZNMethodEntry::Disarm; - } +class ZMarkThreadClosure : public ThreadClosure { +private: + OopClosure* const _cl; +public: + ZMarkThreadClosure(OopClosure* cl) : + _cl(cl) { + ZThreadLocalAllocBuffer::reset_statistics(); + } + ~ZMarkThreadClosure() { + ZThreadLocalAllocBuffer::publish_statistics(); + } virtual void do_thread(Thread* thread) { JavaThread* const jt = thread->as_Java_thread(); - StackWatermarkSet::finish_processing(jt, this, StackWatermarkKind::gc); + StackWatermarkSet::finish_processing(jt, _cl, StackWatermarkKind::gc); ZThreadLocalAllocBuffer::update_stats(jt); } +}; - virtual void do_oop(oop* p) { - ZBarrier::mark_barrier_on_oop_field(p, false /* finalizable */); - } +class ZMarkNMethodClosure : public NMethodClosure { +private: + OopClosure* const _cl; - virtual void do_oop(narrowOop* p) { - ShouldNotReachHere(); +public: + ZMarkNMethodClosure(OopClosure* cl) : + _cl(cl) {} + + virtual void do_nmethod(nmethod* nm) { + ZLocker locker(ZNMethod::lock_for_nmethod(nm)); + if (!nm->is_alive()) { + return; + } + + if (ZNMethod::is_armed(nm)) { + ZNMethod::nmethod_oops_do_inner(nm, _cl); + ZNMethod::disarm(nm); + } } }; +typedef ClaimingCLDToOopClosure ZMarkCLDClosure; + class ZMarkConcurrentRootsTask : public ZTask { private: - ZMark* const _mark; - SuspendibleThreadSetJoiner _sts_joiner; - ZConcurrentRootsIteratorClaimStrong _roots; - ZMarkConcurrentRootsIteratorClosure _cl; + ZMark* const _mark; + SuspendibleThreadSetJoiner _sts_joiner; + ZConcurrentRootsIterator _roots; + + ZMarkOopClosure _cl; + ZMarkCLDClosure _cld_cl; + ZMarkThreadClosure _thread_cl; + ZMarkNMethodClosure _nm_cl; public: ZMarkConcurrentRootsTask(ZMark* mark) : ZTask("ZMarkConcurrentRootsTask"), _mark(mark), _sts_joiner(), - _roots(), - _cl() { + _roots(ClassLoaderData::_claim_strong), + _cl(), + _cld_cl(&_cl), + _thread_cl(&_cl), + _nm_cl(&_cl) { ClassLoaderDataGraph_lock->lock(); } @@ -624,7 +656,10 @@ class ZMarkConcurrentRootsTask : public ZTask { } virtual void work() { - _roots.oops_do(&_cl); + _roots.apply(&_cl, + &_cld_cl, + &_thread_cl, + &_nm_cl); // Flush and free worker stacks. Needed here since // the set of workers executing during root scanning diff --git a/src/hotspot/share/gc/z/zNMethod.cpp b/src/hotspot/share/gc/z/zNMethod.cpp index dfbf38d1dc0..ec3040e0f49 100644 --- a/src/hotspot/share/gc/z/zNMethod.cpp +++ b/src/hotspot/share/gc/z/zNMethod.cpp @@ -204,6 +204,15 @@ void ZNMethod::disarm(nmethod* nm) { } void ZNMethod::nmethod_oops_do(nmethod* nm, OopClosure* cl) { + ZLocker locker(ZNMethod::lock_for_nmethod(nm)); + if (!nm->is_alive()) { + return; + } + + ZNMethod::nmethod_oops_do_inner(nm, cl); +} + +void ZNMethod::nmethod_oops_do_inner(nmethod* nm, OopClosure* cl) { // Process oops table { oop* const begin = nm->oops_begin(); @@ -234,58 +243,16 @@ void ZNMethod::nmethod_oops_do(nmethod* nm, OopClosure* cl) { } } -class ZNMethodToOopsDoClosure : public NMethodClosure { -private: - OopClosure* const _cl; - const ZNMethodEntry _entry; - BarrierSetNMethod* const _bs_nm; - -public: - ZNMethodToOopsDoClosure(OopClosure* cl, ZNMethodEntry entry) : - _cl(cl), - _entry(entry), - _bs_nm(BarrierSet::barrier_set()->barrier_set_nmethod()) {} - - virtual void do_nmethod(nmethod* nm) { - if (_entry == ZNMethodEntry::PreBarrier) { - // Apply entry barrier before proceeding with closure - _bs_nm->nmethod_entry_barrier(nm); - } - - ZLocker locker(ZNMethod::lock_for_nmethod(nm)); - if (!nm->is_alive()) { - return; - } - - if (_entry == ZNMethodEntry::Disarm) { - // Apply closure and disarm only armed nmethods - if (ZNMethod::is_armed(nm)) { - ZNMethod::nmethod_oops_do(nm, _cl); - ZNMethod::disarm(nm); - } - return; - } - - if (_entry == ZNMethodEntry::VerifyDisarmed) { - // Only verify - assert(!ZNMethod::is_armed(nm), "Must be disarmed"); - } - - ZNMethod::nmethod_oops_do(nm, _cl); - } -}; - -void ZNMethod::oops_do_begin() { +void ZNMethod::nmethods_do_begin() { ZNMethodTable::nmethods_do_begin(); } -void ZNMethod::oops_do_end() { +void ZNMethod::nmethods_do_end() { ZNMethodTable::nmethods_do_end(); } -void ZNMethod::oops_do(OopClosure* cl, ZNMethodEntry entry) { - ZNMethodToOopsDoClosure nmethod_cl(cl, entry); - ZNMethodTable::nmethods_do(&nmethod_cl); +void ZNMethod::nmethods_do(NMethodClosure* cl) { + ZNMethodTable::nmethods_do(cl); } class ZNMethodUnlinkClosure : public NMethodClosure { diff --git a/src/hotspot/share/gc/z/zNMethod.hpp b/src/hotspot/share/gc/z/zNMethod.hpp index 66914f1ff25..ec05389b7f4 100644 --- a/src/hotspot/share/gc/z/zNMethod.hpp +++ b/src/hotspot/share/gc/z/zNMethod.hpp @@ -27,17 +27,10 @@ #include "memory/allocation.hpp" class nmethod; -class OopClosure; +class NMethodClosure; class ZReentrantLock; class ZWorkers; -enum class ZNMethodEntry { - PreBarrier, - Disarm, - VerifyDisarmed, - None -}; - class ZNMethod : public AllStatic { private: static void attach_gc_data(nmethod* nm); @@ -56,10 +49,11 @@ class ZNMethod : public AllStatic { static void disarm(nmethod* nm); static void nmethod_oops_do(nmethod* nm, OopClosure* cl); + static void nmethod_oops_do_inner(nmethod* nm, OopClosure* cl); - static void oops_do_begin(); - static void oops_do_end(); - static void oops_do(OopClosure* cl, ZNMethodEntry entry); + static void nmethods_do_begin(); + static void nmethods_do_end(); + static void nmethods_do(NMethodClosure* cl); static ZReentrantLock* lock_for_nmethod(nmethod* nm); diff --git a/src/hotspot/share/gc/z/zOopClosures.hpp b/src/hotspot/share/gc/z/zOopClosures.hpp index 93aede74e57..73201c339f5 100644 --- a/src/hotspot/share/gc/z/zOopClosures.hpp +++ b/src/hotspot/share/gc/z/zOopClosures.hpp @@ -53,20 +53,15 @@ class ZPhantomIsAliveObjectClosure : public BoolObjectClosure { virtual bool do_object_b(oop o); }; -class ZPhantomKeepAliveOopClosure : public ZRootsIteratorClosure { +class ZPhantomKeepAliveOopClosure : public OopClosure { public: virtual void do_oop(oop* p); virtual void do_oop(narrowOop* p); - - virtual ZNMethodEntry nmethod_entry() const; }; - -class ZPhantomCleanOopClosure : public ZRootsIteratorClosure { +class ZPhantomCleanOopClosure : public OopClosure { public: virtual void do_oop(oop* p); virtual void do_oop(narrowOop* p); - - virtual ZNMethodEntry nmethod_entry() const; }; #endif // SHARE_GC_Z_ZOOPCLOSURES_HPP diff --git a/src/hotspot/share/gc/z/zOopClosures.inline.hpp b/src/hotspot/share/gc/z/zOopClosures.inline.hpp index eb9c7ad92fa..da8f22ff9d8 100644 --- a/src/hotspot/share/gc/z/zOopClosures.inline.hpp +++ b/src/hotspot/share/gc/z/zOopClosures.inline.hpp @@ -80,11 +80,6 @@ inline void ZPhantomKeepAliveOopClosure::do_oop(oop* p) { ZBarrier::keep_alive_barrier_on_phantom_oop_field(p); } -inline ZNMethodEntry ZPhantomKeepAliveOopClosure::nmethod_entry() const { - ShouldNotReachHere(); - return ZNMethodEntry::None; -} - inline void ZPhantomKeepAliveOopClosure::do_oop(narrowOop* p) { ShouldNotReachHere(); } @@ -109,9 +104,4 @@ inline void ZPhantomCleanOopClosure::do_oop(narrowOop* p) { ShouldNotReachHere(); } -inline ZNMethodEntry ZPhantomCleanOopClosure::nmethod_entry() const { - ShouldNotReachHere(); - return ZNMethodEntry::None; -} - #endif // SHARE_GC_Z_ZOOPCLOSURES_INLINE_HPP diff --git a/src/hotspot/share/gc/z/zPageAllocator.cpp b/src/hotspot/share/gc/z/zPageAllocator.cpp index ebf29596de2..371ee2ff75a 100644 --- a/src/hotspot/share/gc/z/zPageAllocator.cpp +++ b/src/hotspot/share/gc/z/zPageAllocator.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "gc/shared/gcLogPrecious.hpp" #include "gc/shared/suspendibleThreadSet.hpp" +#include "gc/z/zArray.inline.hpp" #include "gc/z/zCollectedHeap.hpp" #include "gc/z/zFuture.inline.hpp" #include "gc/z/zGlobals.hpp" @@ -748,6 +749,19 @@ void ZPageAllocator::free_page(ZPage* page, bool reclaimed) { satisfy_stalled(); } +void ZPageAllocator::free_pages(const ZArray* pages, bool reclaimed) { + ZLocker locker(&_lock); + + // Free pages + ZArrayIterator iter(pages); + for (ZPage* page; iter.next(&page);) { + free_page_inner(page, reclaimed); + } + + // Try satisfy stalled allocations + satisfy_stalled(); +} + size_t ZPageAllocator::uncommit(uint64_t* timeout) { // We need to join the suspendible thread set while manipulating capacity and // used, to make sure GC safepoints will have a consistent view. However, when diff --git a/src/hotspot/share/gc/z/zPageAllocator.hpp b/src/hotspot/share/gc/z/zPageAllocator.hpp index 800ef4d9875..9c970350732 100644 --- a/src/hotspot/share/gc/z/zPageAllocator.hpp +++ b/src/hotspot/share/gc/z/zPageAllocator.hpp @@ -25,6 +25,7 @@ #define SHARE_GC_Z_ZPAGEALLOCATOR_HPP #include "gc/z/zAllocationFlags.hpp" +#include "gc/z/zArray.hpp" #include "gc/z/zList.hpp" #include "gc/z/zLock.hpp" #include "gc/z/zPageCache.hpp" @@ -124,6 +125,7 @@ class ZPageAllocator { ZPage* alloc_page(uint8_t type, size_t size, ZAllocationFlags flags); void free_page(ZPage* page, bool reclaimed); + void free_pages(const ZArray* pages, bool reclaimed); void enable_deferred_delete() const; void disable_deferred_delete() const; diff --git a/src/hotspot/share/gc/z/zRelocate.cpp b/src/hotspot/share/gc/z/zRelocate.cpp index a8f8f74ef86..95c07cb2bc4 100644 --- a/src/hotspot/share/gc/z/zRelocate.cpp +++ b/src/hotspot/share/gc/z/zRelocate.cpp @@ -36,8 +36,10 @@ #include "gc/z/zThread.inline.hpp" #include "gc/z/zWorkers.hpp" #include "logging/log.hpp" +#include "prims/jvmtiTagMap.hpp" static const ZStatCounter ZCounterRelocationContention("Contention", "Relocation Contention", ZStatUnitOpsPerSecond); +static const ZStatSubPhase ZSubPhasePauseRootsJVMTITagMap("Pause Roots JVMTITagMap"); ZRelocate::ZRelocate(ZWorkers* workers) : _workers(workers) {} @@ -67,8 +69,10 @@ class ZRelocateRootsTask : public ZTask { assert(ZThread::worker_id() == 0, "No multi-thread support"); // During relocation we need to visit the JVMTI - // export weak roots to rehash the JVMTI tag map - ZRelocateRoots::oops_do(&_cl); + // tag map to rehash the entries with the new oop addresses. + ZStatTimer timer(ZSubPhasePauseRootsJVMTITagMap); + AlwaysTrueClosure always_alive; + JvmtiTagMap::weak_oops_do(&always_alive, &_cl); } }; diff --git a/src/hotspot/share/gc/z/zRelocationSet.cpp b/src/hotspot/share/gc/z/zRelocationSet.cpp index 72d9fcef2c7..0591c2a711a 100644 --- a/src/hotspot/share/gc/z/zRelocationSet.cpp +++ b/src/hotspot/share/gc/z/zRelocationSet.cpp @@ -22,51 +22,106 @@ */ #include "precompiled.hpp" +#include "gc/z/zArray.inline.hpp" #include "gc/z/zForwarding.inline.hpp" #include "gc/z/zForwardingAllocator.inline.hpp" #include "gc/z/zRelocationSet.hpp" +#include "gc/z/zRelocationSetSelector.inline.hpp" #include "gc/z/zStat.hpp" -#include "memory/allocation.hpp" +#include "gc/z/zTask.hpp" +#include "gc/z/zWorkers.hpp" +#include "runtime/atomic.hpp" #include "utilities/debug.hpp" -ZRelocationSet::ZRelocationSet() : - _allocator(), - _forwardings(NULL), - _nforwardings(0) {} +class ZRelocationSetInstallTask : public ZTask { +private: + ZForwardingAllocator* const _allocator; + ZForwarding** _forwardings; + const size_t _nforwardings; + ZArrayParallelIterator _small_iter; + ZArrayParallelIterator _medium_iter; + volatile size_t _small_next; + volatile size_t _medium_next; + + void install(ZForwarding* forwarding, volatile size_t* next) { + const size_t index = Atomic::fetch_and_add(next, 1u); + assert(index < _nforwardings, "Invalid index"); + _forwardings[index] = forwarding; + } -void ZRelocationSet::populate(ZPage* const* small, size_t nsmall, - ZPage* const* medium, size_t nmedium, - size_t forwarding_entries) { - // Set relocation set length - _nforwardings = nsmall + nmedium; + void install_small(ZForwarding* forwarding) { + install(forwarding, &_small_next); + } - // Initialize forwarding allocator to have room for the - // relocation set, all forwardings, and all forwarding entries. - const size_t relocation_set_size = _nforwardings * sizeof(ZForwarding*); - const size_t forwardings_size = _nforwardings * sizeof(ZForwarding); - const size_t forwarding_entries_size = forwarding_entries * sizeof(ZForwardingEntry); - _allocator.reset(relocation_set_size + forwardings_size + forwarding_entries_size); + void install_medium(ZForwarding* forwarding) { + install(forwarding, &_medium_next); + } - // Allocate relocation set - _forwardings = new (_allocator.alloc(relocation_set_size)) ZForwarding*[_nforwardings]; +public: + ZRelocationSetInstallTask(ZForwardingAllocator* allocator, const ZRelocationSetSelector* selector) : + ZTask("ZRelocationSetInstallTask"), + _allocator(allocator), + _forwardings(NULL), + _nforwardings(selector->small()->length() + selector->medium()->length()), + _small_iter(selector->small()), + _medium_iter(selector->medium()), + _small_next(selector->medium()->length()), + _medium_next(0) { - // Populate relocation set array - size_t j = 0; + // Reset the allocator to have room for the relocation + // set, all forwardings, and all forwarding entries. + const size_t relocation_set_size = _nforwardings * sizeof(ZForwarding*); + const size_t forwardings_size = _nforwardings * sizeof(ZForwarding); + const size_t forwarding_entries_size = selector->forwarding_entries() * sizeof(ZForwardingEntry); + _allocator->reset(relocation_set_size + forwardings_size + forwarding_entries_size); - // Populate medium pages - for (size_t i = 0; i < nmedium; i++) { - _forwardings[j++] = ZForwarding::alloc(&_allocator, medium[i]); + // Allocate relocation set + _forwardings = new (_allocator->alloc(relocation_set_size)) ZForwarding*[_nforwardings]; } - // Populate small pages - for (size_t i = 0; i < nsmall; i++) { - _forwardings[j++] = ZForwarding::alloc(&_allocator, small[i]); + ~ZRelocationSetInstallTask() { + assert(_allocator->is_full(), "Should be full"); + } + + virtual void work() { + // Allocate and install forwardings for small pages + for (ZPage* page; _small_iter.next(&page);) { + ZForwarding* const forwarding = ZForwarding::alloc(_allocator, page); + install_small(forwarding); + } + + // Allocate and install forwardings for medium pages + for (ZPage* page; _medium_iter.next(&page);) { + ZForwarding* const forwarding = ZForwarding::alloc(_allocator, page); + install_medium(forwarding); + } } - assert(_allocator.is_full(), "Should be full"); + ZForwarding** forwardings() const { + return _forwardings; + } + + size_t nforwardings() const { + return _nforwardings; + } +}; + +ZRelocationSet::ZRelocationSet(ZWorkers* workers) : + _workers(workers), + _allocator(), + _forwardings(NULL), + _nforwardings(0) {} + +void ZRelocationSet::install(const ZRelocationSetSelector* selector) { + // Install relocation set + ZRelocationSetInstallTask task(&_allocator, selector); + _workers->run_concurrent(&task); + + _forwardings = task.forwardings(); + _nforwardings = task.nforwardings(); // Update statistics - ZStatRelocation::set_at_populate_relocation_set(_allocator.size()); + ZStatRelocation::set_at_install_relocation_set(_allocator.size()); } void ZRelocationSet::reset() { diff --git a/src/hotspot/share/gc/z/zRelocationSet.hpp b/src/hotspot/share/gc/z/zRelocationSet.hpp index 2bf6ccb9de6..5881055db99 100644 --- a/src/hotspot/share/gc/z/zRelocationSet.hpp +++ b/src/hotspot/share/gc/z/zRelocationSet.hpp @@ -26,25 +26,24 @@ #include "gc/z/zArray.hpp" #include "gc/z/zForwardingAllocator.hpp" -#include "memory/allocation.hpp" class ZForwarding; -class ZPage; +class ZRelocationSetSelector; +class ZWorkers; class ZRelocationSet { template friend class ZRelocationSetIteratorImpl; private: + ZWorkers* _workers; ZForwardingAllocator _allocator; ZForwarding** _forwardings; size_t _nforwardings; public: - ZRelocationSet(); + ZRelocationSet(ZWorkers* workers); - void populate(ZPage* const* small, size_t nsmall, - ZPage* const* medium, size_t nmedium, - size_t forwarding_entries); + void install(const ZRelocationSetSelector* selector); void reset(); }; diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp index 5239ef0b0cc..3d80286a894 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp @@ -25,7 +25,6 @@ #include "gc/z/zArray.inline.hpp" #include "gc/z/zForwarding.inline.hpp" #include "gc/z/zPage.inline.hpp" -#include "gc/z/zRelocationSet.hpp" #include "gc/z/zRelocationSetSelector.inline.hpp" #include "jfr/jfrEvents.hpp" #include "logging/log.hpp" @@ -52,40 +51,9 @@ ZRelocationSetSelectorGroup::ZRelocationSetSelectorGroup(const char* name, _object_size_limit(object_size_limit), _fragmentation_limit(page_size * (ZFragmentationLimit / 100)), _registered_pages(), - _sorted_pages(NULL), - _nselected(0), _forwarding_entries(0), _stats() {} -ZRelocationSetSelectorGroup::~ZRelocationSetSelectorGroup() { - FREE_C_HEAP_ARRAY(ZPage*, _sorted_pages); -} - -void ZRelocationSetSelectorGroup::register_live_page(ZPage* page) { - const uint8_t type = page->type(); - const size_t size = page->size(); - const size_t live = page->live_bytes(); - const size_t garbage = size - live; - - if (garbage > _fragmentation_limit) { - _registered_pages.append(page); - } - - _stats._npages++; - _stats._total += size; - _stats._live += live; - _stats._garbage += garbage; -} - -void ZRelocationSetSelectorGroup::register_garbage_page(ZPage* page) { - const size_t size = page->size(); - - _stats._npages++; - _stats._total += size; - _stats._garbage += size; - _stats._empty += size; -} - bool ZRelocationSetSelectorGroup::is_disabled() { // Medium pages are disabled when their page size is zero return _page_type == ZPageTypeMedium && _page_size == 0; @@ -102,18 +70,11 @@ void ZRelocationSetSelectorGroup::semi_sort() { const size_t npartitions = (size_t)1 << npartitions_shift; const size_t partition_size = _page_size >> npartitions_shift; const size_t partition_size_shift = exact_log2(partition_size); - const size_t npages = _registered_pages.length(); // Partition slots/fingers - size_t partitions[npartitions]; - - // Allocate destination array - assert(_sorted_pages == NULL, "Already initialized"); - _sorted_pages = NEW_C_HEAP_ARRAY(ZPage*, npages, mtGC); - debug_only(memset(_sorted_pages, 0, npages * sizeof(ZPage*))); + int partitions[npartitions] = { /* zero initialize */ }; // Calculate partition slots - memset(partitions, 0, sizeof(partitions)); ZArrayIterator iter1(&_registered_pages); for (ZPage* page; iter1.next(&page);) { const size_t index = page->live_bytes() >> partition_size_shift; @@ -121,39 +82,45 @@ void ZRelocationSetSelectorGroup::semi_sort() { } // Calculate partition fingers - size_t finger = 0; + int finger = 0; for (size_t i = 0; i < npartitions; i++) { - const size_t slots = partitions[i]; + const int slots = partitions[i]; partitions[i] = finger; finger += slots; } + // Allocate destination array + const int npages = _registered_pages.length(); + ZArray sorted_pages(npages, npages, NULL); + // Sort pages into partitions ZArrayIterator iter2(&_registered_pages); for (ZPage* page; iter2.next(&page);) { const size_t index = page->live_bytes() >> partition_size_shift; - const size_t finger = partitions[index]++; - assert(_sorted_pages[finger] == NULL, "Invalid finger"); - _sorted_pages[finger] = page; + const int finger = partitions[index]++; + assert(sorted_pages.at(finger) == NULL, "Invalid finger"); + sorted_pages.at_put(finger, page); } + + _registered_pages.swap(&sorted_pages); } void ZRelocationSetSelectorGroup::select_inner() { // Calculate the number of pages to relocate by successively including pages in // a candidate relocation set and calculate the maximum space requirement for // their live objects. - const size_t npages = _registered_pages.length(); - size_t selected_from = 0; - size_t selected_to = 0; + const int npages = _registered_pages.length(); + int selected_from = 0; + int selected_to = 0; size_t selected_forwarding_entries = 0; size_t from_live_bytes = 0; size_t from_forwarding_entries = 0; semi_sort(); - for (size_t from = 1; from <= npages; from++) { + for (int from = 1; from <= npages; from++) { // Add page to the candidate relocation set - ZPage* const page = _sorted_pages[from - 1]; + ZPage* const page = _registered_pages.at(from - 1); from_live_bytes += page->live_bytes(); from_forwarding_entries += ZForwarding::nentries(page); @@ -161,14 +128,14 @@ void ZRelocationSetSelectorGroup::select_inner() { // By subtracting the object size limit from the pages size we get the maximum // number of pages that the relocation set is guaranteed to fit in, regardless // of in which order the objects are relocated. - const size_t to = ceil((double)(from_live_bytes) / (double)(_page_size - _object_size_limit)); + const int to = ceil((double)(from_live_bytes) / (double)(_page_size - _object_size_limit)); // Calculate the relative difference in reclaimable space compared to our // currently selected final relocation set. If this number is larger than the // acceptable fragmentation limit, then the current candidate relocation set // becomes our new final relocation set. - const size_t diff_from = from - selected_from; - const size_t diff_to = to - selected_to; + const int diff_from = from - selected_from; + const int diff_to = to - selected_to; const double diff_reclaimable = 100 - percent_of(diff_to, diff_from); if (diff_reclaimable > ZFragmentationLimit) { selected_from = from; @@ -176,24 +143,22 @@ void ZRelocationSetSelectorGroup::select_inner() { selected_forwarding_entries = from_forwarding_entries; } - log_trace(gc, reloc)("Candidate Relocation Set (%s Pages): " SIZE_FORMAT "->" SIZE_FORMAT ", " + log_trace(gc, reloc)("Candidate Relocation Set (%s Pages): %d->%d, " "%.1f%% relative defragmentation, " SIZE_FORMAT " forwarding entries, %s", _name, from, to, diff_reclaimable, from_forwarding_entries, (selected_from == from) ? "Selected" : "Rejected"); } // Finalize selection - _nselected = selected_from; + _registered_pages.trunc_to(selected_from); _forwarding_entries = selected_forwarding_entries; // Update statistics _stats._compacting_from = selected_from * _page_size; _stats._compacting_to = selected_to * _page_size; - log_trace(gc, reloc)("Relocation Set (%s Pages): " SIZE_FORMAT "->" SIZE_FORMAT ", " - SIZE_FORMAT " skipped, " SIZE_FORMAT " forwarding entries", - _name, selected_from, selected_to, npages - selected_from, - selected_forwarding_entries); + log_trace(gc, reloc)("Relocation Set (%s Pages): %d->%d, %d skipped, " SIZE_FORMAT " forwarding entries", + _name, selected_from, selected_to, npages - selected_from, selected_forwarding_entries); } void ZRelocationSetSelectorGroup::select() { @@ -215,33 +180,10 @@ void ZRelocationSetSelectorGroup::select() { ZRelocationSetSelector::ZRelocationSetSelector() : _small("Small", ZPageTypeSmall, ZPageSizeSmall, ZObjectSizeLimitSmall), _medium("Medium", ZPageTypeMedium, ZPageSizeMedium, ZObjectSizeLimitMedium), - _large("Large", ZPageTypeLarge, 0 /* page_size */, 0 /* object_size_limit */) {} - -void ZRelocationSetSelector::register_live_page(ZPage* page) { - const uint8_t type = page->type(); - - if (type == ZPageTypeSmall) { - _small.register_live_page(page); - } else if (type == ZPageTypeMedium) { - _medium.register_live_page(page); - } else { - _large.register_live_page(page); - } -} - -void ZRelocationSetSelector::register_garbage_page(ZPage* page) { - const uint8_t type = page->type(); - - if (type == ZPageTypeSmall) { - _small.register_garbage_page(page); - } else if (type == ZPageTypeMedium) { - _medium.register_garbage_page(page); - } else { - _large.register_garbage_page(page); - } -} + _large("Large", ZPageTypeLarge, 0 /* page_size */, 0 /* object_size_limit */), + _garbage_pages() {} -void ZRelocationSetSelector::select(ZRelocationSet* relocation_set) { +void ZRelocationSetSelector::select() { // Select pages to relocate. The resulting relocation set will be // sorted such that medium pages comes first, followed by small // pages. Pages within each page group will be semi-sorted by live @@ -255,11 +197,6 @@ void ZRelocationSetSelector::select(ZRelocationSet* relocation_set) { _medium.select(); _small.select(); - // Populate relocation set - relocation_set->populate(_small.selected(), _small.nselected(), - _medium.selected(), _medium.nselected(), - forwarding_entries()); - // Send event event.commit(total(), empty(), compacting_from(), compacting_to()); } diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.hpp b/src/hotspot/share/gc/z/zRelocationSetSelector.hpp index 034cee6e097..164fcd628a0 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.hpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.hpp @@ -28,7 +28,6 @@ #include "memory/allocation.hpp" class ZPage; -class ZRelocationSet; class ZRelocationSetSelectorGroupStats { friend class ZRelocationSetSelectorGroup; @@ -76,8 +75,6 @@ class ZRelocationSetSelectorGroup { const size_t _object_size_limit; const size_t _fragmentation_limit; ZArray _registered_pages; - ZPage** _sorted_pages; - size_t _nselected; size_t _forwarding_entries; ZRelocationSetSelectorGroupStats _stats; @@ -91,14 +88,12 @@ class ZRelocationSetSelectorGroup { uint8_t page_type, size_t page_size, size_t object_size_limit); - ~ZRelocationSetSelectorGroup(); void register_live_page(ZPage* page); void register_garbage_page(ZPage* page); void select(); - ZPage* const* selected() const; - size_t nselected() const; + const ZArray* selected() const; size_t forwarding_entries() const; const ZRelocationSetSelectorGroupStats& stats() const; @@ -109,8 +104,8 @@ class ZRelocationSetSelector : public StackObj { ZRelocationSetSelectorGroup _small; ZRelocationSetSelectorGroup _medium; ZRelocationSetSelectorGroup _large; + ZArray _garbage_pages; - size_t forwarding_entries() const; size_t total() const; size_t empty() const; size_t compacting_from() const; @@ -121,7 +116,16 @@ class ZRelocationSetSelector : public StackObj { void register_live_page(ZPage* page); void register_garbage_page(ZPage* page); - void select(ZRelocationSet* relocation_set); + + bool should_free_garbage_pages(int bulk) const; + const ZArray* garbage_pages() const; + void clear_garbage_pages(); + + void select(); + + const ZArray* small() const; + const ZArray* medium() const; + size_t forwarding_entries() const; ZRelocationSetSelectorStats stats() const; }; diff --git a/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp b/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp index 1017a09071b..11c48394fc9 100644 --- a/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp +++ b/src/hotspot/share/gc/z/zRelocationSetSelector.inline.hpp @@ -24,6 +24,8 @@ #ifndef SHARE_GC_Z_ZRELOCATIONSETSELECTOR_INLINE_HPP #define SHARE_GC_Z_ZRELOCATIONSETSELECTOR_INLINE_HPP +#include "gc/z/zArray.inline.hpp" +#include "gc/z/zPage.inline.hpp" #include "gc/z/zRelocationSetSelector.hpp" inline size_t ZRelocationSetSelectorGroupStats::npages() const { @@ -66,12 +68,33 @@ inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorStats::larg return _large; } -inline ZPage* const* ZRelocationSetSelectorGroup::selected() const { - return _sorted_pages; +inline void ZRelocationSetSelectorGroup::register_live_page(ZPage* page) { + const uint8_t type = page->type(); + const size_t size = page->size(); + const size_t live = page->live_bytes(); + const size_t garbage = size - live; + + if (garbage > _fragmentation_limit) { + _registered_pages.append(page); + } + + _stats._npages++; + _stats._total += size; + _stats._live += live; + _stats._garbage += garbage; } -inline size_t ZRelocationSetSelectorGroup::nselected() const { - return _nselected; +inline void ZRelocationSetSelectorGroup::register_garbage_page(ZPage* page) { + const size_t size = page->size(); + + _stats._npages++; + _stats._total += size; + _stats._garbage += size; + _stats._empty += size; +} + +inline const ZArray* ZRelocationSetSelectorGroup::selected() const { + return &_registered_pages; } inline size_t ZRelocationSetSelectorGroup::forwarding_entries() const { @@ -82,8 +105,42 @@ inline const ZRelocationSetSelectorGroupStats& ZRelocationSetSelectorGroup::stat return _stats; } -inline size_t ZRelocationSetSelector::forwarding_entries() const { - return _small.forwarding_entries() + _medium.forwarding_entries(); +inline void ZRelocationSetSelector::register_live_page(ZPage* page) { + const uint8_t type = page->type(); + + if (type == ZPageTypeSmall) { + _small.register_live_page(page); + } else if (type == ZPageTypeMedium) { + _medium.register_live_page(page); + } else { + _large.register_live_page(page); + } +} + +inline void ZRelocationSetSelector::register_garbage_page(ZPage* page) { + const uint8_t type = page->type(); + + if (type == ZPageTypeSmall) { + _small.register_garbage_page(page); + } else if (type == ZPageTypeMedium) { + _medium.register_garbage_page(page); + } else { + _large.register_garbage_page(page); + } + + _garbage_pages.append(page); +} + +inline bool ZRelocationSetSelector::should_free_garbage_pages(int bulk) const { + return _garbage_pages.length() >= bulk && _garbage_pages.is_nonempty(); +} + +inline const ZArray* ZRelocationSetSelector::garbage_pages() const { + return &_garbage_pages; +} + +inline void ZRelocationSetSelector::clear_garbage_pages() { + return _garbage_pages.clear(); } inline size_t ZRelocationSetSelector::total() const { @@ -102,4 +159,16 @@ inline size_t ZRelocationSetSelector::compacting_to() const { return _small.stats().compacting_to() + _medium.stats().compacting_to() + _large.stats().compacting_to(); } +inline const ZArray* ZRelocationSetSelector::small() const { + return _small.selected(); +} + +inline const ZArray* ZRelocationSetSelector::medium() const { + return _medium.selected(); +} + +inline size_t ZRelocationSetSelector::forwarding_entries() const { + return _small.forwarding_entries() + _medium.forwarding_entries(); +} + #endif // SHARE_GC_Z_ZRELOCATIONSETSELECTOR_INLINE_HPP diff --git a/src/hotspot/share/gc/z/zRootsIterator.cpp b/src/hotspot/share/gc/z/zRootsIterator.cpp index 3ddda27b8d5..ec1887e2de2 100644 --- a/src/hotspot/share/gc/z/zRootsIterator.cpp +++ b/src/hotspot/share/gc/z/zRootsIterator.cpp @@ -22,53 +22,57 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderDataGraph.hpp" #include "gc/shared/oopStorageSetParState.inline.hpp" #include "gc/z/zNMethod.hpp" #include "gc/z/zNMethodTable.hpp" #include "gc/z/zRootsIterator.hpp" #include "gc/z/zStat.hpp" #include "memory/resourceArea.hpp" -#include "prims/jvmtiExport.hpp" +#include "prims/jvmtiTagMap.hpp" #include "runtime/atomic.hpp" #include "runtime/globals.hpp" #include "runtime/safepoint.hpp" #include "utilities/debug.hpp" -static const ZStatSubPhase ZSubPhasePauseRootsJVMTIWeakExport("Pause Roots JVMTIWeakExport"); static const ZStatSubPhase ZSubPhaseConcurrentRootsOopStorageSet("Concurrent Roots OopStorageSet"); static const ZStatSubPhase ZSubPhaseConcurrentRootsClassLoaderDataGraph("Concurrent Roots ClassLoaderDataGraph"); static const ZStatSubPhase ZSubPhaseConcurrentRootsJavaThreads("Concurrent Roots JavaThreads"); static const ZStatSubPhase ZSubPhaseConcurrentRootsCodeCache("Concurrent Roots CodeCache"); -static const ZStatSubPhase ZSubPhasePauseWeakRootsJVMTIWeakExport("Pause Weak Roots JVMTIWeakExport"); +static const ZStatSubPhase ZSubPhasePauseWeakRootsJVMTITagMap("Pause Weak Roots JVMTITagMap"); static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsOopStorageSet("Concurrent Weak Roots OopStorageSet"); -template -ZParallelOopsDo::ZParallelOopsDo(T* iter) : - _iter(iter), - _completed(false) {} - -template -void ZParallelOopsDo::oops_do(ZRootsIteratorClosure* cl) { +template +template +void ZParallelApply::apply(ClosureType* cl) { if (!Atomic::load(&_completed)) { - (_iter->*F)(cl); + _iter.apply(cl); if (!Atomic::load(&_completed)) { Atomic::store(&_completed, true); } } } -template -ZSerialWeakOopsDo::ZSerialWeakOopsDo(T* iter) : - _iter(iter), - _claimed(false) {} - -template -void ZSerialWeakOopsDo::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { +template +void ZSerialWeakApply::apply(BoolObjectClosure* is_alive, OopClosure* cl) { if (!Atomic::load(&_claimed) && Atomic::cmpxchg(&_claimed, false, true) == false) { - (_iter->*F)(is_alive, cl); + _iter.apply(is_alive, cl); } } +ZStrongOopStorageSetIterator::ZStrongOopStorageSetIterator() : + _iter() {} + +void ZStrongOopStorageSetIterator::apply(OopClosure* cl) { + ZStatTimer timer(ZSubPhaseConcurrentRootsOopStorageSet); + _iter.oops_do(cl); +} + +void ZStrongCLDsIterator::apply(CLDClosure* cl) { + ZStatTimer timer(ZSubPhaseConcurrentRootsClassLoaderDataGraph); + ClassLoaderDataGraph::always_strong_cld_do(cl); +} + ZJavaThreadsIterator::ZJavaThreadsIterator() : _threads(), _claimed(0) {} @@ -77,119 +81,84 @@ uint ZJavaThreadsIterator::claim() { return Atomic::fetch_and_add(&_claimed, 1u); } -void ZJavaThreadsIterator::threads_do(ThreadClosure* cl) { +void ZJavaThreadsIterator::apply(ThreadClosure* cl) { + ZStatTimer timer(ZSubPhaseConcurrentRootsJavaThreads); + + // The resource mark is needed because interpreter oop maps are + // not reused in concurrent mode. Instead, they are temporary and + // resource allocated. + ResourceMark _rm; + for (uint i = claim(); i < _threads.length(); i = claim()) { cl->do_thread(_threads.thread_at(i)); } } -void ZRelocateRoots::oops_do(OopClosure* cl) { - ZStatTimer timer(ZSubPhasePauseRootsJVMTIWeakExport); - AlwaysTrueClosure always_alive; - JvmtiExport::weak_oops_do(&always_alive, cl); -} - -ZConcurrentRootsIterator::ZConcurrentRootsIterator(int cld_claim) : - _oop_storage_set_iter(), - _java_threads_iter(), - _cld_claim(cld_claim), - _oop_storage_set(this), - _class_loader_data_graph(this), - _java_threads(this), - _code_cache(this) { - ClassLoaderDataGraph::clear_claimed_marks(cld_claim); +ZNMethodsIterator::ZNMethodsIterator() { if (!ClassUnloading) { - ZNMethodTable::nmethods_do_begin(); + ZNMethod::nmethods_do_begin(); } } -ZConcurrentRootsIterator::~ZConcurrentRootsIterator() { +ZNMethodsIterator::~ZNMethodsIterator() { if (!ClassUnloading) { - ZNMethodTable::nmethods_do_end(); + ZNMethod::nmethods_do_end(); } } -void ZConcurrentRootsIterator::do_oop_storage_set(ZRootsIteratorClosure* cl) { - ZStatTimer timer(ZSubPhaseConcurrentRootsOopStorageSet); - _oop_storage_set_iter.oops_do(cl); -} - -void ZConcurrentRootsIterator::do_class_loader_data_graph(ZRootsIteratorClosure* cl) { - ZStatTimer timer(ZSubPhaseConcurrentRootsClassLoaderDataGraph); - CLDToOopClosure cld_cl(cl, _cld_claim); - ClassLoaderDataGraph::always_strong_cld_do(&cld_cl); -} - -void ZConcurrentRootsIterator::do_code_cache(ZRootsIteratorClosure* cl) { +void ZNMethodsIterator::apply(NMethodClosure* cl) { ZStatTimer timer(ZSubPhaseConcurrentRootsCodeCache); - ZNMethod::oops_do(cl, cl->nmethod_entry()); + ZNMethod::nmethods_do(cl); } -class ZConcurrentRootsIteratorThreadClosure : public ThreadClosure { -private: - // The resource mark is needed because interpreter oop maps are - // not reused in concurrent mode. Instead, they are temporary and - // resource allocated. - ResourceMark _rm; - ZRootsIteratorClosure* const _cl; - -public: - ZConcurrentRootsIteratorThreadClosure(ZRootsIteratorClosure* cl) : - _cl(cl) {} - - virtual void do_thread(Thread* thread) { - _cl->do_thread(thread); +ZConcurrentRootsIterator::ZConcurrentRootsIterator(int cld_claim) { + if (cld_claim != ClassLoaderData::_claim_none) { + ClassLoaderDataGraph::clear_claimed_marks(cld_claim); } -}; - -void ZConcurrentRootsIterator::do_java_threads(ZRootsIteratorClosure* cl) { - ZStatTimer timer(ZSubPhaseConcurrentRootsJavaThreads); - ZConcurrentRootsIteratorThreadClosure thread_cl(cl); - _java_threads_iter.threads_do(&thread_cl); } -void ZConcurrentRootsIterator::oops_do(ZRootsIteratorClosure* cl) { - _oop_storage_set.oops_do(cl); - _class_loader_data_graph.oops_do(cl); - _java_threads.oops_do(cl); +void ZConcurrentRootsIterator::apply(OopClosure* cl, + CLDClosure* cld_cl, + ThreadClosure* thread_cl, + NMethodClosure* nm_cl) { + _oop_storage_set.apply(cl); + _class_loader_data_graph.apply(cld_cl); + _java_threads.apply(thread_cl); if (!ClassUnloading) { - _code_cache.oops_do(cl); + _nmethods.apply(nm_cl); } } ZWeakRootsIterator::ZWeakRootsIterator() : - _jvmti_weak_export(this) { + _jvmti_tag_map() { assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); } -void ZWeakRootsIterator::do_jvmti_weak_export(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { - ZStatTimer timer(ZSubPhasePauseWeakRootsJVMTIWeakExport); - JvmtiExport::weak_oops_do(is_alive, cl); +void ZWeakRootsIterator::apply(BoolObjectClosure* is_alive, OopClosure* cl) { + _jvmti_tag_map.apply(is_alive, cl); } -void ZWeakRootsIterator::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { - _jvmti_weak_export.weak_oops_do(is_alive, cl); +void ZJVMTITagMapIterator::apply(BoolObjectClosure* is_alive, OopClosure* cl) { + ZStatTimer timer(ZSubPhasePauseWeakRootsJVMTITagMap); + JvmtiTagMap::weak_oops_do(is_alive, cl); } -void ZWeakRootsIterator::oops_do(ZRootsIteratorClosure* cl) { - AlwaysTrueClosure always_alive; - weak_oops_do(&always_alive, cl); -} +ZWeakOopStorageSetIterator::ZWeakOopStorageSetIterator() : + _iter() {} -ZConcurrentWeakRootsIterator::ZConcurrentWeakRootsIterator() : - _oop_storage_set_iter(), - _oop_storage_set(this) { +void ZWeakOopStorageSetIterator::apply(OopClosure* cl) { + ZStatTimer timer(ZSubPhaseConcurrentWeakRootsOopStorageSet); + _iter.oops_do(cl); } -void ZConcurrentWeakRootsIterator::report_num_dead() { - _oop_storage_set_iter.report_num_dead(); +void ZWeakOopStorageSetIterator::report_num_dead() { + _iter.report_num_dead(); } -void ZConcurrentWeakRootsIterator::do_oop_storage_set(ZRootsIteratorClosure* cl) { - ZStatTimer timer(ZSubPhaseConcurrentWeakRootsOopStorageSet); - _oop_storage_set_iter.oops_do(cl); +void ZConcurrentWeakRootsIterator::report_num_dead() { + _oop_storage_set.iter().report_num_dead(); } -void ZConcurrentWeakRootsIterator::oops_do(ZRootsIteratorClosure* cl) { - _oop_storage_set.oops_do(cl); +void ZConcurrentWeakRootsIterator::apply(OopClosure* cl) { + _oop_storage_set.apply(cl); } diff --git a/src/hotspot/share/gc/z/zRootsIterator.hpp b/src/hotspot/share/gc/z/zRootsIterator.hpp index 49e87cd9799..57b7ce6372d 100644 --- a/src/hotspot/share/gc/z/zRootsIterator.hpp +++ b/src/hotspot/share/gc/z/zRootsIterator.hpp @@ -24,45 +24,56 @@ #ifndef SHARE_GC_Z_ZROOTSITERATOR_HPP #define SHARE_GC_Z_ZROOTSITERATOR_HPP -#include "classfile/classLoaderDataGraph.hpp" #include "gc/shared/oopStorageSetParState.hpp" -#include "gc/z/zNMethod.hpp" -#include "memory/allocation.hpp" +#include "logging/log.hpp" #include "memory/iterator.hpp" #include "runtime/threadSMR.hpp" -class ZRootsIteratorClosure; - -typedef OopStorageSetStrongParState ZOopStorageSetStrongIterator; -typedef OopStorageSetWeakParState ZOopStorageSetWeakIterator; - -template -class ZParallelOopsDo { +template +class ZParallelApply { private: - T* const _iter; + Iterator _iter; volatile bool _completed; public: - ZParallelOopsDo(T* iter); - void oops_do(ZRootsIteratorClosure* cl); + ZParallelApply() : + _iter(), + _completed(false) {} + + template + void apply(ClosureType* cl); + + Iterator& iter() { + return _iter; + } }; -template -class ZSerialWeakOopsDo { +template +class ZSerialWeakApply { private: - T* const _iter; + Iterator _iter; volatile bool _claimed; public: - ZSerialWeakOopsDo(T* iter); - void weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl); + ZSerialWeakApply() : + _iter(), + _claimed(false) {} + + void apply(BoolObjectClosure* is_alive, OopClosure* cl); }; -class ZRootsIteratorClosure : public OopClosure { +class ZStrongOopStorageSetIterator { + OopStorageSetStrongParState _iter; + public: - virtual void do_thread(Thread* thread) {} + ZStrongOopStorageSetIterator(); - virtual ZNMethodEntry nmethod_entry() const = 0; + void apply(OopClosure* cl); +}; + +class ZStrongCLDsIterator { +public: + void apply(CLDClosure* cl); }; class ZJavaThreadsIterator { @@ -75,80 +86,66 @@ class ZJavaThreadsIterator { public: ZJavaThreadsIterator(); - void threads_do(ThreadClosure* cl); + void apply(ThreadClosure* cl); }; -class ZRelocateRoots : public AllStatic { +class ZNMethodsIterator { public: - static void oops_do(OopClosure* cl); + ZNMethodsIterator(); + ~ZNMethodsIterator(); + + void apply(NMethodClosure* cl); }; class ZConcurrentRootsIterator { private: - ZOopStorageSetStrongIterator _oop_storage_set_iter; - ZJavaThreadsIterator _java_threads_iter; - const int _cld_claim; - - void do_oop_storage_set(ZRootsIteratorClosure* cl); - void do_java_threads(ZRootsIteratorClosure* cl); - void do_class_loader_data_graph(ZRootsIteratorClosure* cl); - void do_code_cache(ZRootsIteratorClosure* cl); - - ZParallelOopsDo _oop_storage_set; - ZParallelOopsDo _class_loader_data_graph; - ZParallelOopsDo _java_threads; - ZParallelOopsDo _code_cache; + ZParallelApply _oop_storage_set; + ZParallelApply _class_loader_data_graph; + ZParallelApply _java_threads; + ZParallelApply _nmethods; public: ZConcurrentRootsIterator(int cld_claim); - ~ZConcurrentRootsIterator(); - void oops_do(ZRootsIteratorClosure* cl); + void apply(OopClosure* cl, + CLDClosure* cld_cl, + ThreadClosure* thread_cl, + NMethodClosure* nm_cl); }; -class ZConcurrentRootsIteratorClaimStrong : public ZConcurrentRootsIterator { -public: - ZConcurrentRootsIteratorClaimStrong() : - ZConcurrentRootsIterator(ClassLoaderData::_claim_strong) {} -}; +class ZWeakOopStorageSetIterator { +private: + OopStorageSetWeakParState _iter; -class ZConcurrentRootsIteratorClaimOther : public ZConcurrentRootsIterator { public: - ZConcurrentRootsIteratorClaimOther() : - ZConcurrentRootsIterator(ClassLoaderData::_claim_other) {} + ZWeakOopStorageSetIterator(); + + void apply(OopClosure* cl); + + void report_num_dead(); }; -class ZConcurrentRootsIteratorClaimNone : public ZConcurrentRootsIterator { +class ZJVMTITagMapIterator { public: - ZConcurrentRootsIteratorClaimNone() : - ZConcurrentRootsIterator(ClassLoaderData::_claim_none) {} + void apply(BoolObjectClosure* is_alive, OopClosure* cl); }; class ZWeakRootsIterator { private: - void do_jvmti_weak_export(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl); - - ZSerialWeakOopsDo _jvmti_weak_export; + ZSerialWeakApply _jvmti_tag_map; public: ZWeakRootsIterator(); - void weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl); - void oops_do(ZRootsIteratorClosure* cl); + void apply(BoolObjectClosure* is_alive, OopClosure* cl); }; class ZConcurrentWeakRootsIterator { private: - ZOopStorageSetWeakIterator _oop_storage_set_iter; - - void do_oop_storage_set(ZRootsIteratorClosure* cl); - - ZParallelOopsDo _oop_storage_set; + ZParallelApply _oop_storage_set; public: - ZConcurrentWeakRootsIterator(); - - void oops_do(ZRootsIteratorClosure* cl); + void apply(OopClosure* cl); void report_num_dead(); }; diff --git a/src/hotspot/share/gc/z/zStat.cpp b/src/hotspot/share/gc/z/zStat.cpp index c1441005eae..5d2933289d2 100644 --- a/src/hotspot/share/gc/z/zStat.cpp +++ b/src/hotspot/share/gc/z/zStat.cpp @@ -1147,7 +1147,7 @@ void ZStatRelocation::set_at_select_relocation_set(const ZRelocationSetSelectorS _stats = stats; } -void ZStatRelocation::set_at_populate_relocation_set(size_t forwarding_usage) { +void ZStatRelocation::set_at_install_relocation_set(size_t forwarding_usage) { _forwarding_usage = forwarding_usage; } diff --git a/src/hotspot/share/gc/z/zStat.hpp b/src/hotspot/share/gc/z/zStat.hpp index d8e8c868e5d..6d44c3c99c5 100644 --- a/src/hotspot/share/gc/z/zStat.hpp +++ b/src/hotspot/share/gc/z/zStat.hpp @@ -430,7 +430,7 @@ class ZStatRelocation : public AllStatic { public: static void set_at_select_relocation_set(const ZRelocationSetSelectorStats& stats); - static void set_at_populate_relocation_set(size_t forwarding_usage); + static void set_at_install_relocation_set(size_t forwarding_usage); static void set_at_relocate_end(bool success); static void print(); diff --git a/src/hotspot/share/gc/z/zUnload.cpp b/src/hotspot/share/gc/z/zUnload.cpp index 6eb23088bf3..e4d2cfc6eec 100644 --- a/src/hotspot/share/gc/z/zUnload.cpp +++ b/src/hotspot/share/gc/z/zUnload.cpp @@ -72,7 +72,7 @@ class ZIsUnloadingBehaviour : public IsUnloadingBehaviour { ZReentrantLock* const lock = ZNMethod::lock_for_nmethod(nm); ZLocker locker(lock); ZIsUnloadingOopClosure cl; - ZNMethod::nmethod_oops_do(nm, &cl); + ZNMethod::nmethod_oops_do_inner(nm, &cl); return cl.is_unloading(); } }; diff --git a/src/hotspot/share/gc/z/zVerify.cpp b/src/hotspot/share/gc/z/zVerify.cpp index a10d64c1e87..1481a8576d5 100644 --- a/src/hotspot/share/gc/z/zVerify.cpp +++ b/src/hotspot/share/gc/z/zVerify.cpp @@ -25,6 +25,7 @@ #include "classfile/classLoaderData.hpp" #include "gc/z/zAddress.inline.hpp" #include "gc/z/zHeap.inline.hpp" +#include "gc/z/zNMethod.hpp" #include "gc/z/zOop.hpp" #include "gc/z/zPageAllocator.hpp" #include "gc/z/zResurrection.hpp" @@ -66,7 +67,7 @@ static void z_verify_possibly_weak_oop(oop* p) { } } -class ZVerifyRootClosure : public ZRootsIteratorClosure { +class ZVerifyRootClosure : public OopClosure { private: const bool _verify_fixed; @@ -89,16 +90,9 @@ class ZVerifyRootClosure : public ZRootsIteratorClosure { ShouldNotReachHere(); } - virtual void do_thread(Thread* thread); - bool verify_fixed() const { return _verify_fixed; } - - virtual ZNMethodEntry nmethod_entry() const { - // Verification performs its own verification - return ZNMethodEntry::None; - } }; class ZVerifyCodeBlobClosure : public CodeBlobToOopClosure { @@ -181,18 +175,6 @@ class ZVerifyStack : public OopClosure { } }; -void ZVerifyRootClosure::do_thread(Thread* thread) { - thread->oops_do_no_frames(this, NULL); - - JavaThread* const jt = thread->as_Java_thread(); - if (!jt->has_last_Java_frame()) { - return; - } - - ZVerifyStack verify_stack(this, jt); - verify_stack.verify_frames(); -} - class ZVerifyOopClosure : public ClaimMetadataVisitingOopIterateClosure { private: const bool _verify_weaks; @@ -221,35 +203,90 @@ class ZVerifyOopClosure : public ClaimMetadataVisitingOopIterateClosure { } }; -template -void ZVerify::roots(bool verify_fixed) { - assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); - assert(!ZResurrection::is_blocked(), "Invalid phase"); +typedef ClaimingCLDToOopClosure ZVerifyCLDClosure; - if (ZVerifyRoots) { - ZVerifyRootClosure cl(verify_fixed); - RootsIterator iter; - iter.oops_do(&cl); +class ZVerifyThreadClosure : public ThreadClosure { +private: + ZVerifyRootClosure* const _cl; + +public: + ZVerifyThreadClosure(ZVerifyRootClosure* cl) : + _cl(cl) {} + + virtual void do_thread(Thread* thread) { + thread->oops_do_no_frames(_cl, NULL); + + JavaThread* const jt = thread->as_Java_thread(); + if (!jt->has_last_Java_frame()) { + return; + } + + ZVerifyStack verify_stack(_cl, jt); + verify_stack.verify_frames(); } -} +}; -void ZVerify::roots_weak() { - roots(true /* verify_fixed */); -} +class ZVerifyNMethodClosure : public NMethodClosure { +private: + OopClosure* const _cl; + BarrierSetNMethod* const _bs_nm; + const bool _verify_fixed; + + bool trust_nmethod_state() const { + // The root iterator will visit non-processed + // nmethods class unloading is turned off. + return ClassUnloading || _verify_fixed; + } + +public: + ZVerifyNMethodClosure(OopClosure* cl, bool verify_fixed) : + _cl(cl), + _bs_nm(BarrierSet::barrier_set()->barrier_set_nmethod()), + _verify_fixed(verify_fixed) {} + + virtual void do_nmethod(nmethod* nm) { + assert(!trust_nmethod_state() || !_bs_nm->is_armed(nm), "Should not encounter any armed nmethods"); + + ZNMethod::nmethod_oops_do(nm, _cl); + } +}; void ZVerify::roots_concurrent_strong(bool verify_fixed) { - roots(verify_fixed); + ZVerifyRootClosure cl(verify_fixed); + ZVerifyCLDClosure cld_cl(&cl); + ZVerifyThreadClosure thread_cl(&cl); + ZVerifyNMethodClosure nm_cl(&cl, verify_fixed); + + ZConcurrentRootsIterator iter(ClassLoaderData::_claim_none); + iter.apply(&cl, + &cld_cl, + &thread_cl, + &nm_cl); +} + +void ZVerify::roots_weak() { + AlwaysTrueClosure is_alive; + ZVerifyRootClosure cl(true /* verify_fixed */); + ZWeakRootsIterator iter; + iter.apply(&is_alive, &cl); } void ZVerify::roots_concurrent_weak() { - roots(true /* verify_fixed */); + ZVerifyRootClosure cl(true /* verify_fixed */); + ZConcurrentWeakRootsIterator iter; + iter.apply(&cl); } void ZVerify::roots(bool verify_concurrent_strong, bool verify_weaks) { - roots_concurrent_strong(verify_concurrent_strong); - if (verify_weaks) { - roots_weak(); - roots_concurrent_weak(); + assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); + assert(!ZResurrection::is_blocked(), "Invalid phase"); + + if (ZVerifyRoots) { + roots_concurrent_strong(verify_concurrent_strong); + if (verify_weaks) { + roots_weak(); + roots_concurrent_weak(); + } } } diff --git a/src/hotspot/share/gc/z/zVerify.hpp b/src/hotspot/share/gc/z/zVerify.hpp index 4d405b957bb..400fc05a589 100644 --- a/src/hotspot/share/gc/z/zVerify.hpp +++ b/src/hotspot/share/gc/z/zVerify.hpp @@ -31,10 +31,8 @@ class ZPageAllocator; class ZVerify : public AllStatic { private: - template static void roots(bool verify_fixed); - - static void roots_weak(); static void roots_concurrent_strong(bool verify_fixed); + static void roots_weak(); static void roots_concurrent_weak(); static void roots(bool verify_concurrent_strong, bool verify_weaks); diff --git a/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp b/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp index 0c22b3efff4..7c88523b37c 100644 --- a/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp +++ b/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp @@ -41,13 +41,13 @@ class ZProcessWeakRootsTask : public ZTask { virtual void work() { ZPhantomIsAliveObjectClosure is_alive; ZPhantomKeepAliveOopClosure keep_alive; - _weak_roots.weak_oops_do(&is_alive, &keep_alive); + _weak_roots.apply(&is_alive, &keep_alive); } }; void ZWeakRootsProcessor::process_weak_roots() { ZProcessWeakRootsTask task; - _workers->run_parallel(&task); + _workers->run_serial(&task); } class ZProcessConcurrentWeakRootsTask : public ZTask { @@ -65,7 +65,7 @@ class ZProcessConcurrentWeakRootsTask : public ZTask { virtual void work() { ZPhantomCleanOopClosure cl; - _concurrent_weak_roots.oops_do(&cl); + _concurrent_weak_roots.apply(&cl); } }; diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index 6e09e076d09..35220e2ea60 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -330,6 +330,15 @@ JVM_HasReferencePendingList(JNIEnv *env); JNIEXPORT void JNICALL JVM_WaitForReferencePendingList(JNIEnv *env); +JNIEXPORT jboolean JNICALL +JVM_ReferenceRefersTo(JNIEnv *env, jobject ref, jobject o); + +/* + * java.lang.ref.PhantomReference + */ +JNIEXPORT jboolean JNICALL +JVM_PhantomReferenceRefersTo(JNIEnv *env, jobject ref, jobject o); + /* * java.io.ObjectInputStream */ diff --git a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp index ba162c35703..789fd945bd1 100644 --- a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp +++ b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp @@ -28,7 +28,6 @@ #include "gc/shared/threadLocalAllocBuffer.inline.hpp" #include "interpreter/bytecodeHistogram.hpp" #include "interpreter/zero/bytecodeInterpreter.inline.hpp" -#include "interpreter/zero/bytecodeInterpreterProfiling.hpp" #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" #include "logging/log.hpp" @@ -133,17 +132,23 @@ #ifdef PRODUCT #define DO_UPDATE_INSTRUCTION_COUNT(opcode) #else -#define DO_UPDATE_INSTRUCTION_COUNT(opcode) \ -{ \ - BytecodeCounter::_counter_value++; \ - BytecodeHistogram::_counters[(Bytecodes::Code)opcode]++; \ - if (StopInterpreterAt && StopInterpreterAt == BytecodeCounter::_counter_value) os::breakpoint(); \ - if (TraceBytecodes) { \ - CALL_VM((void)InterpreterRuntime::trace_bytecode(THREAD, 0, \ - topOfStack[Interpreter::expr_index_at(1)], \ - topOfStack[Interpreter::expr_index_at(2)]), \ - handle_exception); \ - } \ +#define DO_UPDATE_INSTRUCTION_COUNT(opcode) \ +{ \ + if (PrintBytecodeHistogram) { \ + BytecodeHistogram::_counters[(Bytecodes::Code)opcode]++; \ + } \ + if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) { \ + BytecodeCounter::_counter_value++; \ + if (StopInterpreterAt == BytecodeCounter::_counter_value) { \ + os::breakpoint(); \ + } \ + if (TraceBytecodes) { \ + CALL_VM((void)InterpreterRuntime::trace_bytecode(THREAD, 0, \ + topOfStack[Interpreter::expr_index_at(1)], \ + topOfStack[Interpreter::expr_index_at(2)]), \ + handle_exception); \ + } \ + } \ } #endif @@ -416,8 +421,6 @@ BytecodeInterpreter::run(interpreterState istate) { static bool _jvmti_interp_events = 0; #endif - static int _compiling; // (UseCompiler || CountCompiledCalls) - #ifdef ASSERT if (istate->_msg != initialize) { assert(labs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + 1), "bad stack limit"); @@ -546,12 +549,12 @@ BytecodeInterpreter::run(interpreterState istate) { topOfStack < istate->stack_base(), "Stack top out of range"); - const uint mdo_last_branch_taken_count = 0; + assert(!UseCompiler, "Zero does not support compilers"); + assert(!CountCompiledCalls, "Zero does not support counting compiled calls"); switch (istate->msg()) { case initialize: { if (initialized++) ShouldNotReachHere(); // Only one initialize call. - _compiling = (UseCompiler || CountCompiledCalls); #ifdef VM_JVMTI _jvmti_interp_events = JvmtiExport::can_post_interpreter_events(); #endif @@ -562,11 +565,6 @@ BytecodeInterpreter::run(interpreterState istate) { THREAD->set_do_not_unlock(); // count invocations assert(initialized, "Interpreter not initialized"); - if (_compiling) { - // Get or create profile data. Check for pending (async) exceptions. - BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception); - SAFEPOINT; - } if ((istate->_stack_base - istate->_stack_limit) != istate->method()->max_stack() + 1) { // initialize @@ -689,12 +687,6 @@ BytecodeInterpreter::run(interpreterState istate) { // clear the message so we don't confuse ourselves later assert(THREAD->pop_frame_in_process(), "wrong frame pop state"); istate->set_msg(no_request); - if (_compiling) { - // Set MDX back to the ProfileData of the invoke bytecode that will be - // restarted. - SET_MDX(NULL); - BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception); - } THREAD->clr_pop_frame_in_process(); goto run; } @@ -716,11 +708,6 @@ BytecodeInterpreter::run(interpreterState istate) { if (THREAD->has_pending_exception()) goto handle_exception; // Update the pc by the saved amount of the invoke bytecode size UPDATE_PC(istate->bcp_advance()); - - if (_compiling) { - // Get or create profile data. Check for pending (async) exceptions. - BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception); - } goto run; } @@ -728,11 +715,6 @@ BytecodeInterpreter::run(interpreterState istate) { // Returned from an opcode that will reexecute. Deopt was // a result of a PopFrame request. // - - if (_compiling) { - // Get or create profile data. Check for pending (async) exceptions. - BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception); - } goto run; } @@ -755,11 +737,6 @@ BytecodeInterpreter::run(interpreterState istate) { } UPDATE_PC(Bytecodes::length_at(METHOD, pc)); if (THREAD->has_pending_exception()) goto handle_exception; - - if (_compiling) { - // Get or create profile data. Check for pending (async) exceptions. - BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception); - } goto run; } case got_monitors: { @@ -1058,9 +1035,6 @@ BytecodeInterpreter::run(interpreterState istate) { UPDATE_PC_AND_CONTINUE(6); } case Bytecodes::_ret: - // Profile ret. - BI_PROFILE_UPDATE_RET(/*bci=*/((int)(intptr_t)(LOCALS_ADDR(reg)))); - // Now, update the pc. pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(reg)); UPDATE_PC_AND_CONTINUE(0); default: @@ -1370,23 +1344,17 @@ BytecodeInterpreter::run(interpreterState istate) { #define COMPARISON_OP(name, comparison) \ CASE(_if_icmp##name): { \ - const bool cmp = (STACK_INT(-2) comparison STACK_INT(-1)); \ - int skip = cmp \ + int skip = (STACK_INT(-2) comparison STACK_INT(-1)) \ ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ address branch_pc = pc; \ - /* Profile branch. */ \ - BI_PROFILE_UPDATE_BRANCH(/*is_taken=*/cmp); \ UPDATE_PC_AND_TOS(skip, -2); \ DO_BACKEDGE_CHECKS(skip, branch_pc); \ CONTINUE; \ } \ CASE(_if##name): { \ - const bool cmp = (STACK_INT(-1) comparison 0); \ - int skip = cmp \ + int skip = (STACK_INT(-1) comparison 0) \ ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ address branch_pc = pc; \ - /* Profile branch. */ \ - BI_PROFILE_UPDATE_BRANCH(/*is_taken=*/cmp); \ UPDATE_PC_AND_TOS(skip, -1); \ DO_BACKEDGE_CHECKS(skip, branch_pc); \ CONTINUE; \ @@ -1395,12 +1363,9 @@ BytecodeInterpreter::run(interpreterState istate) { #define COMPARISON_OP2(name, comparison) \ COMPARISON_OP(name, comparison) \ CASE(_if_acmp##name): { \ - const bool cmp = (STACK_OBJECT(-2) comparison STACK_OBJECT(-1)); \ - int skip = cmp \ + int skip = (STACK_OBJECT(-2) comparison STACK_OBJECT(-1)) \ ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ address branch_pc = pc; \ - /* Profile branch. */ \ - BI_PROFILE_UPDATE_BRANCH(/*is_taken=*/cmp); \ UPDATE_PC_AND_TOS(skip, -2); \ DO_BACKEDGE_CHECKS(skip, branch_pc); \ CONTINUE; \ @@ -1408,12 +1373,9 @@ BytecodeInterpreter::run(interpreterState istate) { #define NULL_COMPARISON_NOT_OP(name) \ CASE(_if##name): { \ - const bool cmp = (!(STACK_OBJECT(-1) == NULL)); \ - int skip = cmp \ + int skip = (!(STACK_OBJECT(-1) == NULL)) \ ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ address branch_pc = pc; \ - /* Profile branch. */ \ - BI_PROFILE_UPDATE_BRANCH(/*is_taken=*/cmp); \ UPDATE_PC_AND_TOS(skip, -1); \ DO_BACKEDGE_CHECKS(skip, branch_pc); \ CONTINUE; \ @@ -1421,12 +1383,9 @@ BytecodeInterpreter::run(interpreterState istate) { #define NULL_COMPARISON_OP(name) \ CASE(_if##name): { \ - const bool cmp = ((STACK_OBJECT(-1) == NULL)); \ - int skip = cmp \ + int skip = ((STACK_OBJECT(-1) == NULL)) \ ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ address branch_pc = pc; \ - /* Profile branch. */ \ - BI_PROFILE_UPDATE_BRANCH(/*is_taken=*/cmp); \ UPDATE_PC_AND_TOS(skip, -1); \ DO_BACKEDGE_CHECKS(skip, branch_pc); \ CONTINUE; \ @@ -1450,13 +1409,10 @@ BytecodeInterpreter::run(interpreterState istate) { int32_t skip; key -= low; if (((uint32_t) key > (uint32_t)(high - low))) { - key = -1; skip = Bytes::get_Java_u4((address)&lpc[0]); } else { skip = Bytes::get_Java_u4((address)&lpc[key + 3]); } - // Profile switch. - BI_PROFILE_UPDATE_SWITCH(/*switch_index=*/key); // Does this really need a full backedge check (osr)? address branch_pc = pc; UPDATE_PC_AND_TOS(skip, -1); @@ -1470,21 +1426,14 @@ BytecodeInterpreter::run(interpreterState istate) { jint* lpc = (jint*)VMalignWordUp(pc+1); int32_t key = STACK_INT(-1); int32_t skip = Bytes::get_Java_u4((address) lpc); /* default amount */ - // Remember index. - int index = -1; - int newindex = 0; int32_t npairs = Bytes::get_Java_u4((address) &lpc[1]); while (--npairs >= 0) { lpc += 2; if (key == (int32_t)Bytes::get_Java_u4((address)lpc)) { skip = Bytes::get_Java_u4((address)&lpc[1]); - index = newindex; break; } - newindex += 1; } - // Profile switch. - BI_PROFILE_UPDATE_SWITCH(/*switch_index=*/index); address branch_pc = pc; UPDATE_PC_AND_TOS(skip, -1); DO_BACKEDGE_CHECKS(skip, branch_pc); @@ -1650,15 +1599,8 @@ BytecodeInterpreter::run(interpreterState istate) { // Seems way more expensive now that we must dispatch // if (rhsKlass != elemKlass && !rhsKlass->is_subtype_of(elemKlass)) { // ebx->is... - // Decrement counter if subtype check failed. - BI_PROFILE_SUBTYPECHECK_FAILED(rhsKlass); VM_JAVA_ERROR(vmSymbols::java_lang_ArrayStoreException(), ""); } - // Profile checkcast with null_seen and receiver. - BI_PROFILE_UPDATE_CHECKCAST(/*null_seen=*/false, rhsKlass); - } else { - // Profile checkcast with null_seen and receiver. - BI_PROFILE_UPDATE_CHECKCAST(/*null_seen=*/true, NULL); } ((objArrayOop) arrObj)->obj_at_put(index, rhsObject); UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); @@ -2169,26 +2111,17 @@ BytecodeInterpreter::run(interpreterState istate) { // Seems way more expensive now that we must dispatch. // if (objKlass != klassOf && !objKlass->is_subtype_of(klassOf)) { - // Decrement counter at checkcast. - BI_PROFILE_SUBTYPECHECK_FAILED(objKlass); ResourceMark rm(THREAD); char* message = SharedRuntime::generate_class_cast_message( objKlass, klassOf); VM_JAVA_ERROR(vmSymbols::java_lang_ClassCastException(), message); } - // Profile checkcast with null_seen and receiver. - BI_PROFILE_UPDATE_CHECKCAST(/*null_seen=*/false, objKlass); - } else { - // Profile checkcast with null_seen and receiver. - BI_PROFILE_UPDATE_CHECKCAST(/*null_seen=*/true, NULL); } UPDATE_PC_AND_CONTINUE(3); CASE(_instanceof): if (STACK_OBJECT(-1) == NULL) { SET_STACK_INT(0, -1); - // Profile instanceof with null_seen and receiver. - BI_PROFILE_UPDATE_INSTANCEOF(/*null_seen=*/true, NULL); } else { VERIFY_OOP(STACK_OBJECT(-1)); u2 index = Bytes::get_Java_u2(pc+1); @@ -2207,11 +2140,7 @@ BytecodeInterpreter::run(interpreterState istate) { SET_STACK_INT(1, -1); } else { SET_STACK_INT(0, -1); - // Decrement counter at checkcast. - BI_PROFILE_SUBTYPECHECK_FAILED(objKlass); } - // Profile instanceof with null_seen and receiver. - BI_PROFILE_UPDATE_INSTANCEOF(/*null_seen=*/false, objKlass); } UPDATE_PC_AND_CONTINUE(3); @@ -2266,6 +2195,7 @@ BytecodeInterpreter::run(interpreterState istate) { break; case JVM_CONSTANT_Dynamic: + case JVM_CONSTANT_DynamicInError: { CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode), handle_exception); oop result = THREAD->vm_result(); @@ -2307,6 +2237,7 @@ BytecodeInterpreter::run(interpreterState istate) { break; case JVM_CONSTANT_Dynamic: + case JVM_CONSTANT_DynamicInError: { CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode), handle_exception); oop result = THREAD->vm_result(); @@ -2386,9 +2317,6 @@ BytecodeInterpreter::run(interpreterState istate) { istate->set_callee_entry_point(method->from_interpreted_entry()); istate->set_bcp_advance(5); - // Invokedynamic has got a call counter, just like an invokestatic -> increment! - BI_PROFILE_UPDATE_CALL(); - UPDATE_PC_AND_RETURN(0); // I'll be back... } @@ -2417,9 +2345,6 @@ BytecodeInterpreter::run(interpreterState istate) { istate->set_callee_entry_point(method->from_interpreted_entry()); istate->set_bcp_advance(3); - // Invokehandle has got a call counter, just like a final call -> increment! - BI_PROFILE_UPDATE_FINALCALL(); - UPDATE_PC_AND_RETURN(0); // I'll be back... } @@ -2445,8 +2370,6 @@ BytecodeInterpreter::run(interpreterState istate) { CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); if (cache->is_vfinal()) { callee = cache->f2_as_vfinal_method(); - // Profile 'special case of invokeinterface' final call. - BI_PROFILE_UPDATE_FINALCALL(); } else { // Get receiver. int parms = cache->parameter_size(); @@ -2455,8 +2378,6 @@ BytecodeInterpreter::run(interpreterState istate) { VERIFY_OOP(rcvr); Klass* rcvrKlass = rcvr->klass(); callee = (Method*) rcvrKlass->method_at_vtable(cache->f2_as_index()); - // Profile 'special case of invokeinterface' virtual call. - BI_PROFILE_UPDATE_VIRTUALCALL(rcvrKlass); } } else if (cache->is_vfinal()) { // private interface method invocations @@ -2543,9 +2464,6 @@ BytecodeInterpreter::run(interpreterState istate) { handle_exception); } - // Profile virtual call. - BI_PROFILE_UPDATE_VIRTUALCALL(rcvr->klass()); - istate->set_callee(callee); istate->set_callee_entry_point(callee->from_interpreted_entry()); #ifdef VM_JVMTI @@ -2579,8 +2497,6 @@ BytecodeInterpreter::run(interpreterState istate) { CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); if (cache->is_vfinal()) { callee = cache->f2_as_vfinal_method(); - // Profile final call. - BI_PROFILE_UPDATE_FINALCALL(); } else { // get receiver int parms = cache->parameter_size(); @@ -2610,17 +2526,12 @@ BytecodeInterpreter::run(interpreterState istate) { Because vtables have the same offset for ArrayKlass and InstanceKlass. */ callee = (Method*) rcvrKlass->method_at_vtable(cache->f2_as_index()); - // Profile virtual call. - BI_PROFILE_UPDATE_VIRTUALCALL(rcvrKlass); } } else { if ((Bytecodes::Code)opcode == Bytecodes::_invokespecial) { CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); } callee = cache->f1_as_method(); - - // Profile call. - BI_PROFILE_UPDATE_CALL(); } istate->set_callee(callee); @@ -2675,8 +2586,6 @@ BytecodeInterpreter::run(interpreterState istate) { CASE(_goto): { int16_t offset = (int16_t)Bytes::get_Java_u2(pc + 1); - // Profile jump. - BI_PROFILE_UPDATE_JUMP(); address branch_pc = pc; UPDATE_PC(offset); DO_BACKEDGE_CHECKS(offset, branch_pc); @@ -2693,8 +2602,6 @@ BytecodeInterpreter::run(interpreterState istate) { CASE(_goto_w): { int32_t offset = Bytes::get_Java_u4(pc + 1); - // Profile jump. - BI_PROFILE_UPDATE_JUMP(); address branch_pc = pc; UPDATE_PC(offset); DO_BACKEDGE_CHECKS(offset, branch_pc); @@ -2704,9 +2611,6 @@ BytecodeInterpreter::run(interpreterState istate) { /* return from a jsr or jsr_w */ CASE(_ret): { - // Profile ret. - BI_PROFILE_UPDATE_RET(/*bci=*/((int)(intptr_t)(LOCALS_ADDR(pc[1])))); - // Now, update the pc. pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(pc[1])); UPDATE_PC_AND_CONTINUE(0); } @@ -2789,9 +2693,6 @@ BytecodeInterpreter::run(interpreterState istate) { } // for AbortVMOnException flag Exceptions::debug_check_abort(except_oop); - - // Update profiling data. - BI_PROFILE_ALIGN_TO_CURRENT_BCI(); goto run; } if (log_is_enabled(Info, exceptions)) { @@ -2902,7 +2803,9 @@ BytecodeInterpreter::run(interpreterState istate) { // a NULL oop in it and then overwrite the oop later as needed. This isn't // unfortunately isn't possible. - THREAD->clear_pending_exception(); + if (THREAD->has_pending_exception()) { + THREAD->clear_pending_exception(); + } // // As far as we are concerned we have returned. If we have a pending exception @@ -3383,7 +3286,6 @@ BytecodeInterpreter::print() { char *method_name = _method->name_and_sig_as_C_string(); tty->print_cr("method: " INTPTR_FORMAT "[ %s ]", (uintptr_t) this->_method, method_name); } - tty->print_cr("mdx: " INTPTR_FORMAT, (uintptr_t) this->_mdx); tty->print_cr("stack: " INTPTR_FORMAT, (uintptr_t) this->_stack); tty->print_cr("msg: %s", C_msg(this->_msg)); tty->print_cr("result_to_call._callee: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee); diff --git a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.hpp b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.hpp index 2d6f86c1f4f..df2943a1e3f 100644 --- a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.hpp +++ b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.hpp @@ -26,7 +26,6 @@ #define SHARE_INTERPRETER_BYTECODEINTERPRETER_HPP #include "memory/allocation.hpp" -#include "oops/methodData.hpp" #include "oops/method.hpp" #include "runtime/basicLock.hpp" #include "runtime/frame.hpp" @@ -110,7 +109,6 @@ friend class VMStructs; ConstantPoolCache* _constants; // constant pool cache Method* _method; // method being executed oop _mirror; // mirror to klass containing method - DataLayout* _mdx; // compiler profiling data for current bytecode intptr_t* _stack; // expression stack messages _msg; // frame manager <-> interpreter message frame_manager_message _result; // result to frame manager @@ -188,8 +186,6 @@ inline intptr_t* locals() { return _locals; } inline ConstantPoolCache* constants() { return _constants; } inline Method* method() { return _method; } -inline DataLayout* mdx() { return _mdx; } -inline void set_mdx(DataLayout *new_mdx) { _mdx = new_mdx; } inline messages msg() { return _msg; } inline void set_msg(messages new_msg) { _msg = new_msg; } diff --git a/src/hotspot/share/interpreter/zero/bytecodeInterpreterProfiling.hpp b/src/hotspot/share/interpreter/zero/bytecodeInterpreterProfiling.hpp deleted file mode 100644 index 49e8d4756fd..00000000000 --- a/src/hotspot/share/interpreter/zero/bytecodeInterpreterProfiling.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 SAP SE. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -// This file defines a set of macros which are used by the c++-interpreter -// for updating a method's methodData object. - - -#ifndef SHARE_INTERPRETER_BYTECODEINTERPRETERPROFILING_HPP -#define SHARE_INTERPRETER_BYTECODEINTERPRETERPROFILING_HPP - -// Empty dummy implementations if profiling code is switched off. ////////////// - -#define SET_MDX(mdx) - -#define BI_PROFILE_GET_OR_CREATE_METHOD_DATA(exception_handler) \ - if (ProfileInterpreter) { \ - ShouldNotReachHere(); \ - } - -#define BI_PROFILE_ALIGN_TO_CURRENT_BCI() - -#define BI_PROFILE_UPDATE_JUMP() -#define BI_PROFILE_UPDATE_BRANCH(is_taken) -#define BI_PROFILE_UPDATE_RET(bci) -#define BI_PROFILE_SUBTYPECHECK_FAILED(receiver) -#define BI_PROFILE_UPDATE_CHECKCAST(null_seen, receiver) -#define BI_PROFILE_UPDATE_INSTANCEOF(null_seen, receiver) -#define BI_PROFILE_UPDATE_CALL() -#define BI_PROFILE_UPDATE_FINALCALL() -#define BI_PROFILE_UPDATE_VIRTUALCALL(receiver) -#define BI_PROFILE_UPDATE_SWITCH(switch_index) - -#endif // SHARE_INTERPRETER_BYTECODEINTERPRETERPROFILING_HPP diff --git a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp index 946ff0e5bb0..2070e631a21 100644 --- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp +++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp @@ -285,7 +285,7 @@ TRACE_REQUEST_FUNC(ThreadContextSwitchRate) { Event ## eventType event; \ event.set_name(flag->name()); \ event.set_value(flag->get_ ## flagType()); \ - event.set_origin(flag->get_origin()); \ + event.set_origin(static_cast(flag->get_origin())); \ event.commit(); \ } \ } \ diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp index b2b0e58cf9d..f867ce14226 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp @@ -122,27 +122,29 @@ void JfrThreadGroupConstant::serialize(JfrCheckpointWriter& writer) { JfrThreadGroup::serialize(writer); } -static const char* flag_value_origin_to_string(JVMFlag::Flags origin) { +static const char* flag_value_origin_to_string(JVMFlagOrigin origin) { switch (origin) { - case JVMFlag::DEFAULT: return "Default"; - case JVMFlag::COMMAND_LINE: return "Command line"; - case JVMFlag::ENVIRON_VAR: return "Environment variable"; - case JVMFlag::CONFIG_FILE: return "Config file"; - case JVMFlag::MANAGEMENT: return "Management"; - case JVMFlag::ERGONOMIC: return "Ergonomic"; - case JVMFlag::ATTACH_ON_DEMAND: return "Attach on demand"; - case JVMFlag::INTERNAL: return "Internal"; - case JVMFlag::JIMAGE_RESOURCE: return "JImage resource"; + case JVMFlagOrigin::DEFAULT: return "Default"; + case JVMFlagOrigin::COMMAND_LINE: return "Command line"; + case JVMFlagOrigin::ENVIRON_VAR: return "Environment variable"; + case JVMFlagOrigin::CONFIG_FILE: return "Config file"; + case JVMFlagOrigin::MANAGEMENT: return "Management"; + case JVMFlagOrigin::ERGONOMIC: return "Ergonomic"; + case JVMFlagOrigin::ATTACH_ON_DEMAND: return "Attach on demand"; + case JVMFlagOrigin::INTERNAL: return "Internal"; + case JVMFlagOrigin::JIMAGE_RESOURCE: return "JImage resource"; default: ShouldNotReachHere(); return ""; } } void FlagValueOriginConstant::serialize(JfrCheckpointWriter& writer) { - static const u4 nof_entries = JVMFlag::LAST_VALUE_ORIGIN + 1; - writer.write_count(nof_entries); - for (u4 i = 0; i < nof_entries; ++i) { - writer.write_key(i); - writer.write(flag_value_origin_to_string((JVMFlag::Flags)i)); + constexpr EnumRange range; + writer.write_count(static_cast(range.size())); + + for (EnumIterator it = range.begin(); it != range.end(); ++it) { + JVMFlagOrigin origin = *it; + writer.write_key(static_cast(origin)); + writer.write(flag_value_origin_to_string(origin)); } } diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 5e1f68b464a..466e6c8e035 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -1995,6 +1995,14 @@ C2V_VMENTRY_NULL(jobject, readFieldValue, (JNIEnv* env, jobject, jobject object, JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Unexpected type: %s", JVMCIENV->klass_name(base))); } + + if (displacement == java_lang_Class::component_mirror_offset() && java_lang_Class::is_instance(obj()) && + !java_lang_Class::as_Klass(obj())->is_array_klass()) { + // Class.componentType for non-array classes can transiently contain an int[] that's + // used for locking so always return null to mimic Class.getComponentType() + return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_NULL_POINTER()); + } + jlong value = 0; JVMCIObject kind; switch (constant_type) { @@ -2220,6 +2228,13 @@ C2V_VMENTRY_NULL(jobject, getObject, (JNIEnv* env, jobject, jobject x, long disp JVMCI_THROW_0(NullPointerException); } Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0); + if (displacement == java_lang_Class::component_mirror_offset() && java_lang_Class::is_instance(xobj()) && + !java_lang_Class::as_Klass(xobj())->is_array_klass()) { + // Class.componentType for non-array classes can transiently contain an int[] that's + // used for locking so always return null to mimic Class.getComponentType() + return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_NULL_POINTER()); + } + oop res = xobj->obj_field(displacement); JVMCIObject result = JVMCIENV->get_object_constant(res); return JVMCIENV->get_jobject(result); diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp index fb52b9211e8..3d5cbc213a3 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp @@ -32,6 +32,7 @@ #include "memory/universe.hpp" #include "oops/compressedOops.hpp" #include "oops/klass.inline.hpp" +#include "runtime/flags/jvmFlag.hpp" #include "runtime/sharedRuntime.hpp" #include "utilities/resourceHash.hpp" diff --git a/src/hotspot/share/jvmci/jvmci_globals.cpp b/src/hotspot/share/jvmci/jvmci_globals.cpp index c9b3869f2f8..bbf3ec67b1b 100644 --- a/src/hotspot/share/jvmci/jvmci_globals.cpp +++ b/src/hotspot/share/jvmci/jvmci_globals.cpp @@ -158,7 +158,7 @@ bool JVMCIGlobals::check_jvmci_flags_are_consistent() { } // Convert JVMCI flags from experimental to product -bool JVMCIGlobals::enable_jvmci_product_mode(JVMFlag::Flags origin) { +bool JVMCIGlobals::enable_jvmci_product_mode(JVMFlagOrigin origin) { const char *JVMCIFlags[] = { "EnableJVMCI", "EnableJVMCIProduct", diff --git a/src/hotspot/share/jvmci/jvmci_globals.hpp b/src/hotspot/share/jvmci/jvmci_globals.hpp index dd1a375c732..5009b17db62 100644 --- a/src/hotspot/share/jvmci/jvmci_globals.hpp +++ b/src/hotspot/share/jvmci/jvmci_globals.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_JVMCI_JVMCI_GLOBALS_HPP #define SHARE_JVMCI_JVMCI_GLOBALS_HPP -#include "runtime/flags/jvmFlag.hpp" +#include "utilities/vmEnums.hpp" class fileStream; @@ -153,7 +153,7 @@ class JVMCIGlobals { static bool check_jvmci_flags_are_consistent(); // Convert JVMCI experimental flags to product - static bool enable_jvmci_product_mode(JVMFlag::Flags); + static bool enable_jvmci_product_mode(JVMFlagOrigin); // Check and exit VM with error if selected GC is not supported by JVMCI. static void check_jvmci_supported_gc(); diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 995cf83ad19..9fcfe5eacd5 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -33,6 +33,7 @@ #include "jvmci/vmStructs_jvmci.hpp" #include "oops/objArrayKlass.hpp" #include "runtime/deoptimization.hpp" +#include "runtime/flags/jvmFlag.hpp" #include "runtime/sharedRuntime.hpp" #if INCLUDE_G1GC #include "gc/g1/g1CardTable.hpp" diff --git a/src/hotspot/share/logging/logHandle.hpp b/src/hotspot/share/logging/logHandle.hpp index 3df30ac2900..fad63649b28 100644 --- a/src/hotspot/share/logging/logHandle.hpp +++ b/src/hotspot/share/logging/logHandle.hpp @@ -91,7 +91,9 @@ class LogTargetHandle { void print(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3) { va_list args; va_start(args, fmt); - _tagset->vwrite(_level, fmt, args); + if (is_enabled()) { + _tagset->vwrite(_level, fmt, args); + } va_end(args); } diff --git a/src/hotspot/share/logging/logTag.hpp b/src/hotspot/share/logging/logTag.hpp index ff065bc91a2..5b79f88a18d 100644 --- a/src/hotspot/share/logging/logTag.hpp +++ b/src/hotspot/share/logging/logTag.hpp @@ -77,9 +77,11 @@ LOG_TAG(free) \ LOG_TAG(freelist) \ LOG_TAG(gc) \ + NOT_PRODUCT(LOG_TAG(generate)) \ LOG_TAG(handshake) \ LOG_TAG(hashtables) \ LOG_TAG(heap) \ + NOT_PRODUCT(LOG_TAG(heapsampling)) \ LOG_TAG(humongous) \ LOG_TAG(ihop) \ LOG_TAG(iklass) \ diff --git a/src/hotspot/share/memory/archiveUtils.cpp b/src/hotspot/share/memory/archiveUtils.cpp index 9b390d4a89f..4474519fd72 100644 --- a/src/hotspot/share/memory/archiveUtils.cpp +++ b/src/hotspot/share/memory/archiveUtils.cpp @@ -319,3 +319,12 @@ void ArchiveUtils::log_to_classlist(BootstrapInfo* bootstrap_specifier, TRAPS) { } } } + +void ArchiveUtils::check_for_oom(oop exception) { + assert(exception != nullptr, "Sanity check"); + if (exception->is_a(SystemDictionary::OutOfMemoryError_klass())) { + vm_direct_exit(-1, + err_msg("Out of memory. Please run with a larger Java heap, current MaxHeapSize = " + SIZE_FORMAT "M", MaxHeapSize/M)); + } +} diff --git a/src/hotspot/share/memory/archiveUtils.hpp b/src/hotspot/share/memory/archiveUtils.hpp index 8e039c5a12c..4f2ae6f6276 100644 --- a/src/hotspot/share/memory/archiveUtils.hpp +++ b/src/hotspot/share/memory/archiveUtils.hpp @@ -243,6 +243,7 @@ class ReadClosure : public SerializeClosure { class ArchiveUtils { public: static void log_to_classlist(BootstrapInfo* bootstrap_specifier, TRAPS) NOT_CDS_RETURN; + static void check_for_oom(oop exception) NOT_CDS_RETURN; }; #endif // SHARE_MEMORY_ARCHIVEUTILS_HPP diff --git a/src/hotspot/share/memory/heap.cpp b/src/hotspot/share/memory/heap.cpp index 3bcf3043cf3..d55bc07e2c0 100644 --- a/src/hotspot/share/memory/heap.cpp +++ b/src/hotspot/share/memory/heap.cpp @@ -770,7 +770,8 @@ int CodeHeap::segmap_hops(size_t beg, size_t end) { if (beg < end) { // setup _segmap pointers for faster indexing address p = (address)_segmap.low() + beg; - int hops_expected = (int)(((end-beg-1)+(free_sentinel-2))/(free_sentinel-1)); + int hops_expected + = checked_cast(((end-beg-1)+(free_sentinel-2))/(free_sentinel-1)); int nhops = 0; size_t ix = end-beg-1; while (p[ix] > 0) { diff --git a/src/hotspot/share/memory/heapShared.cpp b/src/hotspot/share/memory/heapShared.cpp index 1703b1b54cd..8527df81a16 100644 --- a/src/hotspot/share/memory/heapShared.cpp +++ b/src/hotspot/share/memory/heapShared.cpp @@ -206,7 +206,9 @@ oop HeapShared::archive_heap_object(oop obj, Thread* THREAD) { log_error(cds, heap)( "Cannot allocate space for object " PTR_FORMAT " in archived heap region", p2i(obj)); - vm_exit(1); + vm_direct_exit(-1, + err_msg("Out of memory. Please run with a larger Java heap, current MaxHeapSize = " + SIZE_FORMAT "M", MaxHeapSize/M)); } return archived_oop; } @@ -259,15 +261,6 @@ void HeapShared::run_full_gc_in_vm_thread() { void HeapShared::archive_java_heap_objects(GrowableArray *closed, GrowableArray *open) { - if (!is_heap_object_archiving_allowed()) { - log_info(cds)( - "Archived java heap is not supported as UseG1GC, " - "UseCompressedOops and UseCompressedClassPointers are required." - "Current settings: UseG1GC=%s, UseCompressedOops=%s, UseCompressedClassPointers=%s.", - BOOL_TO_STR(UseG1GC), BOOL_TO_STR(UseCompressedOops), - BOOL_TO_STR(UseCompressedClassPointers)); - return; - } G1HeapVerifier::verify_ready_for_archiving(); @@ -734,7 +727,7 @@ oop HeapShared::archive_reachable_objects_from(int level, // these objects that are referenced (directly or indirectly) by static fields. ResourceMark rm; log_error(cds, heap)("Cannot archive object of class %s", orig_obj->klass()->external_name()); - vm_exit(1); + vm_direct_exit(1); } // java.lang.Class instances cannot be included in an archived object sub-graph. We only support @@ -744,7 +737,7 @@ oop HeapShared::archive_reachable_objects_from(int level, // object that is referenced (directly or indirectly) by static fields. if (java_lang_Class::is_instance(orig_obj)) { log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level); - vm_exit(1); + vm_direct_exit(1); } oop archived_obj = find_archived_heap_object(orig_obj); @@ -780,7 +773,7 @@ oop HeapShared::archive_reachable_objects_from(int level, // We don't know how to handle an object that has been archived, but some of its reachable // objects cannot be archived. Bail out for now. We might need to fix this in the future if // we have a real use case. - vm_exit(1); + vm_direct_exit(1); } } @@ -1035,7 +1028,13 @@ void HeapShared::init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[], TempNewSymbol field_name = SymbolTable::new_symbol(info->field_name); Klass* k = SystemDictionary::resolve_or_null(klass_name, THREAD); - assert(k != NULL && !HAS_PENDING_EXCEPTION, "class must exist"); + if (HAS_PENDING_EXCEPTION) { + ResourceMark rm(THREAD); + ArchiveUtils::check_for_oom(PENDING_EXCEPTION); // exit on OOM + log_info(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(), + java_lang_String::as_utf8_string(java_lang_Throwable::message(PENDING_EXCEPTION))); + vm_direct_exit(-1, "VM exits due to exception, use -Xlog:cds,exceptions=trace for detail"); + } InstanceKlass* ik = InstanceKlass::cast(k); assert(InstanceKlass::cast(ik)->is_shared_boot_class(), "Only support boot classes"); @@ -1052,8 +1051,8 @@ void HeapShared::init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[], } void HeapShared::init_subgraph_entry_fields(Thread* THREAD) { + assert(is_heap_object_archiving_allowed(), "Sanity check"); _dump_time_subgraph_info_table = new (ResourceObj::C_HEAP, mtClass)DumpTimeKlassSubGraphInfoTable(); - init_subgraph_entry_fields(closed_archive_subgraph_entry_fields, num_closed_archive_subgraph_entry_fields, THREAD); @@ -1068,8 +1067,10 @@ void HeapShared::init_subgraph_entry_fields(Thread* THREAD) { } void HeapShared::init_for_dumping(Thread* THREAD) { - _dumped_interned_strings = new (ResourceObj::C_HEAP, mtClass)DumpedInternedStrings(); - init_subgraph_entry_fields(THREAD); + if (is_heap_object_archiving_allowed()) { + _dumped_interned_strings = new (ResourceObj::C_HEAP, mtClass)DumpedInternedStrings(); + init_subgraph_entry_fields(THREAD); + } } void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[], diff --git a/src/hotspot/share/memory/iterator.cpp b/src/hotspot/share/memory/iterator.cpp index b0692d5217a..f9fbaf51b90 100644 --- a/src/hotspot/share/memory/iterator.cpp +++ b/src/hotspot/share/memory/iterator.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderDataGraph.hpp" #include "code/nmethod.hpp" #include "memory/iterator.inline.hpp" #include "oops/oop.inline.hpp" @@ -63,3 +64,10 @@ void MarkingCodeBlobClosure::do_code_blob(CodeBlob* cb) { do_nmethod(nm); } } + +void CodeBlobToNMethodClosure::do_code_blob(CodeBlob* cb) { + nmethod* nm = cb->as_nmethod_or_null(); + if (nm != NULL) { + _nm_cl->do_nmethod(nm); + } +} diff --git a/src/hotspot/share/memory/iterator.hpp b/src/hotspot/share/memory/iterator.hpp index 9bf1c22926f..67559629c47 100644 --- a/src/hotspot/share/memory/iterator.hpp +++ b/src/hotspot/share/memory/iterator.hpp @@ -150,6 +150,12 @@ class CLDToOopClosure : public CLDClosure { void do_cld(ClassLoaderData* cld); }; +template +class ClaimingCLDToOopClosure : public CLDToOopClosure { +public: + ClaimingCLDToOopClosure(OopClosure* cl) : CLDToOopClosure(cl, claim) {} +}; + class ClaimMetadataVisitingOopIterateClosure : public OopIterateClosure { protected: const int _claim; @@ -262,6 +268,15 @@ class NMethodClosure : public Closure { virtual void do_nmethod(nmethod* n) = 0; }; +class CodeBlobToNMethodClosure : public CodeBlobClosure { + NMethodClosure* const _nm_cl; + + public: + CodeBlobToNMethodClosure(NMethodClosure* nm_cl) : _nm_cl(nm_cl) {} + + virtual void do_code_blob(CodeBlob* cb); +}; + // MonitorClosure is used for iterating over monitors in the monitors cache class ObjectMonitor; diff --git a/src/hotspot/share/memory/metaspaceShared.cpp b/src/hotspot/share/memory/metaspaceShared.cpp index 34bbc00956d..f3af404e783 100644 --- a/src/hotspot/share/memory/metaspaceShared.cpp +++ b/src/hotspot/share/memory/metaspaceShared.cpp @@ -1098,6 +1098,9 @@ int MetaspaceShared::preload_classes(const char* class_list_path, TRAPS) { int class_count = 0; while (parser.parse_one_line()) { + if (parser.lambda_form_line()) { + continue; + } Klass* klass = parser.load_current_class(THREAD); if (HAS_PENDING_EXCEPTION) { if (klass == NULL && @@ -1165,6 +1168,15 @@ bool MetaspaceShared::try_link_class(InstanceKlass* ik, TRAPS) { #if INCLUDE_CDS_JAVA_HEAP void VM_PopulateDumpSharedSpace::dump_java_heap_objects() { + if(!HeapShared::is_heap_object_archiving_allowed()) { + log_info(cds)( + "Archived java heap is not supported as UseG1GC, " + "UseCompressedOops and UseCompressedClassPointers are required." + "Current settings: UseG1GC=%s, UseCompressedOops=%s, UseCompressedClassPointers=%s.", + BOOL_TO_STR(UseG1GC), BOOL_TO_STR(UseCompressedOops), + BOOL_TO_STR(UseCompressedClassPointers)); + return; + } // Find all the interned strings that should be dumped. int i; for (i = 0; i < _global_klass_objects->length(); i++) { diff --git a/src/hotspot/share/memory/padded.hpp b/src/hotspot/share/memory/padded.hpp index 08003613609..feca46ac7c2 100644 --- a/src/hotspot/share/memory/padded.hpp +++ b/src/hotspot/share/memory/padded.hpp @@ -116,6 +116,7 @@ template class PaddedPrimitiveArray { public: static T* create_unfreeable(size_t length); + static T* create(size_t length, void** alloc_base); }; #endif // SHARE_MEMORY_PADDED_HPP diff --git a/src/hotspot/share/memory/padded.inline.hpp b/src/hotspot/share/memory/padded.inline.hpp index d698f5ee1b3..742db2fe3f8 100644 --- a/src/hotspot/share/memory/padded.inline.hpp +++ b/src/hotspot/share/memory/padded.inline.hpp @@ -82,11 +82,18 @@ T** Padded2DArray::create_unfreeable(uint rows, uint column template T* PaddedPrimitiveArray::create_unfreeable(size_t length) { + void* temp; + return create(length, &temp); +} + +template +T* PaddedPrimitiveArray::create(size_t length, void** alloc_base) { // Allocate a chunk of memory large enough to allow for some alignment. void* chunk = AllocateHeap(length * sizeof(T) + alignment, flags); memset(chunk, 0, length * sizeof(T) + alignment); + *alloc_base = chunk; return (T*)align_up(chunk, alignment); } diff --git a/src/hotspot/share/oops/instanceRefKlass.cpp b/src/hotspot/share/oops/instanceRefKlass.cpp index b8de138d59e..4b30a8edfe6 100644 --- a/src/hotspot/share/oops/instanceRefKlass.cpp +++ b/src/hotspot/share/oops/instanceRefKlass.cpp @@ -79,7 +79,7 @@ void InstanceRefKlass::update_nonstatic_oop_maps(Klass* k) { void InstanceRefKlass::oop_verify_on(oop obj, outputStream* st) { InstanceKlass::oop_verify_on(obj, st); // Verify referent field - oop referent = java_lang_ref_Reference::referent(obj); + oop referent = java_lang_ref_Reference::unknown_referent_no_keepalive(obj); if (referent != NULL) { guarantee(oopDesc::is_oop(referent), "referent field heap failed"); } diff --git a/src/hotspot/share/oops/methodData.cpp b/src/hotspot/share/oops/methodData.cpp index ce6113bd3a1..273e70ed63f 100644 --- a/src/hotspot/share/oops/methodData.cpp +++ b/src/hotspot/share/oops/methodData.cpp @@ -1135,6 +1135,44 @@ ProfileData* MethodData::data_at(int data_index) const { return data_layout->data_in(); } +int DataLayout::cell_count() { + switch (tag()) { + case DataLayout::no_tag: + default: + ShouldNotReachHere(); + return 0; + case DataLayout::bit_data_tag: + return BitData::static_cell_count(); + case DataLayout::counter_data_tag: + return CounterData::static_cell_count(); + case DataLayout::jump_data_tag: + return JumpData::static_cell_count(); + case DataLayout::receiver_type_data_tag: + return ReceiverTypeData::static_cell_count(); + case DataLayout::virtual_call_data_tag: + return VirtualCallData::static_cell_count(); + case DataLayout::ret_data_tag: + return RetData::static_cell_count(); + case DataLayout::branch_data_tag: + return BranchData::static_cell_count(); + case DataLayout::multi_branch_data_tag: + return ((new MultiBranchData(this))->cell_count()); + case DataLayout::arg_info_data_tag: + return ((new ArgInfoData(this))->cell_count()); + case DataLayout::call_type_data_tag: + return ((new CallTypeData(this))->cell_count()); + case DataLayout::virtual_call_type_data_tag: + return ((new VirtualCallTypeData(this))->cell_count()); + case DataLayout::parameters_type_data_tag: + return ((new ParametersTypeData(this))->cell_count()); + case DataLayout::speculative_trap_data_tag: + return SpeculativeTrapData::static_cell_count(); + case DataLayout::array_load_store_data_tag: + return ((new ArrayLoadStoreData(this))->cell_count()); + case DataLayout::acmp_data_tag: + return ((new ACmpData(this))->cell_count()); + } +} ProfileData* DataLayout::data_in() { switch (tag()) { case DataLayout::no_tag: @@ -1182,6 +1220,16 @@ ProfileData* MethodData::next_data(ProfileData* current) const { return next; } +DataLayout* MethodData::next_data_layout(DataLayout* current) const { + int current_index = dp_to_di((address)current); + int next_index = current_index + current->size_in_bytes(); + if (out_of_bounds(next_index)) { + return NULL; + } + DataLayout* next = data_layout_at(next_index); + return next; +} + // Give each of the data entries a chance to perform specific // data initialization. void MethodData::post_initialize(BytecodeStream* stream) { @@ -1354,13 +1402,13 @@ bool MethodData::is_mature() const { // Translate a bci to its corresponding data index (di). address MethodData::bci_to_dp(int bci) { ResourceMark rm; - ProfileData* data = data_before(bci); - ProfileData* prev = NULL; - for ( ; is_valid(data); data = next_data(data)) { + DataLayout* data = data_layout_before(bci); + DataLayout* prev = NULL; + for ( ; is_valid(data); data = next_data_layout(data)) { if (data->bci() >= bci) { - if (data->bci() == bci) set_hint_di(dp_to_di(data->dp())); - else if (prev != NULL) set_hint_di(dp_to_di(prev->dp())); - return data->dp(); + if (data->bci() == bci) set_hint_di(dp_to_di((address)data)); + else if (prev != NULL) set_hint_di(dp_to_di((address)prev)); + return (address)data; } prev = data; } @@ -1369,11 +1417,11 @@ address MethodData::bci_to_dp(int bci) { // Translate a bci to its corresponding data, or NULL. ProfileData* MethodData::bci_to_data(int bci) { - ProfileData* data = data_before(bci); - for ( ; is_valid(data); data = next_data(data)) { + DataLayout* data = data_layout_before(bci); + for ( ; is_valid(data); data = next_data_layout(data)) { if (data->bci() == bci) { - set_hint_di(dp_to_di(data->dp())); - return data; + set_hint_di(dp_to_di((address)data)); + return data->data_in(); } else if (data->bci() > bci) { break; } @@ -1826,27 +1874,7 @@ void MethodData::clean_method_data(bool always_clean) { // methods out of MethodData for all methods. void MethodData::clean_weak_method_links() { ResourceMark rm; - for (ProfileData* data = first_data(); - is_valid(data); - data = next_data(data)) { - data->clean_weak_method_links(); - } - CleanExtraDataMethodClosure cl; clean_extra_data(&cl); verify_extra_data_clean(&cl); } - -#ifdef ASSERT -void MethodData::verify_clean_weak_method_links() { - ResourceMark rm; - for (ProfileData* data = first_data(); - is_valid(data); - data = next_data(data)) { - data->verify_clean_weak_method_links(); - } - - CleanExtraDataMethodClosure cl; - verify_extra_data_clean(&cl); -} -#endif // ASSERT diff --git a/src/hotspot/share/oops/methodData.hpp b/src/hotspot/share/oops/methodData.hpp index 0f0d97927cc..22922a6084c 100644 --- a/src/hotspot/share/oops/methodData.hpp +++ b/src/hotspot/share/oops/methodData.hpp @@ -238,12 +238,15 @@ class DataLayout { ProfileData* data_in(); + int size_in_bytes() { + int cells = cell_count(); + assert(cells >= 0, "invalid number of cells"); + return DataLayout::compute_size_in_bytes(cells); + } + int cell_count(); + // GC support void clean_weak_klass_links(bool always_clean); - - // Redefinition support - void clean_weak_method_links(); - DEBUG_ONLY(void verify_clean_weak_method_links();) }; @@ -469,10 +472,6 @@ class ProfileData : public ResourceObj { // GC support virtual void clean_weak_klass_links(bool always_clean) {} - // Redefinition support - virtual void clean_weak_method_links() {} - DEBUG_ONLY(virtual void verify_clean_weak_method_links() {}) - // CI translation: ProfileData can represent both MethodDataOop data // as well as CIMethodData data. This function is provided for translating // an oop in a ProfileData to the ci equivalent. Generally speaking, @@ -2222,14 +2221,15 @@ class MethodData : public Metadata { assert(!out_of_bounds(di), "hint_di out of bounds"); _hint_di = di; } - ProfileData* data_before(int bci) { + + DataLayout* data_layout_before(int bci) { // avoid SEGV on this edge case if (data_size() == 0) return NULL; - int hint = hint_di(); - if (data_layout_at(hint)->bci() <= bci) - return data_at(hint); - return first_data(); + DataLayout* layout = data_layout_at(hint_di()); + if (layout->bci() <= bci) + return layout; + return data_layout_at(first_di()); } // What is the index of the first data entry? @@ -2412,7 +2412,9 @@ class MethodData : public Metadata { // Walk through the data in order. ProfileData* first_data() const { return data_at(first_di()); } ProfileData* next_data(ProfileData* current) const; + DataLayout* next_data_layout(DataLayout* current) const; bool is_valid(ProfileData* current) const { return current != NULL; } + bool is_valid(DataLayout* current) const { return current != NULL; } // Convert a dp (data pointer) to a di (data index). int dp_to_di(address dp) const { @@ -2576,7 +2578,6 @@ class MethodData : public Metadata { void clean_method_data(bool always_clean); void clean_weak_method_links(); - DEBUG_ONLY(void verify_clean_weak_method_links();) Mutex* extra_data_lock() { return &_extra_data_lock; } }; diff --git a/src/hotspot/share/opto/addnode.cpp b/src/hotspot/share/opto/addnode.cpp index b1049350aca..aaf65e22d7b 100644 --- a/src/hotspot/share/opto/addnode.cpp +++ b/src/hotspot/share/opto/addnode.cpp @@ -328,10 +328,9 @@ Node *AddINode::Ideal(PhaseGVN *phase, bool can_reshape) { //------------------------------Identity--------------------------------------- // Fold (x-y)+y OR y+(x-y) into x Node* AddINode::Identity(PhaseGVN* phase) { - if( in(1)->Opcode() == Op_SubI && phase->eqv(in(1)->in(2),in(2)) ) { + if (in(1)->Opcode() == Op_SubI && in(1)->in(2) == in(2)) { return in(1)->in(1); - } - else if( in(2)->Opcode() == Op_SubI && phase->eqv(in(2)->in(2),in(1)) ) { + } else if (in(2)->Opcode() == Op_SubI && in(2)->in(2) == in(1)) { return in(2)->in(1); } return AddNode::Identity(phase); @@ -445,10 +444,9 @@ Node *AddLNode::Ideal(PhaseGVN *phase, bool can_reshape) { //------------------------------Identity--------------------------------------- // Fold (x-y)+y OR y+(x-y) into x Node* AddLNode::Identity(PhaseGVN* phase) { - if( in(1)->Opcode() == Op_SubL && phase->eqv(in(1)->in(2),in(2)) ) { + if (in(1)->Opcode() == Op_SubL && in(1)->in(2) == in(2)) { return in(1)->in(1); - } - else if( in(2)->Opcode() == Op_SubL && phase->eqv(in(2)->in(2),in(1)) ) { + } else if (in(2)->Opcode() == Op_SubL && in(2)->in(2) == in(1)) { return in(2)->in(1); } return AddNode::Identity(phase); @@ -748,7 +746,7 @@ uint AddPNode::match_edge(uint idx) const { //------------------------------Identity--------------------------------------- Node* OrINode::Identity(PhaseGVN* phase) { // x | x => x - if (phase->eqv(in(1), in(2))) { + if (in(1) == in(2)) { return in(1); } @@ -835,7 +833,7 @@ const Type *OrINode::add_ring( const Type *t0, const Type *t1 ) const { //------------------------------Identity--------------------------------------- Node* OrLNode::Identity(PhaseGVN* phase) { // x | x => x - if (phase->eqv(in(1), in(2))) { + if (in(1) == in(2)) { return in(1); } @@ -1090,7 +1088,7 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) { // Transform MIN2(x + c0, MIN2(x + c1, z)) into MIN2(x + MIN2(c0, c1), z) // if x == y and the additions can't overflow. - if (phase->eqv(x,y) && tx != NULL && + if (x == y && tx != NULL && !can_overflow(tx, x_off) && !can_overflow(tx, y_off)) { return new MinINode(phase->transform(new AddINode(x, phase->intcon(MIN2(x_off, y_off)))), r->in(2)); @@ -1098,7 +1096,7 @@ Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) { } else { // Transform MIN2(x + c0, y + c1) into x + MIN2(c0, c1) // if x == y and the additions can't overflow. - if (phase->eqv(x,y) && tx != NULL && + if (x == y && tx != NULL && !can_overflow(tx, x_off) && !can_overflow(tx, y_off)) { return new AddINode(x,phase->intcon(MIN2(x_off,y_off))); diff --git a/src/hotspot/share/opto/callnode.cpp b/src/hotspot/share/opto/callnode.cpp index 4e30cde1458..dc57ce0a059 100644 --- a/src/hotspot/share/opto/callnode.cpp +++ b/src/hotspot/share/opto/callnode.cpp @@ -1430,8 +1430,12 @@ Node* SafePointNode::Identity(PhaseGVN* phase) { //------------------------------Value------------------------------------------ const Type* SafePointNode::Value(PhaseGVN* phase) const { - if( phase->type(in(0)) == Type::TOP ) return Type::TOP; - if( phase->eqv( in(0), this ) ) return Type::TOP; // Dead infinite loop + if (phase->type(in(0)) == Type::TOP) { + return Type::TOP; + } + if (in(0) == this) { + return Type::TOP; // Dead infinite loop + } return Type::CONTROL; } diff --git a/src/hotspot/share/opto/callnode.hpp b/src/hotspot/share/opto/callnode.hpp index 077715fe985..f48c058c124 100644 --- a/src/hotspot/share/opto/callnode.hpp +++ b/src/hotspot/share/opto/callnode.hpp @@ -749,25 +749,17 @@ class CallStaticJavaNode : public CallJavaNode { init_flags(Flag_is_macro); C->add_macro_node(this); } - - _is_scalar_replaceable = false; - _is_non_escaping = false; } + CallStaticJavaNode(const TypeFunc* tf, address addr, const char* name, int bci, const TypePtr* adr_type) : CallJavaNode(tf, addr, NULL, bci) { init_class_id(Class_CallStaticJava); // This node calls a runtime stub, which often has narrow memory effects. _adr_type = adr_type; - _is_scalar_replaceable = false; - _is_non_escaping = false; _name = name; } - // Result of Escape Analysis - bool _is_scalar_replaceable; - bool _is_non_escaping; - // If this is an uncommon trap, return the request code, else zero. int uncommon_trap_request() const; static int extract_uncommon_trap_request(const Node* call); diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp index c0be2fb0d93..c40ff774fed 100644 --- a/src/hotspot/share/opto/cfgnode.cpp +++ b/src/hotspot/share/opto/cfgnode.cpp @@ -345,7 +345,7 @@ bool RegionNode::is_possible_unsafe_loop(const PhaseGVN* phase) const { Node* n = raw_out(i); if (n != NULL && n->is_Phi()) { PhiNode* phi = n->as_Phi(); - assert(phase->eqv(phi->in(0), this), "sanity check phi"); + assert(phi->in(0) == this, "sanity check phi"); if (phi->outcnt() == 0) { continue; // Safe case - no loops } @@ -384,7 +384,7 @@ bool RegionNode::is_unreachable_from_root(const PhaseGVN* phase) const { for (uint i = 0; i < max; i++) { Node* m = n->raw_out(i); if (m != NULL && m->is_CFG()) { - if (phase->eqv(m, this)) { + if (m == this) { return false; // We reached the Region node - it is not dead. } if (!visited.test_set(m->_idx)) @@ -575,7 +575,7 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) { for (j = outs(); has_out(j); j++) { Node *n = out(j); if( n->is_Phi() ) { - assert( igvn->eqv(n->in(0), this), "" ); + assert(n->in(0) == this, ""); assert( n->req() == 2 && n->in(1) != NULL, "Only one data input expected" ); // Break dead loop data path. // Eagerly replace phis with top to avoid regionless phis. @@ -626,7 +626,7 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) { // The fallthrough case since we already checked dead loops above. parent_ctrl = in(1); assert(parent_ctrl != NULL, "Region is a copy of some non-null control"); - assert(!igvn->eqv(parent_ctrl, this), "Close dead loop"); + assert(parent_ctrl != this, "Close dead loop"); } if (!add_to_worklist) igvn->add_users_to_worklist(this); // Check for further allowed opts @@ -648,7 +648,7 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) { igvn->replace_node(n, in); } else if( n->is_Region() ) { // Update all incoming edges - assert( !igvn->eqv(n, this), "Must be removed from DefUse edges"); + assert(n != this, "Must be removed from DefUse edges"); uint uses_found = 0; for( uint k=1; k < n->req(); k++ ) { if( n->in(k) == this ) { @@ -661,12 +661,12 @@ Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) { } } else { - assert( igvn->eqv(n->in(0), this), "Expect RegionNode to be control parent"); + assert(n->in(0) == this, "Expect RegionNode to be control parent"); n->set_req(0, parent_ctrl); } #ifdef ASSERT for( uint k=0; k < n->req(); k++ ) { - assert( !igvn->eqv(n->in(k), this), "All uses of RegionNode should be gone"); + assert(n->in(k) != this, "All uses of RegionNode should be gone"); } #endif } @@ -2106,7 +2106,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) { if (can_reshape) { opt = split_flow_path(phase, this); // This optimization only modifies phi - don't need to check for dead loop. - assert(opt == NULL || phase->eqv(opt, this), "do not elide phi"); + assert(opt == NULL || opt == this, "do not elide phi"); if (opt != NULL) return opt; } @@ -2224,7 +2224,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) { if (ii->is_MergeMem()) { MergeMemNode* n = ii->as_MergeMem(); merge_width = MAX2(merge_width, n->req()); - saw_self = saw_self || phase->eqv(n->base_memory(), this); + saw_self = saw_self || (n->base_memory() == this); } else { mergemem_only = false; } diff --git a/src/hotspot/share/opto/divnode.cpp b/src/hotspot/share/opto/divnode.cpp index 3bbe88d148a..ef2b5b8d257 100644 --- a/src/hotspot/share/opto/divnode.cpp +++ b/src/hotspot/share/opto/divnode.cpp @@ -505,8 +505,9 @@ const Type* DivINode::Value(PhaseGVN* phase) const { if( t2 == Type::TOP ) return Type::TOP; // x/x == 1 since we always generate the dynamic divisor check for 0. - if( phase->eqv( in(1), in(2) ) ) + if (in(1) == in(2)) { return TypeInt::ONE; + } // Either input is BOTTOM ==> the result is the local BOTTOM const Type *bot = bottom_type(); @@ -610,8 +611,9 @@ const Type* DivLNode::Value(PhaseGVN* phase) const { if( t2 == Type::TOP ) return Type::TOP; // x/x == 1 since we always generate the dynamic divisor check for 0. - if( phase->eqv( in(1), in(2) ) ) + if (in(1) == in(2)) { return TypeLong::ONE; + } // Either input is BOTTOM ==> the result is the local BOTTOM const Type *bot = bottom_type(); @@ -685,9 +687,10 @@ const Type* DivFNode::Value(PhaseGVN* phase) const { // x/x == 1, we ignore 0/0. // Note: if t1 and t2 are zero then result is NaN (JVMS page 213) // Does not work for variables because of NaN's - if( phase->eqv( in(1), in(2) ) && t1->base() == Type::FloatCon) - if (!g_isnan(t1->getf()) && g_isfinite(t1->getf()) && t1->getf() != 0.0) // could be negative ZERO or NaN - return TypeF::ONE; + if (in(1) == in(2) && t1->base() == Type::FloatCon && + !g_isnan(t1->getf()) && g_isfinite(t1->getf()) && t1->getf() != 0.0) { // could be negative ZERO or NaN + return TypeF::ONE; + } if( t2 == TypeF::ONE ) return t1; @@ -773,9 +776,10 @@ const Type* DivDNode::Value(PhaseGVN* phase) const { // x/x == 1, we ignore 0/0. // Note: if t1 and t2 are zero then result is NaN (JVMS page 213) // Does not work for variables because of NaN's - if( phase->eqv( in(1), in(2) ) && t1->base() == Type::DoubleCon) - if (!g_isnan(t1->getd()) && g_isfinite(t1->getd()) && t1->getd() != 0.0) // could be negative ZERO or NaN - return TypeD::ONE; + if (in(1) == in(2) && t1->base() == Type::DoubleCon && + !g_isnan(t1->getd()) && g_isfinite(t1->getd()) && t1->getd() != 0.0) { // could be negative ZERO or NaN + return TypeD::ONE; + } if( t2 == TypeD::ONE ) return t1; @@ -990,7 +994,9 @@ const Type* ModINode::Value(PhaseGVN* phase) const { // 0 MOD X is 0 if( t1 == TypeInt::ZERO ) return TypeInt::ZERO; // X MOD X is 0 - if( phase->eqv( in(1), in(2) ) ) return TypeInt::ZERO; + if (in(1) == in(2)) { + return TypeInt::ZERO; + } // Either input is BOTTOM ==> the result is the local BOTTOM const Type *bot = bottom_type(); @@ -1163,7 +1169,9 @@ const Type* ModLNode::Value(PhaseGVN* phase) const { // 0 MOD X is 0 if( t1 == TypeLong::ZERO ) return TypeLong::ZERO; // X MOD X is 0 - if( phase->eqv( in(1), in(2) ) ) return TypeLong::ZERO; + if (in(1) == in(2)) { + return TypeLong::ZERO; + } // Either input is BOTTOM ==> the result is the local BOTTOM const Type *bot = bottom_type(); diff --git a/src/hotspot/share/opto/escape.cpp b/src/hotspot/share/opto/escape.cpp index 6b5e88bf448..bc0a958a3e7 100644 --- a/src/hotspot/share/opto/escape.cpp +++ b/src/hotspot/share/opto/escape.cpp @@ -256,9 +256,6 @@ bool ConnectionGraph::compute_escape() { if (n->is_Allocate()) { n->as_Allocate()->_is_non_escaping = noescape; } - if (n->is_CallStaticJava()) { - n->as_CallStaticJava()->_is_non_escaping = noescape; - } if (noescape && ptn->scalar_replaceable()) { adjust_scalar_replaceable_state(ptn); if (ptn->scalar_replaceable()) { @@ -3126,11 +3123,6 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist, // so it could be eliminated if it has no uses. alloc->as_Allocate()->_is_scalar_replaceable = true; } - if (alloc->is_CallStaticJava()) { - // Set the scalar_replaceable flag for boxing method - // so it could be eliminated if it has no uses. - alloc->as_CallStaticJava()->_is_scalar_replaceable = true; - } continue; } if (!n->is_CheckCastPP()) { // not unique CheckCastPP. @@ -3179,11 +3171,6 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist, // so it could be eliminated. alloc->as_Allocate()->_is_scalar_replaceable = true; } - if (alloc->is_CallStaticJava()) { - // Set the scalar_replaceable flag for boxing method - // so it could be eliminated. - alloc->as_CallStaticJava()->_is_scalar_replaceable = true; - } set_escape_state(ptnode_adr(n->_idx), es); // CheckCastPP escape state // in order for an object to be scalar-replaceable, it must be: // - a direct allocation (not a call returning an object) diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index 2cc48aa06bd..60714423ef0 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -1082,7 +1082,7 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const { if (st->is_Store()) { Node* st_adr = st->in(MemNode::Address); - if (!phase->eqv(st_adr, ld_adr)) { + if (st_adr != ld_adr) { // Try harder before giving up. Unify base pointers with casts (e.g., raw/non-raw pointers). intptr_t st_off = 0; Node* st_base = AddPNode::Ideal_base_and_offset(st_adr, phase, st_off); @@ -1564,7 +1564,7 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) { // Do nothing here if Identity will find a value // (to avoid infinite chain of value phis generation). - if (!phase->eqv(this, this->Identity(phase))) { + if (this != Identity(phase)) { return NULL; } @@ -2821,7 +2821,7 @@ Node* StoreNode::Identity(PhaseGVN* phase) { // Steps (a), (b): Walk past independent stores to find an exact match. if (prev_mem != NULL) { Node* prev_val = can_see_stored_value(prev_mem, phase); - if (prev_val != NULL && phase->eqv(prev_val, val)) { + if (prev_val != NULL && prev_val == val) { // prev_val and val might differ by a cast; it would be good // to keep the more informative of the two. if (phase->type(val)->is_zero_type()) { diff --git a/src/hotspot/share/opto/movenode.cpp b/src/hotspot/share/opto/movenode.cpp index f5a001d6648..f9b887c3173 100644 --- a/src/hotspot/share/opto/movenode.cpp +++ b/src/hotspot/share/opto/movenode.cpp @@ -78,9 +78,9 @@ Node *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { if( in(0) && remove_dead_region(phase, can_reshape) ) return this; // Don't bother trying to transform a dead node if( in(0) && in(0)->is_top() ) return NULL; - assert( !phase->eqv(in(Condition), this) && - !phase->eqv(in(IfFalse), this) && - !phase->eqv(in(IfTrue), this), "dead loop in CMoveNode::Ideal" ); + assert(in(Condition) != this && + in(IfFalse) != this && + in(IfTrue) != this, "dead loop in CMoveNode::Ideal" ); if( phase->type(in(Condition)) == Type::TOP ) return NULL; // return NULL when Condition is dead @@ -98,11 +98,9 @@ Node *CMoveNode::Ideal(PhaseGVN *phase, bool can_reshape) { // Helper function to check for CMOVE identity. Shared with PhiNode::Identity Node *CMoveNode::is_cmove_id( PhaseTransform *phase, Node *cmp, Node *t, Node *f, BoolNode *b ) { // Check for Cmp'ing and CMove'ing same values - if( (phase->eqv(cmp->in(1),f) && - phase->eqv(cmp->in(2),t)) || - // Swapped Cmp is OK - (phase->eqv(cmp->in(2),f) && - phase->eqv(cmp->in(1),t)) ) { + if ((cmp->in(1) == f && cmp->in(2) == t) || + // Swapped Cmp is OK + (cmp->in(2) == f && cmp->in(1) == t)) { // Give up this identity check for floating points because it may choose incorrect // value around 0.0 and -0.0 if ( cmp->Opcode()==Op_CmpF || cmp->Opcode()==Op_CmpD ) @@ -122,12 +120,16 @@ Node *CMoveNode::is_cmove_id( PhaseTransform *phase, Node *cmp, Node *t, Node *f // Conditional-move is an identity if both inputs are the same, or the test // true or false. Node* CMoveNode::Identity(PhaseGVN* phase) { - if( phase->eqv(in(IfFalse),in(IfTrue)) ) // C-moving identical inputs? - return in(IfFalse); // Then it doesn't matter - if( phase->type(in(Condition)) == TypeInt::ZERO ) - return in(IfFalse); // Always pick left(false) input - if( phase->type(in(Condition)) == TypeInt::ONE ) - return in(IfTrue); // Always pick right(true) input + // C-moving identical inputs? + if (in(IfFalse) == in(IfTrue)) { + return in(IfFalse); // Then it doesn't matter + } + if (phase->type(in(Condition)) == TypeInt::ZERO) { + return in(IfFalse); // Always pick left(false) input + } + if (phase->type(in(Condition)) == TypeInt::ONE) { + return in(IfTrue); // Always pick right(true) input + } // Check for CMove'ing a constant after comparing against the constant. // Happens all the time now, since if we compare equality vs a constant in diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp index 4730ba50df8..f54d46098c7 100644 --- a/src/hotspot/share/opto/mulnode.cpp +++ b/src/hotspot/share/opto/mulnode.cpp @@ -87,12 +87,13 @@ Node *MulNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node *mul1 = in(1); #ifdef ASSERT // Check for dead loop - int op1 = mul1->Opcode(); - if( phase->eqv( mul1, this ) || phase->eqv( in(2), this ) || - ( ( op1 == mul_opcode() || op1 == add_opcode() ) && - ( phase->eqv( mul1->in(1), this ) || phase->eqv( mul1->in(2), this ) || - phase->eqv( mul1->in(1), mul1 ) || phase->eqv( mul1->in(2), mul1 ) ) ) ) + int op1 = mul1->Opcode(); + if ((mul1 == this) || (in(2) == this) || + ((op1 == mul_opcode() || op1 == add_opcode()) && + ((mul1->in(1) == this) || (mul1->in(2) == this) || + (mul1->in(1) == mul1) || (mul1->in(2) == mul1)))) { assert(false, "dead loop in MulNode::Ideal"); + } #endif if( mul1->Opcode() == mul_opcode() ) { // Left input is a multiply? @@ -448,7 +449,9 @@ const Type *AndINode::mul_ring( const Type *t0, const Type *t1 ) const { Node* AndINode::Identity(PhaseGVN* phase) { // x & x => x - if (phase->eqv(in(1), in(2))) return in(1); + if (in(1) == in(2)) { + return in(1); + } Node* in1 = in(1); uint op = in1->Opcode(); @@ -570,7 +573,9 @@ const Type *AndLNode::mul_ring( const Type *t0, const Type *t1 ) const { Node* AndLNode::Identity(PhaseGVN* phase) { // x & x => x - if (phase->eqv(in(1), in(2))) return in(1); + if (in(1) == in(2)) { + return in(1); + } Node *usr = in(1); const TypeLong *t2 = phase->type( in(2) )->isa_long(); diff --git a/src/hotspot/share/opto/phaseX.hpp b/src/hotspot/share/opto/phaseX.hpp index 80aacb75d34..fc4f6fe883f 100644 --- a/src/hotspot/share/opto/phaseX.hpp +++ b/src/hotspot/share/opto/phaseX.hpp @@ -282,11 +282,6 @@ class PhaseTransform : public Phase { // in a faster or cheaper fashion. virtual Node *transform( Node *n ) = 0; - // Return whether two Nodes are equivalent. - // Must not be recursive, since the recursive version is built from this. - // For pessimistic optimizations this is simply pointer equivalence. - bool eqv(const Node* n1, const Node* n2) const { return n1 == n2; } - // For pessimistic passes, the return type must monotonically narrow. // For optimistic passes, the return type must monotonically widen. // It is possible to get into a "death march" in either type of pass, diff --git a/src/hotspot/share/opto/subnode.cpp b/src/hotspot/share/opto/subnode.cpp index f0e29c2239c..94380922ba3 100644 --- a/src/hotspot/share/opto/subnode.cpp +++ b/src/hotspot/share/opto/subnode.cpp @@ -61,20 +61,22 @@ Node* SubNode::Identity(PhaseGVN* phase) { } // Convert "(X+Y) - Y" into X and "(X+Y) - X" into Y - if( in(1)->Opcode() == Op_AddI ) { - if( phase->eqv(in(1)->in(2),in(2)) ) + if (in(1)->Opcode() == Op_AddI) { + if (in(1)->in(2) == in(2)) { return in(1)->in(1); - if (phase->eqv(in(1)->in(1),in(2))) + } + if (in(1)->in(1) == in(2)) { return in(1)->in(2); + } // Also catch: "(X + Opaque2(Y)) - Y". In this case, 'Y' is a loop-varying // trip counter and X is likely to be loop-invariant (that's how O2 Nodes // are originally used, although the optimizer sometimes jiggers things). // This folding through an O2 removes a loop-exit use of a loop-varying // value and generally lowers register pressure in and around the loop. - if( in(1)->in(2)->Opcode() == Op_Opaque2 && - phase->eqv(in(1)->in(2)->in(1),in(2)) ) + if (in(1)->in(2)->Opcode() == Op_Opaque2 && in(1)->in(2)->in(1) == in(2)) { return in(1)->in(1); + } } return ( phase->type( in(2) )->higher_equal( zero ) ) ? in(1) : this; @@ -154,11 +156,12 @@ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){ #ifdef ASSERT // Check for dead loop - if( phase->eqv( in1, this ) || phase->eqv( in2, this ) || - ( ( op1 == Op_AddI || op1 == Op_SubI ) && - ( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) || - phase->eqv( in1->in(1), in1 ) || phase->eqv( in1->in(2), in1 ) ) ) ) + if ((in1 == this) || (in2 == this) || + ((op1 == Op_AddI || op1 == Op_SubI) && + ((in1->in(1) == this) || (in1->in(2) == this) || + (in1->in(1) == in1) || (in1->in(2) == in1)))) { assert(false, "dead loop in SubINode::Ideal"); + } #endif const Type *t2 = phase->type( in2 ); @@ -200,24 +203,25 @@ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){ #ifdef ASSERT // Check for dead loop - if( ( op2 == Op_AddI || op2 == Op_SubI ) && - ( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) || - phase->eqv( in2->in(1), in2 ) || phase->eqv( in2->in(2), in2 ) ) ) + if ((op2 == Op_AddI || op2 == Op_SubI) && + ((in2->in(1) == this) || (in2->in(2) == this) || + (in2->in(1) == in2) || (in2->in(2) == in2))) { assert(false, "dead loop in SubINode::Ideal"); + } #endif // Convert "x - (x+y)" into "-y" - if( op2 == Op_AddI && - phase->eqv( in1, in2->in(1) ) ) - return new SubINode( phase->intcon(0),in2->in(2)); + if (op2 == Op_AddI && in1 == in2->in(1)) { + return new SubINode(phase->intcon(0), in2->in(2)); + } // Convert "(x-y) - x" into "-y" - if( op1 == Op_SubI && - phase->eqv( in1->in(1), in2 ) ) - return new SubINode( phase->intcon(0),in1->in(2)); + if (op1 == Op_SubI && in1->in(1) == in2) { + return new SubINode(phase->intcon(0), in1->in(2)); + } // Convert "x - (y+x)" into "-y" - if( op2 == Op_AddI && - phase->eqv( in1, in2->in(2) ) ) - return new SubINode( phase->intcon(0),in2->in(1)); + if (op2 == Op_AddI && in1 == in2->in(2)) { + return new SubINode(phase->intcon(0), in2->in(1)); + } // Convert "0 - (x-y)" into "y-x" if( t1 == TypeInt::ZERO && op2 == Op_SubI ) @@ -296,11 +300,12 @@ Node *SubLNode::Ideal(PhaseGVN *phase, bool can_reshape) { #ifdef ASSERT // Check for dead loop - if( phase->eqv( in1, this ) || phase->eqv( in2, this ) || - ( ( op1 == Op_AddL || op1 == Op_SubL ) && - ( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) || - phase->eqv( in1->in(1), in1 ) || phase->eqv( in1->in(2), in1 ) ) ) ) + if ((in1 == this) || (in2 == this) || + ((op1 == Op_AddL || op1 == Op_SubL) && + ((in1->in(1) == this) || (in1->in(2) == this) || + (in1->in(1) == in1) || (in1->in(2) == in1)))) { assert(false, "dead loop in SubLNode::Ideal"); + } #endif if( phase->type( in2 ) == Type::TOP ) return NULL; @@ -340,20 +345,21 @@ Node *SubLNode::Ideal(PhaseGVN *phase, bool can_reshape) { #ifdef ASSERT // Check for dead loop - if( ( op2 == Op_AddL || op2 == Op_SubL ) && - ( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) || - phase->eqv( in2->in(1), in2 ) || phase->eqv( in2->in(2), in2 ) ) ) + if ((op2 == Op_AddL || op2 == Op_SubL) && + ((in2->in(1) == this) || (in2->in(2) == this) || + (in2->in(1) == in2) || (in2->in(2) == in2))) { assert(false, "dead loop in SubLNode::Ideal"); + } #endif // Convert "x - (x+y)" into "-y" - if( op2 == Op_AddL && - phase->eqv( in1, in2->in(1) ) ) - return new SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2)); + if (op2 == Op_AddL && in1 == in2->in(1)) { + return new SubLNode(phase->makecon(TypeLong::ZERO), in2->in(2)); + } // Convert "x - (y+x)" into "-y" - if( op2 == Op_AddL && - phase->eqv( in1, in2->in(2) ) ) - return new SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1)); + if (op2 == Op_AddL && in1 == in2->in(2)) { + return new SubLNode(phase->makecon(TypeLong::ZERO), in2->in(1)); + } // Convert "0 - (x-y)" into "y-x" if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL ) @@ -421,8 +427,8 @@ const Type* SubFPNode::Value(PhaseGVN* phase) const { // if both operands are infinity of same sign, the result is NaN; do // not replace with zero - if( (t1->is_finite() && t2->is_finite()) ) { - if( phase->eqv(in1, in2) ) return add_id(); + if (t1->is_finite() && t2->is_finite() && in1 == in2) { + return add_id(); } // Either input is BOTTOM ==> the result is the local BOTTOM @@ -445,11 +451,10 @@ Node *SubFNode::Ideal(PhaseGVN *phase, bool can_reshape) { } // Not associative because of boundary conditions (infinity) - if( IdealizedNumerics && !phase->C->method()->is_strict() ) { + if (IdealizedNumerics && !phase->C->method()->is_strict() && + in(2)->is_Add() && in(1) == in(2)->in(1)) { // Convert "x - (x+y)" into "-y" - if( in(2)->is_Add() && - phase->eqv(in(1),in(2)->in(1) ) ) - return new SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2)); + return new SubFNode(phase->makecon(TypeF::ZERO), in(2)->in(2)); } // Cannot replace 0.0-X with -X because a 'fsub' bytecode computes @@ -488,11 +493,10 @@ Node *SubDNode::Ideal(PhaseGVN *phase, bool can_reshape){ } // Not associative because of boundary conditions (infinity) - if( IdealizedNumerics && !phase->C->method()->is_strict() ) { + if (IdealizedNumerics && !phase->C->method()->is_strict() && + in(2)->is_Add() && in(1) == in(2)->in(1)) { // Convert "x - (x+y)" into "-y" - if( in(2)->is_Add() && - phase->eqv(in(1),in(2)->in(1) ) ) - return new SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2)); + return new SubDNode(phase->makecon(TypeD::ZERO), in(2)->in(2)); } // Cannot replace 0.0-X with -X because a 'dsub' bytecode computes diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp index 9f86869371b..d462bea17f1 100644 --- a/src/hotspot/share/opto/type.cpp +++ b/src/hotspot/share/opto/type.cpp @@ -3289,21 +3289,22 @@ TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, Offse } else if (klass() == ciEnv::current()->Class_klass() && this->offset() >= InstanceMirrorKlass::offset_of_static_fields()) { // Static fields - assert(o != NULL, "must be constant"); - ciInstanceKlass* ik = o->as_instance()->java_lang_Class_klass()->as_instance_klass(); - BasicType basic_elem_type; - if (ik->is_inlinetype() && this->offset() == ik->as_inline_klass()->default_value_offset()) { - // Special hidden field that contains the oop of the default inline type - basic_elem_type = T_INLINE_TYPE; - _is_ptr_to_narrowoop = UseCompressedOops; - } else { - ciField* field = ik->get_field_by_offset(this->offset(), true); - if (field != NULL) { - BasicType basic_elem_type = field->layout_type(); - _is_ptr_to_narrowoop = UseCompressedOops && is_reference_type(basic_elem_type); + ciField* field = NULL; + if (const_oop() != NULL) { + ciInstanceKlass* k = const_oop()->as_instance()->java_lang_Class_klass()->as_instance_klass(); + if (k->is_inlinetype() && this->offset() == k->as_inline_klass()->default_value_offset()) { + // Special hidden field that contains the oop of the default inline type + // basic_elem_type = T_INLINE_TYPE; + _is_ptr_to_narrowoop = UseCompressedOops; } else { - // unsafe access - _is_ptr_to_narrowoop = UseCompressedOops; + field = k->get_field_by_offset(this->offset(), true); + if (field != NULL) { + BasicType basic_elem_type = field->layout_type(); + _is_ptr_to_narrowoop = UseCompressedOops && is_reference_type(basic_elem_type); + } else { + // unsafe access + _is_ptr_to_narrowoop = UseCompressedOops; + } } } } else { diff --git a/src/hotspot/share/opto/vectorIntrinsics.cpp b/src/hotspot/share/opto/vectorIntrinsics.cpp index abf11d4a48b..d06c8348907 100644 --- a/src/hotspot/share/opto/vectorIntrinsics.cpp +++ b/src/hotspot/share/opto/vectorIntrinsics.cpp @@ -100,7 +100,10 @@ static bool is_vector_shuffle(ciKlass* klass) { } static bool is_klass_initialized(const TypeInstPtr* vec_klass) { - assert(vec_klass->const_oop()->as_instance()->java_lang_Class_klass(), "klass instance expected"); + if (vec_klass->const_oop() == NULL) { + return false; // uninitialized or some kind of unsafe access + } + assert(vec_klass->const_oop()->as_instance()->java_lang_Class_klass() != NULL, "klass instance expected"); ciInstanceKlass* klass = vec_klass->const_oop()->as_instance()->java_lang_Class_klass()->as_instance_klass(); return klass->is_initialized(); } diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 43176eedd90..5f1d5ca5efa 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "jvm.h" #include "classfile/classFileStream.hpp" +#include "classfile/classListParser.hpp" #include "classfile/classListWriter.hpp" #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.hpp" @@ -32,7 +33,6 @@ #include "classfile/classLoadInfo.hpp" #include "classfile/javaAssertions.hpp" #include "classfile/javaClasses.inline.hpp" -#include "classfile/lambdaFormInvokers.hpp" #include "classfile/moduleEntry.hpp" #include "classfile/modules.hpp" #include "classfile/packageEntry.hpp" @@ -3510,6 +3510,24 @@ JVM_ENTRY(void, JVM_WaitForReferencePendingList(JNIEnv* env)) } JVM_END +JVM_ENTRY(jboolean, JVM_ReferenceRefersTo(JNIEnv* env, jobject ref, jobject o)) + JVMWrapper("JVM_ReferenceRefersTo"); + oop ref_oop = JNIHandles::resolve_non_null(ref); + oop referent = java_lang_ref_Reference::weak_referent_no_keepalive(ref_oop); + return referent == JNIHandles::resolve(o); +JVM_END + + +// java.lang.ref.PhantomReference ////////////////////////////////////////////////// + + +JVM_ENTRY(jboolean, JVM_PhantomReferenceRefersTo(JNIEnv* env, jobject ref, jobject o)) + JVMWrapper("JVM_PhantomReferenceRefersTo"); + oop ref_oop = JNIHandles::resolve_non_null(ref); + oop referent = java_lang_ref_Reference::phantom_referent_no_keepalive(ref_oop); + return referent == JNIHandles::resolve(o); +JVM_END + // ObjectInputStream /////////////////////////////////////////////////////////////// @@ -3954,7 +3972,7 @@ JVM_ENTRY(void, JVM_LogLambdaFormInvoker(JNIEnv *env, jstring line)) Handle h_line (THREAD, JNIHandles::resolve_non_null(line)); char* c_line = java_lang_String::as_utf8_string(h_line()); ClassListWriter w; - w.stream()->print_cr("%s %s", LambdaFormInvokers::lambda_form_invoker_tag(), c_line); + w.stream()->print_cr("%s %s", LAMBDA_FORM_TAG, c_line); } #endif // INCLUDE_CDS JVM_END diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index 7760b41c9aa..8b932030a3d 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -1653,17 +1653,9 @@ JvmtiEnv::PopFrame(JavaThread* java_thread) { // Eagerly reallocate scalar replaced objects. JavaThread* current_thread = JavaThread::current(); EscapeBarrier eb(true, current_thread, java_thread); - if (eb.barrier_active()) { - if (java_thread->frames_to_pop_failed_realloc() > 0) { - // VM is in the process of popping the top frame because it has scalar replaced objects which - // could not be reallocated on the heap. - // Return JVMTI_ERROR_OUT_OF_MEMORY to avoid interfering with the VM. - return JVMTI_ERROR_OUT_OF_MEMORY; - } - if (!eb.deoptimize_objects(1)) { - // Reallocation of scalar replaced objects failed -> return with error - return JVMTI_ERROR_OUT_OF_MEMORY; - } + if (!eb.deoptimize_objects(1)) { + // Reallocation of scalar replaced objects failed -> return with error + return JVMTI_ERROR_OUT_OF_MEMORY; } MutexLocker mu(JvmtiThreadState_lock); diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp index b0d96f94aba..2065aa68f8c 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp @@ -1378,17 +1378,9 @@ JvmtiEnvBase::force_early_return(JavaThread* java_thread, jvalue value, TosState // Eagerly reallocate scalar replaced objects. JavaThread* current_thread = JavaThread::current(); EscapeBarrier eb(true, current_thread, java_thread); - if (eb.barrier_active()) { - if (java_thread->frames_to_pop_failed_realloc() > 0) { - // VM is in the process of popping the top frame because it has scalar replaced objects - // which could not be reallocated on the heap. - // Return JVMTI_ERROR_OUT_OF_MEMORY to avoid interfering with the VM. - return JVMTI_ERROR_OUT_OF_MEMORY; - } - if (!eb.deoptimize_objects(0)) { - // Reallocation of scalar replaced objects failed -> return with error - return JVMTI_ERROR_OUT_OF_MEMORY; - } + if (!eb.deoptimize_objects(0)) { + // Reallocation of scalar replaced objects failed -> return with error + return JVMTI_ERROR_OUT_OF_MEMORY; } SetForceEarlyReturn op(state, value, tos); diff --git a/src/hotspot/share/prims/jvmtiImpl.cpp b/src/hotspot/share/prims/jvmtiImpl.cpp index 7689804a995..7517827019b 100644 --- a/src/hotspot/share/prims/jvmtiImpl.cpp +++ b/src/hotspot/share/prims/jvmtiImpl.cpp @@ -630,58 +630,12 @@ static bool can_be_deoptimized(vframe* vf) { return (vf->is_compiled_frame() && vf->fr().can_be_deoptimized()); } -// Revert optimizations based on escape analysis if this is an access to a local object -bool VM_GetOrSetLocal::deoptimize_objects(javaVFrame* jvf) { -#if COMPILER2_OR_JVMCI - assert(_type == T_OBJECT, "EscapeBarrier should not be active if _type != T_OBJECT"); - if (_depth < _thread->frames_to_pop_failed_realloc()) { - // cannot access frame with failed reallocations +bool VM_GetOrSetLocal::doit_prologue() { + if (!_eb.deoptimize_objects(_depth, _depth)) { + // The target frame is affected by a reallocation failure. _result = JVMTI_ERROR_OUT_OF_MEMORY; return false; } - if (can_be_deoptimized(jvf)) { - compiledVFrame* cf = compiledVFrame::cast(jvf); - if (cf->has_ea_local_in_scope() && !_eb.deoptimize_objects(cf->fr().id())) { - // reallocation of scalar replaced objects failed because heap is exhausted - _result = JVMTI_ERROR_OUT_OF_MEMORY; - return false; - } - } - - // With this access the object could escape the thread changing its escape state from ArgEscape, - // to GlobalEscape so we must deoptimize callers which could have optimized on the escape state. - vframe* vf = jvf; - do { - // move to next physical frame - while(!vf->is_top()) { - vf = vf->sender(); - } - vf = vf->sender(); - - if (vf != NULL && vf->is_compiled_frame()) { - compiledVFrame* cvf = compiledVFrame::cast(vf); - // Deoptimize objects if arg escape is being passed down the stack. - // Note that deoptimizing the frame is not enough because objects need to be relocked - if (cvf->arg_escape() && !_eb.deoptimize_objects(cvf->fr().id())) { - // reallocation of scalar replaced objects failed because heap is exhausted - _result = JVMTI_ERROR_OUT_OF_MEMORY; - return false; - } - } - } while(vf != NULL && !vf->is_entry_frame()); -#endif // COMPILER2_OR_JVMCI - return true; -} - -bool VM_GetOrSetLocal::doit_prologue() { - if (_eb.barrier_active()) { - _jvf = get_java_vframe(); - NULL_CHECK(_jvf, false); - - if (!deoptimize_objects(_jvf)) { - return false; - } - } return true; } diff --git a/src/hotspot/share/prims/jvmtiImpl.hpp b/src/hotspot/share/prims/jvmtiImpl.hpp index 7a3a2197b68..1895f9ab8e6 100644 --- a/src/hotspot/share/prims/jvmtiImpl.hpp +++ b/src/hotspot/share/prims/jvmtiImpl.hpp @@ -334,7 +334,6 @@ class VM_GetOrSetLocal : public VM_Operation { javaVFrame* get_java_vframe(); bool check_slot_type_lvt(javaVFrame* vf); bool check_slot_type_no_lvt(javaVFrame* vf); - bool deoptimize_objects(javaVFrame* vf); public: // Constructor for non-object getter diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index ae78b6f1751..3957763388e 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -1248,7 +1248,7 @@ static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value) { const char* flag_name = env->GetStringUTFChars(name, NULL); CHECK_JNI_EXCEPTION_(env, false); JVMFlag* flag = JVMFlag::find_flag(flag_name); - JVMFlag::Error result = JVMFlagAccess::set(flag, value, JVMFlag::INTERNAL); + JVMFlag::Error result = JVMFlagAccess::set(flag, value, JVMFlagOrigin::INTERNAL); env->ReleaseStringUTFChars(name, flag_name); return (result == JVMFlag::SUCCESS); } diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 0f5bcfa06e8..3bf7c6e8228 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -877,7 +877,7 @@ void Arguments::describe_range_error(ArgsRange errcode) { } } -static bool set_bool_flag(JVMFlag* flag, bool value, JVMFlag::Flags origin) { +static bool set_bool_flag(JVMFlag* flag, bool value, JVMFlagOrigin origin) { if (JVMFlagAccess::boolAtPut(flag, &value, origin) == JVMFlag::SUCCESS) { return true; } else { @@ -885,7 +885,7 @@ static bool set_bool_flag(JVMFlag* flag, bool value, JVMFlag::Flags origin) { } } -static bool set_fp_numeric_flag(JVMFlag* flag, char* value, JVMFlag::Flags origin) { +static bool set_fp_numeric_flag(JVMFlag* flag, char* value, JVMFlagOrigin origin) { char* end; errno = 0; double v = strtod(value, &end); @@ -899,7 +899,7 @@ static bool set_fp_numeric_flag(JVMFlag* flag, char* value, JVMFlag::Flags origi return false; } -static bool set_numeric_flag(JVMFlag* flag, char* value, JVMFlag::Flags origin) { +static bool set_numeric_flag(JVMFlag* flag, char* value, JVMFlagOrigin origin) { julong v; int int_v; intx intx_v; @@ -952,14 +952,14 @@ static bool set_numeric_flag(JVMFlag* flag, char* value, JVMFlag::Flags origin) } } -static bool set_string_flag(JVMFlag* flag, const char* value, JVMFlag::Flags origin) { +static bool set_string_flag(JVMFlag* flag, const char* value, JVMFlagOrigin origin) { if (JVMFlagAccess::ccstrAtPut(flag, &value, origin) != JVMFlag::SUCCESS) return false; // Contract: JVMFlag always returns a pointer that needs freeing. FREE_C_HEAP_ARRAY(char, value); return true; } -static bool append_to_string_flag(JVMFlag* flag, const char* new_value, JVMFlag::Flags origin) { +static bool append_to_string_flag(JVMFlag* flag, const char* new_value, JVMFlagOrigin origin) { const char* old_value = ""; if (JVMFlagAccess::ccstrAt(flag, &old_value) != JVMFlag::SUCCESS) return false; size_t old_len = old_value != NULL ? strlen(old_value) : 0; @@ -1060,7 +1060,7 @@ AliasedLoggingFlag Arguments::catch_logging_aliases(const char* name, bool on){ return a; } -bool Arguments::parse_argument(const char* arg, JVMFlag::Flags origin) { +bool Arguments::parse_argument(const char* arg, JVMFlagOrigin origin) { // range of acceptable characters spelled out for portability reasons #define NAME_RANGE "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]" @@ -1275,7 +1275,7 @@ void Arguments::print_jvm_args_on(outputStream* st) { bool Arguments::process_argument(const char* arg, jboolean ignore_unrecognized, - JVMFlag::Flags origin) { + JVMFlagOrigin origin) { JDK_Version since = JDK_Version(); if (parse_argument(arg, origin)) { @@ -1404,7 +1404,7 @@ bool Arguments::process_settings_file(const char* file_name, bool should_exist, // this allows a way to include spaces in string-valued options token[pos] = '\0'; logOption(token); - result &= process_argument(token, ignore_unrecognized, JVMFlag::CONFIG_FILE); + result &= process_argument(token, ignore_unrecognized, JVMFlagOrigin::CONFIG_FILE); build_jvm_flags(token); pos = 0; in_white_space = true; @@ -1422,7 +1422,7 @@ bool Arguments::process_settings_file(const char* file_name, bool should_exist, } if (pos > 0) { token[pos] = '\0'; - result &= process_argument(token, ignore_unrecognized, JVMFlag::CONFIG_FILE); + result &= process_argument(token, ignore_unrecognized, JVMFlagOrigin::CONFIG_FILE); build_jvm_flags(token); } fclose(stream); @@ -1659,10 +1659,6 @@ void set_object_alignment() { // Oop encoding heap max OopEncodingHeapMax = (uint64_t(max_juint) + 1) << LogMinObjAlignmentInBytes; - - if (SurvivorAlignmentInBytes == 0) { - SurvivorAlignmentInBytes = ObjectAlignmentInBytes; - } } size_t Arguments::max_heap_for_compressed_oops() { @@ -2302,27 +2298,27 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs *vm_options_args, set_mode_flags(_mixed); // Parse args structure generated from java.base vm options resource - jint result = parse_each_vm_init_arg(vm_options_args, &patch_mod_javabase, JVMFlag::JIMAGE_RESOURCE); + jint result = parse_each_vm_init_arg(vm_options_args, &patch_mod_javabase, JVMFlagOrigin::JIMAGE_RESOURCE); if (result != JNI_OK) { return result; } // Parse args structure generated from JAVA_TOOL_OPTIONS environment // variable (if present). - result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, JVMFlag::ENVIRON_VAR); + result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, JVMFlagOrigin::ENVIRON_VAR); if (result != JNI_OK) { return result; } // Parse args structure generated from the command line flags. - result = parse_each_vm_init_arg(cmd_line_args, &patch_mod_javabase, JVMFlag::COMMAND_LINE); + result = parse_each_vm_init_arg(cmd_line_args, &patch_mod_javabase, JVMFlagOrigin::COMMAND_LINE); if (result != JNI_OK) { return result; } // Parse args structure generated from the _JAVA_OPTIONS environment // variable (if present) (mimics classic VM) - result = parse_each_vm_init_arg(java_options_args, &patch_mod_javabase, JVMFlag::ENVIRON_VAR); + result = parse_each_vm_init_arg(java_options_args, &patch_mod_javabase, JVMFlagOrigin::ENVIRON_VAR); if (result != JNI_OK) { return result; } @@ -2466,7 +2462,7 @@ jint Arguments::parse_xss(const JavaVMOption* option, const char* tail, intx* ou return JNI_OK; } -jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, JVMFlag::Flags origin) { +jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, JVMFlagOrigin origin) { // For match_option to return remaining or value part of option string const char* tail; @@ -3250,6 +3246,11 @@ jint Arguments::finalize_vm_init_args(bool patch_mod_javabase) { set_mode_flags(_int); } +#ifdef ZERO + // Zero always runs in interpreted mode + set_mode_flags(_int); +#endif + // eventually fix up InitialTenuringThreshold if only MaxTenuringThreshold is set if (FLAG_IS_DEFAULT(InitialTenuringThreshold) && (InitialTenuringThreshold > MaxTenuringThreshold)) { FLAG_SET_ERGO(InitialTenuringThreshold, MaxTenuringThreshold); diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index 1a77eb3d302..eb3312dc588 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -28,11 +28,11 @@ #include "logging/logLevel.hpp" #include "logging/logTag.hpp" #include "memory/allocation.hpp" -#include "runtime/flags/jvmFlag.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" #include "runtime/perfData.hpp" #include "utilities/debug.hpp" +#include "utilities/vmEnums.hpp" // Arguments parses the command line and recognizes options @@ -408,8 +408,8 @@ class Arguments : AllStatic { static jint set_aggressive_heap_flags(); // Argument parsing - static bool parse_argument(const char* arg, JVMFlag::Flags origin); - static bool process_argument(const char* arg, jboolean ignore_unrecognized, JVMFlag::Flags origin); + static bool parse_argument(const char* arg, JVMFlagOrigin origin); + static bool process_argument(const char* arg, jboolean ignore_unrecognized, JVMFlagOrigin origin); static void process_java_launcher_argument(const char*, void*); static void process_java_compiler_argument(const char* arg); static jint parse_options_environment_variable(const char* name, ScopedVMInitArgs* vm_args); @@ -436,7 +436,7 @@ class Arguments : AllStatic { const JavaVMInitArgs *java_tool_options_args, const JavaVMInitArgs *java_options_args, const JavaVMInitArgs *cmd_line_args); - static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, JVMFlag::Flags origin); + static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, JVMFlagOrigin origin); static jint finalize_vm_init_args(bool patch_mod_javabase); static bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type); diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index 849567b69a7..e10f646944f 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -239,11 +239,6 @@ static bool eliminate_allocations(JavaThread* thread, int exec_mode, CompiledMet bool skip_internal = (compiled_method != NULL) && !compiled_method->is_compiled_by_jvmci(); Deoptimization::reassign_fields(&deoptee, &map, objects, realloc_failures, skip_internal, CHECK_AND_CLEAR_(true)); } - // Make sure the deoptee frame gets processed after a potential safepoint during - // object reallocation. This is necessary because (a) deoptee_thread can be - // different from the current thread and (b) the deoptee frame does not need to be - // the top frame. - StackWatermarkSet::finish_processing(deoptee_thread, NULL /* context */, StackWatermarkKind::gc); deoptimized_objects = true; } else { JRT_BLOCK diff --git a/src/hotspot/share/runtime/escapeBarrier.cpp b/src/hotspot/share/runtime/escapeBarrier.cpp index b6870e2209b..cc101d86b3e 100644 --- a/src/hotspot/share/runtime/escapeBarrier.cpp +++ b/src/hotspot/share/runtime/escapeBarrier.cpp @@ -33,6 +33,7 @@ #include "runtime/handles.hpp" #include "runtime/handshake.hpp" #include "runtime/interfaceSupport.inline.hpp" +#include "runtime/keepStackGCProcessed.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/registerMap.hpp" #include "runtime/stackValue.hpp" @@ -62,29 +63,37 @@ bool EscapeBarrier::objs_are_deoptimized(JavaThread* thread, intptr_t* fr_id) { return result; } -// Object references of frames up to the given depth are about to be -// accessed. Frames with optimizations based on escape state that is potentially -// changed by the accesses need to be deoptimized and the referenced objects -// need to be reallocated and relocked. Up to depth this is done for frames -// with not escaping objects in scope. For deeper frames it is done only if -// they pass not escaping objects as arguments because they potentially escape -// from callee frames within the given depth. -// The search for deeper frames is ended if an entry frame is found because -// arguments to native methods are considered to escape globally. -bool EscapeBarrier::deoptimize_objects(int depth) { - if (barrier_active() && deoptee_thread()->has_last_Java_frame()) { +// Deoptimize objects of frames of the target thread at depth >= d1 and depth <= d2. +// Deoptimize objects of caller frames if they passed references to ArgEscape objects as arguments. +// Return false in the case of a reallocation failure and true otherwise. +bool EscapeBarrier::deoptimize_objects(int d1, int d2) { + if (!barrier_active()) return true; + if (d1 < deoptee_thread()->frames_to_pop_failed_realloc()) { + // The deoptee thread has frames with reallocation failures on top of its stack. + // These frames are about to be removed. We must not interfere with that and signal failure. + return false; + } + if (deoptee_thread()->has_last_Java_frame()) { assert(calling_thread() == Thread::current(), "should be"); + KeepStackGCProcessedMark ksgcpm(deoptee_thread()); ResourceMark rm(calling_thread()); HandleMark hm(calling_thread()); RegisterMap reg_map(deoptee_thread(), false /* update_map */, false /* process_frames */); vframe* vf = deoptee_thread()->last_java_vframe(®_map); int cur_depth = 0; - while (vf != NULL && ((cur_depth <= depth) || !vf->is_entry_frame())) { + + // Skip frames at depth < d1 + while (vf != NULL && cur_depth < d1) { + cur_depth++; + vf = vf->sender(); + } + + while (vf != NULL && ((cur_depth <= d2) || !vf->is_entry_frame())) { if (vf->is_compiled_frame()) { compiledVFrame* cvf = compiledVFrame::cast(vf); // Deoptimize frame and local objects if any exist. // If cvf is deeper than depth, then we deoptimize iff local objects are passed as args. - bool should_deopt = cur_depth <= depth ? cvf->has_ea_local_in_scope() : cvf->arg_escape(); + bool should_deopt = cur_depth <= d2 ? cvf->has_ea_local_in_scope() : cvf->arg_escape(); if (should_deopt && !deoptimize_objects(cvf->fr().id())) { // reallocation of scalar replaced objects failed because heap is exhausted return false; @@ -109,7 +118,13 @@ bool EscapeBarrier::deoptimize_objects_all_threads() { if (!barrier_active()) return true; ResourceMark rm(calling_thread()); for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) { + if (jt->frames_to_pop_failed_realloc() > 0) { + // The deoptee thread jt has frames with reallocation failures on top of its stack. + // These frames are about to be removed. We must not interfere with that and signal failure. + return false; + } if (jt->has_last_Java_frame()) { + KeepStackGCProcessedMark ksgcpm(jt); RegisterMap reg_map(jt, false /* update_map */, false /* process_frames */); vframe* vf = jt->last_java_vframe(®_map); assert(jt->frame_anchor()->walkable(), @@ -297,7 +312,7 @@ static void set_objs_are_deoptimized(JavaThread* thread, intptr_t* fr_id) { // frame is replaced with interpreter frames. Returns false iff at least one // reallocation failed. bool EscapeBarrier::deoptimize_objects_internal(JavaThread* deoptee, intptr_t* fr_id) { - if (!barrier_active()) return true; + assert(barrier_active(), "should not call"); JavaThread* ct = calling_thread(); bool realloc_failures = false; @@ -307,11 +322,7 @@ bool EscapeBarrier::deoptimize_objects_internal(JavaThread* deoptee, intptr_t* f compiledVFrame* last_cvf; bool fr_is_deoptimized; do { - if (!self_deopt()) { - // Process stack of deoptee thread as we will access oops during object deoptimization. - StackWatermarkSet::start_processing(deoptee, StackWatermarkKind::gc); - } - StackFrameStream fst(deoptee, true /* update */, true /* process_frames */); + StackFrameStream fst(deoptee, true /* update */, false /* process_frames */); while (fst.current()->id() != fr_id && !fst.is_done()) { fst.next(); } diff --git a/src/hotspot/share/runtime/escapeBarrier.hpp b/src/hotspot/share/runtime/escapeBarrier.hpp index 57230cbdb25..96df2827783 100644 --- a/src/hotspot/share/runtime/escapeBarrier.hpp +++ b/src/hotspot/share/runtime/escapeBarrier.hpp @@ -61,6 +61,12 @@ class EscapeBarrier : StackObj { // Deoptimize the given frame and deoptimize objects with optimizations based on escape analysis. bool deoptimize_objects_internal(JavaThread* deoptee, intptr_t* fr_id); + // Deoptimize objects, i.e. reallocate and relock them. The target frames are deoptimized. + // The methods return false iff at least one reallocation failed. + bool deoptimize_objects(intptr_t* fr_id) { + return deoptimize_objects_internal(deoptee_thread(), fr_id); + } + public: // Revert ea based optimizations for given deoptee thread EscapeBarrier(bool barrier_active, JavaThread* calling_thread, JavaThread* deoptee_thread) @@ -89,13 +95,17 @@ class EscapeBarrier : StackObj { bool barrier_active() const { return false; } #endif // COMPILER2_OR_JVMCI - // Deoptimize objects, i.e. reallocate and relock them. The target frames are deoptimized. - // The methods return false iff at least one reallocation failed. - bool deoptimize_objects(intptr_t* fr_id) { - return true COMPILER2_OR_JVMCI_PRESENT(&& deoptimize_objects_internal(deoptee_thread(), fr_id)); + // Deoptimize objects of frames of the target thread up to the given depth. + // Deoptimize objects of caller frames if they passed references to ArgEscape objects as arguments. + // Return false in the case of a reallocation failure and true otherwise. + bool deoptimize_objects(int depth) { + return deoptimize_objects(0, depth); } - bool deoptimize_objects(int depth) NOT_COMPILER2_OR_JVMCI_RETURN_(true); + // Deoptimize objects of frames of the target thread at depth >= d1 and depth <= d2. + // Deoptimize objects of caller frames if they passed references to ArgEscape objects as arguments. + // Return false in the case of a reallocation failure and true otherwise. + bool deoptimize_objects(int d1, int d2) NOT_COMPILER2_OR_JVMCI_RETURN_(true); // Find and deoptimize non escaping objects and the holding frames on all stacks. bool deoptimize_objects_all_threads() NOT_COMPILER2_OR_JVMCI_RETURN_(true); diff --git a/src/hotspot/share/runtime/flags/jvmFlag.cpp b/src/hotspot/share/runtime/flags/jvmFlag.cpp index d90a134d0b5..464f4a75f96 100644 --- a/src/hotspot/share/runtime/flags/jvmFlag.cpp +++ b/src/hotspot/share/runtime/flags/jvmFlag.cpp @@ -41,10 +41,15 @@ static bool is_product_build() { #endif } -void JVMFlag::set_origin(Flags origin) { +void JVMFlag::set_origin(JVMFlagOrigin new_origin) { + int old_flags = _flags; + int origin = static_cast(new_origin); assert((origin & VALUE_ORIGIN_MASK) == origin, "sanity"); - Flags new_origin = Flags((origin == COMMAND_LINE) ? Flags(origin | ORIG_COMMAND_LINE) : origin); - _flags = Flags((_flags & ~VALUE_ORIGIN_MASK) | new_origin); + int was_in_cmdline = (new_origin == JVMFlagOrigin::COMMAND_LINE) ? WAS_SET_ON_COMMAND_LINE : 0; + _flags = Flags((_flags & ~VALUE_ORIGIN_MASK) | origin | was_in_cmdline); + if ((old_flags & WAS_SET_ON_COMMAND_LINE) != 0) { + assert((_flags & WAS_SET_ON_COMMAND_LINE) != 0, "once initialized, should never change"); + } } /** @@ -376,29 +381,28 @@ void JVMFlag::print_kind(outputStream* st, unsigned int width) const { } void JVMFlag::print_origin(outputStream* st, unsigned int width) const { - int origin = _flags & VALUE_ORIGIN_MASK; st->print("{"); - switch(origin) { - case DEFAULT: + switch(get_origin()) { + case JVMFlagOrigin::DEFAULT: st->print("default"); break; - case COMMAND_LINE: + case JVMFlagOrigin::COMMAND_LINE: st->print("command line"); break; - case ENVIRON_VAR: + case JVMFlagOrigin::ENVIRON_VAR: st->print("environment"); break; - case CONFIG_FILE: + case JVMFlagOrigin::CONFIG_FILE: st->print("config file"); break; - case MANAGEMENT: + case JVMFlagOrigin::MANAGEMENT: st->print("management"); break; - case ERGONOMIC: - if (_flags & ORIG_COMMAND_LINE) { + case JVMFlagOrigin::ERGONOMIC: + if (_flags & WAS_SET_ON_COMMAND_LINE) { st->print("command line, "); } st->print("ergonomic"); break; - case ATTACH_ON_DEMAND: + case JVMFlagOrigin::ATTACH_ON_DEMAND: st->print("attach"); break; - case INTERNAL: + case JVMFlagOrigin::INTERNAL: st->print("internal"); break; - case JIMAGE_RESOURCE: + case JVMFlagOrigin::JIMAGE_RESOURCE: st->print("jimage"); break; } st->print("}"); @@ -495,7 +499,7 @@ static constexpr int flag_group(int flag_enum) { constexpr JVMFlag::JVMFlag(int flag_enum, FlagType type, const char* name, void* addr, int flags, int extra_flags, const char* doc) : _addr(addr), _name(name), _flags(), _type(type) NOT_PRODUCT(COMMA _doc(doc)) { - flags = flags | extra_flags | JVMFlag::DEFAULT | flag_group(flag_enum); + flags = flags | extra_flags | static_cast(JVMFlagOrigin::DEFAULT) | flag_group(flag_enum); if ((flags & JVMFlag::KIND_PRODUCT) != 0) { if (flags & (JVMFlag::KIND_DIAGNOSTIC | JVMFlag::KIND_MANAGEABLE | JVMFlag::KIND_EXPERIMENTAL)) { // Backwards compatibility. This will be relaxed in JDK-7123237. @@ -653,7 +657,7 @@ void JVMFlag::printSetFlags(outputStream* out) { // Print for (size_t i = 0; i < length; i++) { - if (array[i]->get_origin() /* naked field! */) { + if (array[i]->get_origin() != JVMFlagOrigin::DEFAULT) { array[i]->print_as_flag(out); out->print(" "); } diff --git a/src/hotspot/share/runtime/flags/jvmFlag.hpp b/src/hotspot/share/runtime/flags/jvmFlag.hpp index 9704ddd42f3..d4beb7d85e3 100644 --- a/src/hotspot/share/runtime/flags/jvmFlag.hpp +++ b/src/hotspot/share/runtime/flags/jvmFlag.hpp @@ -26,27 +26,34 @@ #define SHARE_RUNTIME_FLAGS_JVMFLAG_HPP #include "utilities/globalDefinitions.hpp" +#include "utilities/enumIterator.hpp" #include "utilities/macros.hpp" #include "utilities/vmEnums.hpp" class outputStream; +enum class JVMFlagOrigin : int { + // This is the value returned by JVMFlag::get_origin(). It records who + // has most recently changed the value of a JVMFlag. DEFAULT means that the + // flag was never changed, or was most recently changed by FLAG_SET_DEFAULT. + DEFAULT = 0, + COMMAND_LINE = 1, + ENVIRON_VAR = 2, + CONFIG_FILE = 3, + MANAGEMENT = 4, + ERGONOMIC = 5, + ATTACH_ON_DEMAND = 6, + INTERNAL = 7, + JIMAGE_RESOURCE = 8, +}; + +ENUMERATOR_RANGE(JVMFlagOrigin, JVMFlagOrigin::DEFAULT, JVMFlagOrigin::JIMAGE_RESOURCE) + class JVMFlag { friend class VMStructs; + public: enum Flags : int { - // latest value origin - DEFAULT = 0, - COMMAND_LINE = 1, - ENVIRON_VAR = 2, - CONFIG_FILE = 3, - MANAGEMENT = 4, - ERGONOMIC = 5, - ATTACH_ON_DEMAND = 6, - INTERNAL = 7, - JIMAGE_RESOURCE = 8, - - LAST_VALUE_ORIGIN = JIMAGE_RESOURCE, VALUE_ORIGIN_BITS = 4, VALUE_ORIGIN_MASK = right_n_bits(VALUE_ORIGIN_BITS), @@ -64,10 +71,15 @@ class JVMFlag { KIND_LP64_PRODUCT = 1 << 14, KIND_JVMCI = 1 << 15, - // set this bit if the flag was set on the command line - ORIG_COMMAND_LINE = 1 << 17, + // Note the difference: + // f->get_origin() == COMMAND_LINE + // f was mostly recently set by the command-line + // f->_flags & WAS_SET_ON_COMMAND_LINE + // f was specified on the command-line (but may have since been updated by + // someone else like FLAG_SET_ERGO) + WAS_SET_ON_COMMAND_LINE = 1 << 17, - KIND_MASK = ~(VALUE_ORIGIN_MASK | ORIG_COMMAND_LINE) + KIND_MASK = ~(VALUE_ORIGIN_MASK | WAS_SET_ON_COMMAND_LINE) }; enum Error { @@ -232,20 +244,20 @@ class JVMFlag { *static_cast(_addr) = value; } - Flags get_origin() const { return Flags(_flags & VALUE_ORIGIN_MASK); } - void set_origin(Flags origin); - - bool is_default() const { return (get_origin() == DEFAULT); } - bool is_ergonomic() const { return (get_origin() == ERGONOMIC); } - bool is_command_line() const { return (_flags & ORIG_COMMAND_LINE) != 0; } - void set_command_line() { _flags = Flags(_flags | ORIG_COMMAND_LINE); } - bool is_jimage_resource() const { return (get_origin() == JIMAGE_RESOURCE); } - bool is_product() const { return (_flags & KIND_PRODUCT) != 0; } - bool is_manageable() const { return (_flags & KIND_MANAGEABLE) != 0; } - bool is_diagnostic() const { return (_flags & KIND_DIAGNOSTIC) != 0; } - bool is_experimental() const { return (_flags & KIND_EXPERIMENTAL) != 0; } - bool is_notproduct() const { return (_flags & KIND_NOT_PRODUCT) != 0; } - bool is_develop() const { return (_flags & KIND_DEVELOP) != 0; } + JVMFlagOrigin get_origin() const { return JVMFlagOrigin(_flags & VALUE_ORIGIN_MASK); } + void set_origin(JVMFlagOrigin origin); + + bool is_default() const { return (get_origin() == JVMFlagOrigin::DEFAULT); } + bool is_ergonomic() const { return (get_origin() == JVMFlagOrigin::ERGONOMIC); } + bool is_command_line() const { return (_flags & WAS_SET_ON_COMMAND_LINE) != 0; } + void set_command_line() { _flags = Flags(_flags | WAS_SET_ON_COMMAND_LINE); } + bool is_jimage_resource() const { return (get_origin() == JVMFlagOrigin::JIMAGE_RESOURCE); } + bool is_product() const { return (_flags & KIND_PRODUCT) != 0; } + bool is_manageable() const { return (_flags & KIND_MANAGEABLE) != 0; } + bool is_diagnostic() const { return (_flags & KIND_DIAGNOSTIC) != 0; } + bool is_experimental() const { return (_flags & KIND_EXPERIMENTAL) != 0; } + bool is_notproduct() const { return (_flags & KIND_NOT_PRODUCT) != 0; } + bool is_develop() const { return (_flags & KIND_DEVELOP) != 0; } bool is_constant_in_binary() const; diff --git a/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp b/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp index 07ff6b1546e..51aeb086081 100644 --- a/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp +++ b/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp @@ -33,22 +33,22 @@ #include "utilities/ostream.hpp" template -static void trace_flag_changed(JVMFlag* flag, const T old_value, const T new_value, const JVMFlag::Flags origin) { +static void trace_flag_changed(JVMFlag* flag, const T old_value, const T new_value, const JVMFlagOrigin origin) { EVENT e; e.set_name(flag->name()); e.set_oldValue(old_value); e.set_newValue(new_value); - e.set_origin(origin); + e.set_origin(static_cast(origin)); e.commit(); } class FlagAccessImpl { public: - JVMFlag::Error set(JVMFlag* flag, void* value, JVMFlag::Flags origin) const { + JVMFlag::Error set(JVMFlag* flag, void* value, JVMFlagOrigin origin) const { return set_impl(flag, value, origin); } - virtual JVMFlag::Error set_impl(JVMFlag* flag, void* value, JVMFlag::Flags origin) const = 0; + virtual JVMFlag::Error set_impl(JVMFlag* flag, void* value, JVMFlagOrigin origin) const = 0; virtual JVMFlag::Error check_range(const JVMFlag* flag, bool verbose) const { return JVMFlag::SUCCESS; } virtual void print_range(outputStream* st, const JVMFlagLimit* range) const { ShouldNotReachHere(); } virtual void print_default_range(outputStream* st) const { ShouldNotReachHere(); } @@ -59,7 +59,7 @@ template class TypedFlagAccessImpl : public FlagAccessImpl { public: - JVMFlag::Error check_constraint_and_set(JVMFlag* flag, void* value_addr, JVMFlag::Flags origin, bool verbose) const { + JVMFlag::Error check_constraint_and_set(JVMFlag* flag, void* value_addr, JVMFlagOrigin origin, bool verbose) const { T value = *((T*)value_addr); const JVMTypedFlagLimit* constraint = (const JVMTypedFlagLimit*)JVMFlagLimit::get_constraint(flag); if (constraint != NULL && constraint->phase() <= static_cast(JVMFlagLimit::validating_phase())) { @@ -87,7 +87,7 @@ class TypedFlagAccessImpl : public FlagAccessImpl { class FlagAccessImpl_bool : public TypedFlagAccessImpl { public: - JVMFlag::Error set_impl(JVMFlag* flag, void* value_addr, JVMFlag::Flags origin) const { + JVMFlag::Error set_impl(JVMFlag* flag, void* value_addr, JVMFlagOrigin origin) const { bool verbose = JVMFlagLimit::verbose_checks_needed(); return TypedFlagAccessImpl ::check_constraint_and_set(flag, value_addr, origin, verbose); @@ -101,7 +101,7 @@ class FlagAccessImpl_bool : public TypedFlagAccessImpl class RangedFlagAccessImpl : public TypedFlagAccessImpl { public: - virtual JVMFlag::Error set_impl(JVMFlag* flag, void* value_addr, JVMFlag::Flags origin) const { + virtual JVMFlag::Error set_impl(JVMFlag* flag, void* value_addr, JVMFlagOrigin origin) const { T value = *((T*)value_addr); bool verbose = JVMFlagLimit::verbose_checks_needed(); @@ -292,7 +292,7 @@ inline const FlagAccessImpl* JVMFlagAccess::access_impl(const JVMFlag* flag) { } // This is called by JVMFlagAccess::*AtPut() and JVMFlagAccess::set<...>(JVMFlag* flag, ...) -JVMFlag::Error JVMFlagAccess::set_impl(JVMFlag* flag, int type_enum, void* value, JVMFlag::Flags origin) { +JVMFlag::Error JVMFlagAccess::set_impl(JVMFlag* flag, int type_enum, void* value, JVMFlagOrigin origin) { if (type_enum == JVMFlag::TYPE_ccstr || type_enum == JVMFlag::TYPE_ccstrlist) { return ccstrAtPut(flag, (ccstr*)value, origin); } @@ -306,7 +306,7 @@ JVMFlag::Error JVMFlagAccess::set_impl(JVMFlag* flag, int type_enum, void* value return access_impl(flag)->set(flag, value, origin); } -JVMFlag::Error JVMFlagAccess::ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlag::Flags origin) { +JVMFlag::Error JVMFlagAccess::ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlagOrigin origin) { if (flag == NULL) return JVMFlag::INVALID_FLAG; if (!flag->is_ccstr()) return JVMFlag::WRONG_FORMAT; ccstr old_value = flag->get_ccstr(); @@ -326,7 +326,7 @@ JVMFlag::Error JVMFlagAccess::ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlag::F } // This is called by the FLAG_SET_XXX macros. -JVMFlag::Error JVMFlagAccess::set_impl(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlag::Flags origin) { +JVMFlag::Error JVMFlagAccess::set_impl(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlagOrigin origin) { if (type_enum == JVMFlag::TYPE_ccstr || type_enum == JVMFlag::TYPE_ccstrlist) { return ccstrAtPut((JVMFlagsEnum)flag_enum, *((ccstr*)value), origin); } @@ -337,7 +337,7 @@ JVMFlag::Error JVMFlagAccess::set_impl(JVMFlagsEnum flag_enum, int type_enum, vo } // This is called by the FLAG_SET_XXX macros. -JVMFlag::Error JVMFlagAccess::ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlag::Flags origin) { +JVMFlag::Error JVMFlagAccess::ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlagOrigin origin) { JVMFlag* faddr = JVMFlag::flag_from_enum(flag); assert(faddr->is_ccstr(), "wrong flag type"); ccstr old_value = faddr->get_ccstr(); diff --git a/src/hotspot/share/runtime/flags/jvmFlagAccess.hpp b/src/hotspot/share/runtime/flags/jvmFlagAccess.hpp index ce5dff42e87..91e41ded3da 100644 --- a/src/hotspot/share/runtime/flags/jvmFlagAccess.hpp +++ b/src/hotspot/share/runtime/flags/jvmFlagAccess.hpp @@ -52,9 +52,9 @@ class outputStream; // of setters are provided. See notes below on which one to use. class JVMFlagAccess : AllStatic { inline static const FlagAccessImpl* access_impl(const JVMFlag* flag); - static JVMFlag::Error set_impl(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlag::Flags origin); - static JVMFlag::Error set_impl(JVMFlag* flag, int type_enum, void* value, JVMFlag::Flags origin); - static JVMFlag::Error ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlag::Flags origin); + static JVMFlag::Error set_impl(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlagOrigin origin); + static JVMFlag::Error set_impl(JVMFlag* flag, int type_enum, void* value, JVMFlagOrigin origin); + static JVMFlag::Error ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlagOrigin origin); public: static JVMFlag::Error check_range(const JVMFlag* flag, bool verbose); @@ -85,7 +85,7 @@ class JVMFlagAccess : AllStatic { // It's used to set a specific flag whose type is statically known. A mismatched // type_enum will result in an assert. template - static JVMFlag::Error set(JVMFlagsEnum flag_enum, T value, JVMFlag::Flags origin) { + static JVMFlag::Error set(JVMFlagsEnum flag_enum, T value, JVMFlagOrigin origin) { return set_impl(flag_enum, type_enum, &value, origin); } @@ -95,23 +95,23 @@ class JVMFlagAccess : AllStatic { // Examples callers are arguments.cpp, writeableFlags.cpp, and WB_SetXxxVMFlag functions. // A mismatched type_enum would result in a JVMFlag::WRONG_FORMAT code. template - static JVMFlag::Error set(JVMFlag* flag, T* value, JVMFlag::Flags origin) { + static JVMFlag::Error set(JVMFlag* flag, T* value, JVMFlagOrigin origin) { return set_impl(flag, type_enum, (void*)value, origin); } - static JVMFlag::Error boolAtPut (JVMFlag* f, bool* v, JVMFlag::Flags origin) { return set (f, v, origin); } - static JVMFlag::Error intAtPut (JVMFlag* f, int* v, JVMFlag::Flags origin) { return set (f, v, origin); } - static JVMFlag::Error uintAtPut (JVMFlag* f, uint* v, JVMFlag::Flags origin) { return set (f, v, origin); } - static JVMFlag::Error intxAtPut (JVMFlag* f, intx* v, JVMFlag::Flags origin) { return set (f, v, origin); } - static JVMFlag::Error uintxAtPut (JVMFlag* f, uintx* v, JVMFlag::Flags origin) { return set (f, v, origin); } - static JVMFlag::Error uint64_tAtPut(JVMFlag* f, uint64_t* v, JVMFlag::Flags origin) { return set(f, v, origin); } - static JVMFlag::Error size_tAtPut (JVMFlag* f, size_t* v, JVMFlag::Flags origin) { return set (f, v, origin); } - static JVMFlag::Error doubleAtPut (JVMFlag* f, double* v, JVMFlag::Flags origin) { return set (f, v, origin); } + static JVMFlag::Error boolAtPut (JVMFlag* f, bool* v, JVMFlagOrigin origin) { return set (f, v, origin); } + static JVMFlag::Error intAtPut (JVMFlag* f, int* v, JVMFlagOrigin origin) { return set (f, v, origin); } + static JVMFlag::Error uintAtPut (JVMFlag* f, uint* v, JVMFlagOrigin origin) { return set (f, v, origin); } + static JVMFlag::Error intxAtPut (JVMFlag* f, intx* v, JVMFlagOrigin origin) { return set (f, v, origin); } + static JVMFlag::Error uintxAtPut (JVMFlag* f, uintx* v, JVMFlagOrigin origin) { return set (f, v, origin); } + static JVMFlag::Error uint64_tAtPut(JVMFlag* f, uint64_t* v, JVMFlagOrigin origin) { return set(f, v, origin); } + static JVMFlag::Error size_tAtPut (JVMFlag* f, size_t* v, JVMFlagOrigin origin) { return set (f, v, origin); } + static JVMFlag::Error doubleAtPut (JVMFlag* f, double* v, JVMFlagOrigin origin) { return set (f, v, origin); } // Special handling needed for ccstr // Contract: JVMFlag will make private copy of the incoming value. // Outgoing value is always malloc-ed, and caller MUST call free. - static JVMFlag::Error ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlag::Flags origin); + static JVMFlag::Error ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlagOrigin origin); // Handy aliases static JVMFlag::Error ccstrAt(const JVMFlag* flag, ccstr* value) { diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index 800562f11ca..86c193c7d05 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -2411,11 +2411,6 @@ const intx ObjectAlignmentInBytes = 8; product(bool, WhiteBoxAPI, false, DIAGNOSTIC, \ "Enable internal testing APIs") \ \ - product(intx, SurvivorAlignmentInBytes, 0, EXPERIMENTAL, \ - "Default survivor space alignment in bytes") \ - range(8, 256) \ - constraint(SurvivorAlignmentInBytesConstraintFunc,AfterErgo) \ - \ product(ccstr, DumpLoadedClassList, NULL, \ "Dump the names all loaded classes, that could be stored into " \ "the CDS archive, in the specified file") \ diff --git a/src/hotspot/share/runtime/globals_extension.hpp b/src/hotspot/share/runtime/globals_extension.hpp index e5a7750e3d6..ceb5413b212 100644 --- a/src/hotspot/share/runtime/globals_extension.hpp +++ b/src/hotspot/share/runtime/globals_extension.hpp @@ -53,7 +53,7 @@ enum JVMFlagsEnum : int { #define FLAG_MEMBER_SETTER(name) Flag_##name##_set #define FLAG_MEMBER_SETTER_(type, name) \ - inline JVMFlag::Error FLAG_MEMBER_SETTER(name)(type value, JVMFlag::Flags origin) { \ + inline JVMFlag::Error FLAG_MEMBER_SETTER(name)(type value, JVMFlagOrigin origin) { \ return JVMFlagAccess::set(FLAG_MEMBER_ENUM(name), value, origin); \ } @@ -75,9 +75,9 @@ ALL_FLAGS(DEFINE_FLAG_MEMBER_SETTER, #define FLAG_SET_DEFAULT(name, value) ((name) = (value)) #define FLAG_SET_CMDLINE(name, value) (JVMFlag::setOnCmdLine(FLAG_MEMBER_ENUM(name)), \ - FLAG_MEMBER_SETTER(name)((value), JVMFlag::COMMAND_LINE)) -#define FLAG_SET_ERGO(name, value) (FLAG_MEMBER_SETTER(name)((value), JVMFlag::ERGONOMIC)) -#define FLAG_SET_MGMT(name, value) (FLAG_MEMBER_SETTER(name)((value), JVMFlag::MANAGEMENT)) + FLAG_MEMBER_SETTER(name)((value), JVMFlagOrigin::COMMAND_LINE)) +#define FLAG_SET_ERGO(name, value) (FLAG_MEMBER_SETTER(name)((value), JVMFlagOrigin::ERGONOMIC)) +#define FLAG_SET_MGMT(name, value) (FLAG_MEMBER_SETTER(name)((value), JVMFlagOrigin::MANAGEMENT)) #define FLAG_SET_ERGO_IF_DEFAULT(name, value) \ do { \ diff --git a/src/hotspot/share/runtime/java.cpp b/src/hotspot/share/runtime/java.cpp index 3e0a274a247..c7726fd5388 100644 --- a/src/hotspot/share/runtime/java.cpp +++ b/src/hotspot/share/runtime/java.cpp @@ -478,6 +478,12 @@ void before_exit(JavaThread* thread) { BytecodeHistogram::print(); } +#ifdef LINUX + if (DumpPerfMapAtExit) { + CodeCache::write_perf_map(); + } +#endif + if (JvmtiExport::should_post_thread_life()) { JvmtiExport::post_thread_end(thread); } @@ -572,6 +578,13 @@ void vm_direct_exit(int code) { os::exit(code); } +void vm_direct_exit(int code, const char* message) { + if (message != nullptr) { + tty->print_cr("%s", message); + } + vm_direct_exit(code); +} + void vm_perform_shutdown_actions() { if (is_init_completed()) { Thread* thread = Thread::current_or_null(); diff --git a/src/hotspot/share/runtime/java.hpp b/src/hotspot/share/runtime/java.hpp index c24b2619c6e..8fb5aff75fd 100644 --- a/src/hotspot/share/runtime/java.hpp +++ b/src/hotspot/share/runtime/java.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ extern void vm_exit(int code); // Wrapper for ::exit() extern void vm_direct_exit(int code); +extern void vm_direct_exit(int code, const char* message); // Shutdown the VM but do not exit the process extern void vm_shutdown(); diff --git a/src/hotspot/share/runtime/keepStackGCProcessed.cpp b/src/hotspot/share/runtime/keepStackGCProcessed.cpp new file mode 100644 index 00000000000..df851b9f1cc --- /dev/null +++ b/src/hotspot/share/runtime/keepStackGCProcessed.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "runtime/safepoint.hpp" +#include "runtime/stackWatermark.inline.hpp" +#include "runtime/stackWatermarkSet.inline.hpp" +#include "runtime/keepStackGCProcessed.hpp" + +KeepStackGCProcessedMark::KeepStackGCProcessedMark(JavaThread* jt) : + _active(true), + _jt(jt) { + finish_processing(); + if (!Thread::current()->is_Java_thread()) { + assert(SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread(), + "must be either Java thread or VM thread in a safepoint"); + _active = false; + return; + } + StackWatermark* our_watermark = StackWatermarkSet::get(JavaThread::current(), StackWatermarkKind::gc); + if (our_watermark == NULL) { + _active = false; + return; + } + StackWatermark* their_watermark = StackWatermarkSet::get(jt, StackWatermarkKind::gc); + our_watermark->link_watermark(their_watermark); +} + +KeepStackGCProcessedMark::~KeepStackGCProcessedMark() { + if (!_active) { + return; + } + StackWatermark* our_watermark = StackWatermarkSet::get(JavaThread::current(), StackWatermarkKind::gc); + our_watermark->link_watermark(NULL); +} + +void KeepStackGCProcessedMark::finish_processing() { + StackWatermarkSet::finish_processing(_jt, NULL /* context */, StackWatermarkKind::gc); +} diff --git a/src/hotspot/share/gc/z/zForwardingTable.cpp b/src/hotspot/share/runtime/keepStackGCProcessed.hpp similarity index 54% rename from src/hotspot/share/gc/z/zForwardingTable.cpp rename to src/hotspot/share/runtime/keepStackGCProcessed.hpp index 926ae7fe63e..2c36991fe28 100644 --- a/src/hotspot/share/gc/z/zForwardingTable.cpp +++ b/src/hotspot/share/runtime/keepStackGCProcessed.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -19,30 +19,31 @@ * Please 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/z/zForwarding.inline.hpp" -#include "gc/z/zForwardingTable.inline.hpp" -#include "gc/z/zGlobals.hpp" -#include "gc/z/zGranuleMap.inline.hpp" -#include "utilities/debug.hpp" +#ifndef SHARE_RUNTIME_KEEPSTACKGCPROCESSED_HPP +#define SHARE_RUNTIME_KEEPSTACKGCPROCESSED_HPP + +#include "memory/allocation.hpp" +#include "runtime/stackWatermark.hpp" +#include "runtime/stackWatermarkKind.hpp" +#include "runtime/stackWatermarkSet.hpp" -ZForwardingTable::ZForwardingTable() : - _map(ZAddressOffsetMax) {} +// Use this class to mark a remote thread you are currently interested +// in examining the entire stack, without it slipping into an unprocessed +// state at safepoint polls. +class KeepStackGCProcessedMark : public StackObj { + friend class StackWatermark; + bool _active; + JavaThread* _jt; -void ZForwardingTable::insert(ZForwarding* forwarding) { - const uintptr_t offset = forwarding->start(); - const size_t size = forwarding->size(); + void finish_processing(); - assert(_map.get(offset) == NULL, "Invalid entry"); - _map.put(offset, size, forwarding); -} +public: + KeepStackGCProcessedMark(JavaThread* jt); + ~KeepStackGCProcessedMark(); +}; -void ZForwardingTable::remove(ZForwarding* forwarding) { - const uintptr_t offset = forwarding->start(); - const size_t size = forwarding->size(); - assert(_map.get(offset) == forwarding, "Invalid entry"); - _map.put(offset, size, NULL); -} +#endif // SHARE_RUNTIME_KEEPSTACKGCPROCESSED_HPP diff --git a/src/hotspot/share/runtime/mutex.cpp b/src/hotspot/share/runtime/mutex.cpp index e8eb720e2a6..b9e1b0578dc 100644 --- a/src/hotspot/share/runtime/mutex.cpp +++ b/src/hotspot/share/runtime/mutex.cpp @@ -50,8 +50,8 @@ void Mutex::check_safepoint_state(Thread* thread) { // If the JavaThread checks for safepoint, verify that the lock wasn't created with safepoint_check_never. if (thread->is_active_Java_thread()) { assert(_safepoint_check_required != _safepoint_check_never, - "This lock should %s have a safepoint check for Java threads: %s", - _safepoint_check_required ? "always" : "never", name()); + "This lock should never have a safepoint check for Java threads: %s", + name()); // Also check NoSafepointVerifier, and thread state is _thread_in_vm thread->check_for_valid_safepoint_state(); @@ -65,8 +65,8 @@ void Mutex::check_safepoint_state(Thread* thread) { void Mutex::check_no_safepoint_state(Thread* thread) { check_block_state(thread); assert(!thread->is_active_Java_thread() || _safepoint_check_required != _safepoint_check_always, - "This lock should %s have a safepoint check for Java threads: %s", - _safepoint_check_required ? "always" : "never", name()); + "This lock should always have a safepoint check for Java threads: %s", + name()); } #endif // ASSERT diff --git a/src/hotspot/share/runtime/mutex.hpp b/src/hotspot/share/runtime/mutex.hpp index ee4cd68cd51..1ab0832edab 100644 --- a/src/hotspot/share/runtime/mutex.hpp +++ b/src/hotspot/share/runtime/mutex.hpp @@ -99,10 +99,8 @@ class Mutex : public CHeapObj { void no_safepoint_verifier (Thread* thread, bool enable) NOT_DEBUG_RETURN; public: - enum { - _allow_vm_block_flag = true, - _as_suspend_equivalent_flag = true - }; + static const bool _allow_vm_block_flag = true; + static const bool _as_suspend_equivalent_flag = true; // Locks can be acquired with or without a safepoint check. NonJavaThreads do not follow // the safepoint protocol when acquiring locks. @@ -124,12 +122,17 @@ class Mutex : public CHeapObj { // deadlock can occur. We should check this by noting which // locks are shared, and walk held locks during safepoint checking. - enum SafepointCheckFlag { + enum class SafepointCheckFlag { _safepoint_check_flag, _no_safepoint_check_flag }; + // Bring the enumerator names into class scope. + static const SafepointCheckFlag _safepoint_check_flag = + SafepointCheckFlag::_safepoint_check_flag; + static const SafepointCheckFlag _no_safepoint_check_flag = + SafepointCheckFlag::_no_safepoint_check_flag; - enum SafepointCheckRequired { + enum class SafepointCheckRequired { _safepoint_check_never, // Mutexes with this value will cause errors // when acquired by a JavaThread with a safepoint check. _safepoint_check_sometimes, // A couple of special locks are acquired by JavaThreads sometimes @@ -138,6 +141,13 @@ class Mutex : public CHeapObj { _safepoint_check_always // Mutexes with this value will cause errors // when acquired by a JavaThread without a safepoint check. }; + // Bring the enumerator names into class scope. + static const SafepointCheckRequired _safepoint_check_never = + SafepointCheckRequired::_safepoint_check_never; + static const SafepointCheckRequired _safepoint_check_sometimes = + SafepointCheckRequired::_safepoint_check_sometimes; + static const SafepointCheckRequired _safepoint_check_always = + SafepointCheckRequired::_safepoint_check_always; NOT_PRODUCT(SafepointCheckRequired _safepoint_check_required;) diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp index 07d33964713..41d3c0910e9 100644 --- a/src/hotspot/share/runtime/mutexLocker.hpp +++ b/src/hotspot/share/runtime/mutexLocker.hpp @@ -298,7 +298,7 @@ class MutexUnlocker: StackObj { public: MutexUnlocker(Mutex* mutex, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) : _mutex(mutex), - _no_safepoint_check(flag) { + _no_safepoint_check(flag == Mutex::_no_safepoint_check_flag) { _mutex->unlock(); } diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index 433818c8d24..bca50071ef9 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -1002,8 +1002,14 @@ void os::print_date_and_time(outputStream *st, char* buf, size_t buflen) { struct tm tz; if (localtime_pd(&tloc, &tz) != NULL) { - ::strftime(buf, buflen, "%Z", &tz); - st->print("Time: %s %s", timestring, buf); + wchar_t w_buf[80]; + size_t n = ::wcsftime(w_buf, 80, L"%Z", &tz); + if (n > 0) { + ::wcstombs(buf, w_buf, buflen); + st->print("Time: %s %s", timestring, buf); + } else { + st->print("Time: %s", timestring); + } } else { st->print("Time: %s", timestring); } diff --git a/src/hotspot/share/runtime/safepointMechanism.cpp b/src/hotspot/share/runtime/safepointMechanism.cpp index 2218b527d16..bb10694b000 100644 --- a/src/hotspot/share/runtime/safepointMechanism.cpp +++ b/src/hotspot/share/runtime/safepointMechanism.cpp @@ -83,13 +83,13 @@ void SafepointMechanism::process(JavaThread *thread) { SafepointSynchronize::block(thread); // Recursive } - // The call to start_processing fixes the thread's oops and the first few frames. + // The call to on_safepoint fixes the thread's oops and the first few frames. // // The call has been carefully placed here to cater for a few situations: // 1) After we exit from block after a global poll // 2) After a thread races with the disarming of the global poll and transitions from native/blocked // 3) Before the handshake code is run - StackWatermarkSet::start_processing(thread, StackWatermarkKind::gc); + StackWatermarkSet::on_safepoint(thread); if (thread->handshake_state()->should_process()) { thread->handshake_state()->process_by_self(); diff --git a/src/hotspot/share/runtime/stackOverflow.hpp b/src/hotspot/share/runtime/stackOverflow.hpp index 45a2314f022..c8e4249ab25 100644 --- a/src/hotspot/share/runtime/stackOverflow.hpp +++ b/src/hotspot/share/runtime/stackOverflow.hpp @@ -137,12 +137,15 @@ class StackOverflow { return _stack_red_zone_size; } + // Returns base of red zone (one-beyond the highest red zone address, so + // itself outside red zone and the highest address of the yellow zone). address stack_red_zone_base() const { return (address)(stack_end() + stack_red_zone_size()); } + // Returns true if address points into the red zone. bool in_stack_red_zone(address a) const { - return a <= stack_red_zone_base() && a >= stack_end(); + return a < stack_red_zone_base() && a >= stack_end(); } static size_t stack_yellow_zone_size() { @@ -155,20 +158,25 @@ class StackOverflow { return _stack_reserved_zone_size; } + // Returns base of the reserved zone (one-beyond the highest reserved zone address). address stack_reserved_zone_base() const { return (address)(stack_end() + (stack_red_zone_size() + stack_yellow_zone_size() + stack_reserved_zone_size())); } + + // Returns true if address points into the reserved zone. bool in_stack_reserved_zone(address a) const { - return (a <= stack_reserved_zone_base()) && + return (a < stack_reserved_zone_base()) && (a >= (address)((intptr_t)stack_reserved_zone_base() - stack_reserved_zone_size())); } static size_t stack_yellow_reserved_zone_size() { return _stack_yellow_zone_size + _stack_reserved_zone_size; } + + // Returns true if a points into either yellow or reserved zone. bool in_stack_yellow_reserved_zone(address a) const { - return (a <= stack_reserved_zone_base()) && (a >= stack_red_zone_base()); + return (a < stack_reserved_zone_base()) && (a >= stack_red_zone_base()); } // Size of red + yellow + reserved zones. diff --git a/src/hotspot/share/runtime/stackValue.cpp b/src/hotspot/share/runtime/stackValue.cpp index 43828d621d4..91ca8fe5850 100644 --- a/src/hotspot/share/runtime/stackValue.cpp +++ b/src/hotspot/share/runtime/stackValue.cpp @@ -33,7 +33,7 @@ #include "gc/z/zBarrier.inline.hpp" #endif #if INCLUDE_SHENANDOAHGC -#include "gc/shenandoah/shenandoahBarrierSet.hpp" +#include "gc/shenandoah/shenandoahBarrierSet.inline.hpp" #endif StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv) { diff --git a/src/hotspot/share/runtime/stackWatermark.cpp b/src/hotspot/share/runtime/stackWatermark.cpp index 1dbd3f8c860..2d6722f2e8c 100644 --- a/src/hotspot/share/runtime/stackWatermark.cpp +++ b/src/hotspot/share/runtime/stackWatermark.cpp @@ -163,7 +163,8 @@ StackWatermark::StackWatermark(JavaThread* jt, StackWatermarkKind kind, uint32_t _jt(jt), _iterator(NULL), _lock(Mutex::tty - 1, "stack_watermark_lock", true, Mutex::_safepoint_check_never), - _kind(kind) { + _kind(kind), + _linked_watermark(NULL) { } StackWatermark::~StackWatermark() { @@ -247,6 +248,11 @@ void StackWatermark::process_one() { } } +void StackWatermark::link_watermark(StackWatermark* watermark) { + assert(watermark == NULL || _linked_watermark == NULL, "nesting not supported"); + _linked_watermark = watermark; +} + uintptr_t StackWatermark::watermark() { return Atomic::load_acquire(&_watermark); } @@ -280,6 +286,14 @@ bool StackWatermark::processing_completed_acquire() const { return processing_completed(Atomic::load_acquire(&_state)); } +void StackWatermark::on_safepoint() { + start_processing(); + StackWatermark* linked_watermark = _linked_watermark; + if (linked_watermark != NULL) { + linked_watermark->finish_processing(NULL /* context */); + } +} + void StackWatermark::start_processing() { if (!processing_started_acquire()) { MutexLocker ml(&_lock, Mutex::_no_safepoint_check_flag); diff --git a/src/hotspot/share/runtime/stackWatermark.hpp b/src/hotspot/share/runtime/stackWatermark.hpp index df0c13840b9..342bbd15613 100644 --- a/src/hotspot/share/runtime/stackWatermark.hpp +++ b/src/hotspot/share/runtime/stackWatermark.hpp @@ -26,6 +26,7 @@ #define SHARE_RUNTIME_STACKWATERMARK_HPP #include "memory/allocation.hpp" +#include "runtime/mutex.hpp" #include "runtime/stackWatermarkKind.hpp" class frame; @@ -92,6 +93,7 @@ class StackWatermark : public CHeapObj { StackWatermarkFramesIterator* _iterator; Mutex _lock; StackWatermarkKind _kind; + StackWatermark* _linked_watermark; void process_one(); @@ -127,6 +129,8 @@ class StackWatermark : public CHeapObj { StackWatermark* next() const { return _next; } void set_next(StackWatermark* n) { _next = n; } + void link_watermark(StackWatermark* watermark); + uintptr_t watermark(); uintptr_t last_processed(); @@ -139,6 +143,7 @@ class StackWatermark : public CHeapObj { void after_unwind(); void on_iteration(const frame& f); + void on_safepoint(); void start_processing(); void finish_processing(void* context); }; diff --git a/src/hotspot/share/runtime/stackWatermark.inline.hpp b/src/hotspot/share/runtime/stackWatermark.inline.hpp index 161c7687e83..93c92234457 100644 --- a/src/hotspot/share/runtime/stackWatermark.inline.hpp +++ b/src/hotspot/share/runtime/stackWatermark.inline.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_RUNTIME_STACKWATERMARK_INLINE_HPP #define SHARE_RUNTIME_STACKWATERMARK_INLINE_HPP +#include "code/nmethod.hpp" #include "runtime/stackWatermark.hpp" #include "runtime/thread.hpp" diff --git a/src/hotspot/share/runtime/stackWatermarkSet.cpp b/src/hotspot/share/runtime/stackWatermarkSet.cpp index 617e3b38448..e2836797120 100644 --- a/src/hotspot/share/runtime/stackWatermarkSet.cpp +++ b/src/hotspot/share/runtime/stackWatermarkSet.cpp @@ -109,6 +109,13 @@ void StackWatermarkSet::on_iteration(JavaThread* jt, const frame& fr) { // calling this might not be Thread::current(). } +void StackWatermarkSet::on_safepoint(JavaThread* jt) { + StackWatermark* watermark = get(jt, StackWatermarkKind::gc); + if (watermark != NULL) { + watermark->on_safepoint(); + } +} + void StackWatermarkSet::start_processing(JavaThread* jt, StackWatermarkKind kind) { verify_processing_context(); assert(!jt->is_terminated(), "Poll after termination is a bug"); diff --git a/src/hotspot/share/runtime/stackWatermarkSet.hpp b/src/hotspot/share/runtime/stackWatermarkSet.hpp index ee3af3ceff4..78cfc7f2827 100644 --- a/src/hotspot/share/runtime/stackWatermarkSet.hpp +++ b/src/hotspot/share/runtime/stackWatermarkSet.hpp @@ -73,6 +73,9 @@ class StackWatermarkSet : public AllStatic { // Called by stack walkers when walking into a frame static void on_iteration(JavaThread* jt, const frame& fr); + // Called to ensure that processing of the thread is started when waking up from safepoint + static void on_safepoint(JavaThread* jt); + // Called to ensure that processing of the thread is started static void start_processing(JavaThread* jt, StackWatermarkKind kind); diff --git a/src/hotspot/share/runtime/threadHeapSampler.cpp b/src/hotspot/share/runtime/threadHeapSampler.cpp index 68f02f0d2fe..21f57c9f055 100644 --- a/src/hotspot/share/runtime/threadHeapSampler.cpp +++ b/src/hotspot/share/runtime/threadHeapSampler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, Google and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -24,6 +24,8 @@ */ #include "precompiled.hpp" +#include "logging/log.hpp" +#include "logging/logTag.hpp" #include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/sharedRuntime.hpp" @@ -34,19 +36,305 @@ uint64_t ThreadHeapSampler::_rnd; // Default is 512kb. volatile int ThreadHeapSampler::_sampling_interval = 512 * 1024; -// Ordering here is important: _log_table first, _log_table_initialized second. -double ThreadHeapSampler::_log_table[1 << ThreadHeapSampler::FastLogNumBits] = {}; +// Statics for the fast log +static const int FastLogNumBits = 10; +static const int FastLogCount = 1 << FastLogNumBits; +static const int FastLogMask = FastLogCount - 1; +static const double log_table[FastLogCount] = { + 0.000704269011247, 0.002111776479852, 0.003517912108602, 0.004922678569045, + 0.006326078524934, 0.007728114632254, 0.009128789539256, 0.010528105886485, + 0.011926066306808, 0.013322673425448, 0.014717929860010, 0.016111838220512, + 0.017504401109415, 0.018895621121649, 0.020285500844648, 0.021674042858370, + 0.023061249735335, 0.024447124040647, 0.025831668332026, 0.027214885159835, + 0.028596777067108, 0.029977346589579, 0.031356596255709, 0.032734528586714, + 0.034111146096593, 0.035486451292154, 0.036860446673046, 0.038233134731779, + 0.039604517953758, 0.040974598817306, 0.042343379793691, 0.043710863347156, + 0.045077051934941, 0.046441948007312, 0.047805554007589, 0.049167872372170, + 0.050528905530555, 0.051888655905378, 0.053247125912426, 0.054604317960672, + 0.055960234452294, 0.057314877782703, 0.058668250340571, 0.060020354507853, + 0.061371192659811, 0.062720767165044, 0.064069080385509, 0.065416134676548, + 0.066761932386908, 0.068106475858773, 0.069449767427783, 0.070791809423061, + 0.072132604167234, 0.073472153976460, 0.074810461160454, 0.076147528022505, + 0.077483356859507, 0.078817949961979, 0.080151309614087, 0.081483438093674, + 0.082814337672274, 0.084144010615144, 0.085472459181283, 0.086799685623453, + 0.088125692188207, 0.089450481115907, 0.090774054640751, 0.092096414990791, + 0.093417564387961, 0.094737505048093, 0.096056239180946, 0.097373768990222, + 0.098690096673594, 0.100005224422721, 0.101319154423276, 0.102631888854968, + 0.103943429891557, 0.105253779700883, 0.106562940444883, 0.107870914279614, + 0.109177703355275, 0.110483309816226, 0.111787735801012, 0.113090983442381, + 0.114393054867307, 0.115693952197011, 0.116993677546981, 0.118292233026990, + 0.119589620741122, 0.120885842787790, 0.122180901259752, 0.123474798244141, + 0.124767535822473, 0.126059116070680, 0.127349541059119, 0.128638812852598, + 0.129926933510393, 0.131213905086272, 0.132499729628509, 0.133784409179907, + 0.135067945777817, 0.136350341454156, 0.137631598235428, 0.138911718142743, + 0.140190703191836, 0.141468555393084, 0.142745276751529, 0.144020869266892, + 0.145295334933597, 0.146568675740786, 0.147840893672337, 0.149111990706888, + 0.150381968817848, 0.151650829973421, 0.152918576136622, 0.154185209265297, + 0.155450731312137, 0.156715144224702, 0.157978449945432, 0.159240650411673, + 0.160501747555687, 0.161761743304675, 0.163020639580794, 0.164278438301170, + 0.165535141377924, 0.166790750718180, 0.168045268224090, 0.169298695792846, + 0.170551035316700, 0.171802288682983, 0.173052457774115, 0.174301544467631, + 0.175549550636190, 0.176796478147599, 0.178042328864822, 0.179287104646004, + 0.180530807344482, 0.181773438808808, 0.183015000882756, 0.184255495405349, + 0.185494924210866, 0.186733289128866, 0.187970591984199, 0.189206834597024, + 0.190442018782825, 0.191676146352428, 0.192909219112013, 0.194141238863136, + 0.195372207402739, 0.196602126523170, 0.197830998012197, 0.199058823653021, + 0.200285605224298, 0.201511344500146, 0.202736043250167, 0.203959703239463, + 0.205182326228643, 0.206403913973847, 0.207624468226758, 0.208843990734615, + 0.210062483240231, 0.211279947482008, 0.212496385193948, 0.213711798105673, + 0.214926187942435, 0.216139556425135, 0.217351905270334, 0.218563236190271, + 0.219773550892874, 0.220982851081777, 0.222191138456332, 0.223398414711628, + 0.224604681538499, 0.225809940623543, 0.227014193649133, 0.228217442293435, + 0.229419688230416, 0.230620933129866, 0.231821178657404, 0.233020426474497, + 0.234218678238471, 0.235415935602526, 0.236612200215751, 0.237807473723136, + 0.239001757765583, 0.240195053979925, 0.241387363998937, 0.242578689451346, + 0.243769031961852, 0.244958393151134, 0.246146774635865, 0.247334178028729, + 0.248520604938429, 0.249706056969705, 0.250890535723341, 0.252074042796184, + 0.253256579781154, 0.254438148267256, 0.255618749839596, 0.256798386079390, + 0.257977058563978, 0.259154768866840, 0.260331518557602, 0.261507309202055, + 0.262682142362165, 0.263856019596082, 0.265028942458160, 0.266200912498961, + 0.267371931265274, 0.268542000300123, 0.269711121142782, 0.270879295328784, + 0.272046524389938, 0.273212809854334, 0.274378153246363, 0.275542556086722, + 0.276706019892431, 0.277868546176841, 0.279030136449649, 0.280190792216907, + 0.281350514981036, 0.282509306240837, 0.283667167491501, 0.284824100224623, + 0.285980105928212, 0.287135186086704, 0.288289342180970, 0.289442575688332, + 0.290594888082571, 0.291746280833939, 0.292896755409173, 0.294046313271500, + 0.295194955880655, 0.296342684692889, 0.297489501160979, 0.298635406734241, + 0.299780402858540, 0.300924490976300, 0.302067672526519, 0.303209948944775, + 0.304351321663238, 0.305491792110684, 0.306631361712501, 0.307770031890703, + 0.308907804063939, 0.310044679647506, 0.311180660053355, 0.312315746690106, + 0.313449940963058, 0.314583244274195, 0.315715658022202, 0.316847183602472, + 0.317977822407119, 0.319107575824984, 0.320236445241649, 0.321364432039446, + 0.322491537597468, 0.323617763291577, 0.324743110494416, 0.325867580575418, + 0.326991174900817, 0.328113894833656, 0.329235741733800, 0.330356716957943, + 0.331476821859620, 0.332596057789214, 0.333714426093970, 0.334831928118000, + 0.335948565202297, 0.337064338684741, 0.338179249900111, 0.339293300180094, + 0.340406490853295, 0.341518823245243, 0.342630298678407, 0.343740918472201, + 0.344850683942991, 0.345959596404112, 0.347067657165871, 0.348174867535556, + 0.349281228817452, 0.350386742312842, 0.351491409320021, 0.352595231134304, + 0.353698209048035, 0.354800344350596, 0.355901638328417, 0.357002092264984, + 0.358101707440847, 0.359200485133632, 0.360298426618046, 0.361395533165889, + 0.362491806046063, 0.363587246524577, 0.364681855864560, 0.365775635326268, + 0.366868586167093, 0.367960709641570, 0.369052007001388, 0.370142479495399, + 0.371232128369622, 0.372320954867259, 0.373408960228696, 0.374496145691516, + 0.375582512490507, 0.376668061857668, 0.377752795022220, 0.378836713210614, + 0.379919817646538, 0.381002109550926, 0.382083590141966, 0.383164260635110, + 0.384244122243078, 0.385323176175872, 0.386401423640778, 0.387478865842379, + 0.388555503982561, 0.389631339260521, 0.390706372872775, 0.391780606013166, + 0.392854039872873, 0.393926675640417, 0.394998514501672, 0.396069557639868, + 0.397139806235604, 0.398209261466852, 0.399277924508967, 0.400345796534695, + 0.401412878714178, 0.402479172214964, 0.403544678202014, 0.404609397837712, + 0.405673332281866, 0.406736482691724, 0.407798850221975, 0.408860436024760, + 0.409921241249679, 0.410981267043796, 0.412040514551651, 0.413098984915263, + 0.414156679274141, 0.415213598765286, 0.416269744523207, 0.417325117679919, + 0.418379719364956, 0.419433550705378, 0.420486612825775, 0.421538906848277, + 0.422590433892561, 0.423641195075856, 0.424691191512953, 0.425740424316211, + 0.426788894595561, 0.427836603458520, 0.428883552010191, 0.429929741353273, + 0.430975172588069, 0.432019846812492, 0.433063765122069, 0.434106928609955, + 0.435149338366930, 0.436190995481417, 0.437231901039479, 0.438272056124831, + 0.439311461818846, 0.440350119200562, 0.441388029346687, 0.442425193331607, + 0.443461612227394, 0.444497287103809, 0.445532219028312, 0.446566409066067, + 0.447599858279950, 0.448632567730552, 0.449664538476192, 0.450695771572915, + 0.451726268074506, 0.452756029032494, 0.453785055496155, 0.454813348512524, + 0.455840909126398, 0.456867738380343, 0.457893837314700, 0.458919206967592, + 0.459943848374931, 0.460967762570422, 0.461990950585571, 0.463013413449693, + 0.464035152189912, 0.465056167831175, 0.466076461396253, 0.467096033905747, + 0.468114886378099, 0.469133019829591, 0.470150435274359, 0.471167133724392, + 0.472183116189541, 0.473198383677527, 0.474212937193944, 0.475226777742266, + 0.476239906323851, 0.477252323937953, 0.478264031581720, 0.479275030250205, + 0.480285320936372, 0.481294904631098, 0.482303782323183, 0.483311954999353, + 0.484319423644267, 0.485326189240524, 0.486332252768664, 0.487337615207182, + 0.488342277532524, 0.489346240719100, 0.490349505739287, 0.491352073563435, + 0.492353945159870, 0.493355121494907, 0.494355603532845, 0.495355392235982, + 0.496354488564616, 0.497352893477049, 0.498350607929600, 0.499347632876599, + 0.500343969270403, 0.501339618061397, 0.502334580197997, 0.503328856626662, + 0.504322448291891, 0.505315356136237, 0.506307581100306, 0.507299124122766, + 0.508289986140348, 0.509280168087859, 0.510269670898178, 0.511258495502268, + 0.512246642829179, 0.513234113806053, 0.514220909358129, 0.515207030408751, + 0.516192477879367, 0.517177252689541, 0.518161355756956, 0.519144787997414, + 0.520127550324851, 0.521109643651332, 0.522091068887064, 0.523071826940395, + 0.524051918717823, 0.525031345124000, 0.526010107061737, 0.526988205432007, + 0.527965641133954, 0.528942415064895, 0.529918528120324, 0.530893981193921, + 0.531868775177554, 0.532842910961282, 0.533816389433366, 0.534789211480267, + 0.535761377986656, 0.536732889835414, 0.537703747907644, 0.538673953082668, + 0.539643506238036, 0.540612408249530, 0.541580659991169, 0.542548262335212, + 0.543515216152167, 0.544481522310791, 0.545447181678094, 0.546412195119352, + 0.547376563498101, 0.548340287676148, 0.549303368513575, 0.550265806868740, + 0.551227603598288, 0.552188759557150, 0.553149275598548, 0.554109152574003, + 0.555068391333337, 0.556026992724677, 0.556984957594463, 0.557942286787447, + 0.558898981146702, 0.559855041513625, 0.560810468727941, 0.561765263627707, + 0.562719427049319, 0.563672959827513, 0.564625862795372, 0.565578136784329, + 0.566529782624171, 0.567480801143044, 0.568431193167460, 0.569380959522294, + 0.570330101030798, 0.571278618514596, 0.572226512793695, 0.573173784686486, + 0.574120435009748, 0.575066464578656, 0.576011874206780, 0.576956664706092, + 0.577900836886970, 0.578844391558203, 0.579787329526992, 0.580729651598958, + 0.581671358578144, 0.582612451267020, 0.583552930466485, 0.584492796975875, + 0.585432051592962, 0.586370695113965, 0.587308728333545, 0.588246152044817, + 0.589182967039351, 0.590119174107175, 0.591054774036780, 0.591989767615125, + 0.592924155627638, 0.593857938858223, 0.594791118089265, 0.595723694101627, + 0.596655667674663, 0.597587039586216, 0.598517810612622, 0.599447981528719, + 0.600377553107844, 0.601306526121841, 0.602234901341064, 0.603162679534382, + 0.604089861469180, 0.605016447911364, 0.605942439625368, 0.606867837374152, + 0.607792641919210, 0.608716854020573, 0.609640474436812, 0.610563503925040, + 0.611485943240922, 0.612407793138670, 0.613329054371054, 0.614249727689401, + 0.615169813843603, 0.616089313582115, 0.617008227651965, 0.617926556798751, + 0.618844301766652, 0.619761463298424, 0.620678042135410, 0.621594039017540, + 0.622509454683335, 0.623424289869911, 0.624338545312985, 0.625252221746873, + 0.626165319904499, 0.627077840517394, 0.627989784315704, 0.628901152028190, + 0.629811944382234, 0.630722162103839, 0.631631805917638, 0.632540876546891, + 0.633449374713493, 0.634357301137976, 0.635264656539513, 0.636171441635921, + 0.637077657143663, 0.637983303777853, 0.638888382252261, 0.639792893279312, + 0.640696837570094, 0.641600215834357, 0.642503028780520, 0.643405277115674, + 0.644306961545581, 0.645208082774684, 0.646108641506103, 0.647008638441647, + 0.647908074281808, 0.648806949725770, 0.649705265471412, 0.650603022215310, + 0.651500220652738, 0.652396861477678, 0.653292945382815, 0.654188473059545, + 0.655083445197979, 0.655977862486942, 0.656871725613981, 0.657765035265364, + 0.658657792126085, 0.659549996879870, 0.660441650209173, 0.661332752795187, + 0.662223305317840, 0.663113308455806, 0.664002762886501, 0.664891669286088, + 0.665780028329483, 0.666667840690356, 0.667555107041132, 0.668441828052998, + 0.669328004395903, 0.670213636738564, 0.671098725748465, 0.671983272091864, + 0.672867276433793, 0.673750739438063, 0.674633661767266, 0.675516044082778, + 0.676397887044763, 0.677279191312175, 0.678159957542760, 0.679040186393061, + 0.679919878518420, 0.680799034572981, 0.681677655209692, 0.682555741080310, + 0.683433292835402, 0.684310311124349, 0.685186796595348, 0.686062749895414, + 0.686938171670387, 0.687813062564931, 0.688687423222536, 0.689561254285525, + 0.690434556395054, 0.691307330191115, 0.692179576312539, 0.693051295396999, + 0.693922488081015, 0.694793154999950, 0.695663296788022, 0.696532914078300, + 0.697402007502708, 0.698270577692031, 0.699138625275914, 0.700006150882866, + 0.700873155140263, 0.701739638674351, 0.702605602110248, 0.703471046071947, + 0.704335971182319, 0.705200378063116, 0.706064267334970, 0.706927639617403, + 0.707790495528823, 0.708652835686530, 0.709514660706716, 0.710375971204471, + 0.711236767793784, 0.712097051087546, 0.712956821697550, 0.713816080234498, + 0.714674827308002, 0.715533063526583, 0.716390789497679, 0.717248005827646, + 0.718104713121757, 0.718960911984210, 0.719816603018127, 0.720671786825556, + 0.721526464007477, 0.722380635163802, 0.723234300893377, 0.724087461793988, + 0.724940118462359, 0.725792271494157, 0.726643921483994, 0.727495069025431, + 0.728345714710977, 0.729195859132094, 0.730045502879201, 0.730894646541672, + 0.731743290707842, 0.732591435965008, 0.733439082899433, 0.734286232096346, + 0.735132884139946, 0.735979039613404, 0.736824699098865, 0.737669863177453, + 0.738514532429268, 0.739358707433394, 0.740202388767900, 0.741045577009838, + 0.741888272735251, 0.742730476519174, 0.743572188935634, 0.744413410557655, + 0.745254141957257, 0.746094383705463, 0.746934136372297, 0.747773400526791, + 0.748612176736981, 0.749450465569916, 0.750288267591654, 0.751125583367269, + 0.751962413460854, 0.752798758435516, 0.753634618853387, 0.754469995275621, + 0.755304888262399, 0.756139298372928, 0.756973226165448, 0.757806672197228, + 0.758639637024576, 0.759472121202833, 0.760304125286382, 0.761135649828646, + 0.761966695382092, 0.762797262498232, 0.763627351727628, 0.764456963619890, + 0.765286098723682, 0.766114757586723, 0.766942940755785, 0.767770648776705, + 0.768597882194375, 0.769424641552754, 0.770250927394865, 0.771076740262799, + 0.771902080697716, 0.772726949239850, 0.773551346428504, 0.774375272802063, + 0.775198728897986, 0.776021715252813, 0.776844232402167, 0.777666280880755, + 0.778487861222371, 0.779308973959898, 0.780129619625307, 0.780949798749665, + 0.781769511863131, 0.782588759494964, 0.783407542173518, 0.784225860426252, + 0.785043714779724, 0.785861105759600, 0.786678033890652, 0.787494499696761, + 0.788310503700919, 0.789126046425230, 0.789941128390916, 0.790755750118313, + 0.791569912126878, 0.792383614935189, 0.793196859060945, 0.794009645020972, + 0.794821973331222, 0.795633844506778, 0.796445259061850, 0.797256217509785, + 0.798066720363063, 0.798876768133299, 0.799686361331250, 0.800495500466812, + 0.801304186049023, 0.802112418586066, 0.802920198585270, 0.803727526553114, + 0.804534402995225, 0.805340828416384, 0.806146803320525, 0.806952328210736, + 0.807757403589267, 0.808562029957525, 0.809366207816078, 0.810169937664658, + 0.810973220002164, 0.811776055326660, 0.812578444135380, 0.813380386924727, + 0.814181884190280, 0.814982936426790, 0.815783544128185, 0.816583707787570, + 0.817383427897233, 0.818182704948640, 0.818981539432443, 0.819779931838480, + 0.820577882655774, 0.821375392372539, 0.822172461476178, 0.822969090453287, + 0.823765279789659, 0.824561029970280, 0.825356341479334, 0.826151214800207, + 0.826945650415485, 0.827739648806957, 0.828533210455617, 0.829326335841667, + 0.830119025444515, 0.830911279742782, 0.831703099214300, 0.832494484336112, + 0.833285435584481, 0.834075953434884, 0.834866038362018, 0.835655690839800, + 0.836444911341368, 0.837233700339087, 0.838022058304546, 0.838809985708559, + 0.839597483021174, 0.840384550711666, 0.841171189248543, 0.841957399099547, + 0.842743180731658, 0.843528534611089, 0.844313461203296, 0.845097960972975, + 0.845882034384061, 0.846665681899738, 0.847448903982432, 0.848231701093818, + 0.849014073694819, 0.849796022245609, 0.850577547205614, 0.851358649033513, + 0.852139328187243, 0.852919585123995, 0.853699420300221, 0.854478834171630, + 0.855257827193196, 0.856036399819156, 0.856814552503010, 0.857592285697526, + 0.858369599854740, 0.859146495425959, 0.859922972861758, 0.860699032611988, + 0.861474675125773, 0.862249900851513, 0.863024710236886, 0.863799103728850, + 0.864573081773641, 0.865346644816780, 0.866119793303070, 0.866892527676600, + 0.867664848380745, 0.868436755858169, 0.869208250550826, 0.869979332899962, + 0.870750003346114, 0.871520262329114, 0.872290110288090, 0.873059547661470, + 0.873828574886976, 0.874597192401634, 0.875365400641771, 0.876133200043017, + 0.876900591040306, 0.877667574067881, 0.878434149559290, 0.879200317947393, + 0.879966079664357, 0.880731435141664, 0.881496384810110, 0.882260929099804, + 0.883025068440173, 0.883788803259962, 0.884552133987234, 0.885315061049376, + 0.886077584873094, 0.886839705884419, 0.887601424508708, 0.888362741170644, + 0.889123656294237, 0.889884170302829, 0.890644283619089, 0.891403996665022, + 0.892163309861966, 0.892922223630591, 0.893680738390908, 0.894438854562262, + 0.895196572563340, 0.895953892812168, 0.896710815726115, 0.897467341721893, + 0.898223471215558, 0.898979204622514, 0.899734542357511, 0.900489484834649, + 0.901244032467376, 0.901998185668496, 0.902751944850161, 0.903505310423880, + 0.904258282800518, 0.905010862390296, 0.905763049602793, 0.906514844846950, + 0.907266248531065, 0.908017261062803, 0.908767882849189, 0.909518114296615, + 0.910267955810839, 0.911017407796985, 0.911766470659550, 0.912515144802397, + 0.913263430628762, 0.914011328541254, 0.914758838941858, 0.915505962231931, + 0.916252698812210, 0.916999049082807, 0.917745013443216, 0.918490592292311, + 0.919235786028347, 0.919980595048962, 0.920725019751180, 0.921469060531410, + 0.922212717785448, 0.922955991908478, 0.923698883295072, 0.924441392339197, + 0.925183519434208, 0.925925264972856, 0.926666629347283, 0.927407612949032, + 0.928148216169037, 0.928888439397636, 0.929628283024562, 0.930367747438952, + 0.931106833029342, 0.931845540183673, 0.932583869289291, 0.933321820732945, + 0.934059394900794, 0.934796592178403, 0.935533412950747, 0.936269857602210, + 0.937005926516589, 0.937741620077096, 0.938476938666352, 0.939211882666397, + 0.939946452458687, 0.940680648424094, 0.941414470942911, 0.942147920394849, + 0.942880997159041, 0.943613701614043, 0.944346034137834, 0.945077995107817, + 0.945809584900821, 0.946540803893103, 0.947271652460349, 0.948002130977671, + 0.948732239819614, 0.949461979360154, 0.950191349972701, 0.950920352030097, + 0.951648985904620, 0.952377251967984, 0.953105150591341, 0.953832682145281, + 0.954559846999833, 0.955286645524468, 0.956013078088099, 0.956739145059080, + 0.957464846805211, 0.958190183693738, 0.958915156091350, 0.959639764364186, + 0.960364008877834, 0.961087889997331, 0.961811408087163, 0.962534563511272, + 0.963257356633048, 0.963979787815339, 0.964701857420447, 0.965423565810129, + 0.966144913345602, 0.966865900387539, 0.967586527296073, 0.968306794430798, + 0.969026702150771, 0.969746250814509, 0.970465440779995, 0.971184272404677, + 0.971902746045467, 0.972620862058745, 0.973338620800360, 0.974056022625630, + 0.974773067889342, 0.975489756945754, 0.976206090148598, 0.976922067851080, + 0.977637690405876, 0.978352958165143, 0.979067871480510, 0.979782430703087, + 0.980496636183459, 0.981210488271695, 0.981923987317340, 0.982637133669424, + 0.983349927676458, 0.984062369686437, 0.984774460046841, 0.985486199104635, + 0.986197587206273, 0.986908624697693, 0.987619311924326, 0.988329649231088, + 0.989039636962390, 0.989749275462133, 0.990458565073711, 0.991167506140010, + 0.991876099003415, 0.992584344005802, 0.993292241488548, 0.993999791792523, + 0.994706995258101, 0.995413852225151, 0.996120363033046, 0.996826528020659, + 0.997532347526366, 0.998237821888046, 0.998942951443085, 0.999647736528371, +}; -// Force initialization of the log_table. -bool ThreadHeapSampler::_log_table_initialized = init_log_table(); +#ifndef PRODUCT +static double log_table_value(int i) { + return (log(1.0 + static_cast(i + 0.5) / FastLogCount) / log(2.0)); +} + +// Ensure initialization checks only happen once during bootstrap +static volatile bool log_table_checked = false; -bool ThreadHeapSampler::init_log_table() { - for (int i = 0; i < (1 << FastLogNumBits); i++) { - _log_table[i] = (log(1.0 + static_cast(i+0.5) / (1 << FastLogNumBits)) - / log(2.0)); +// Sanity check all log_table values or print it out if running +// -Xlog:heapsampling+generate::none +static void verify_or_generate_log_table() { + log_table_checked = true; + assert(is_power_of_2(FastLogCount) && FastLogCount >= 4, "table size should be power of two and at least 4"); + if (log_is_enabled(Info,heapsampling,generate)) { + log_info(heapsampling,generate)("FastLogCount = %d", FastLogCount); + log_info(heapsampling,generate)("static const double log_table[FastLogCount] = {"); + int i = 0; + for (; i < FastLogCount; i += 4) { + double v1 = log_table_value(i); + double v2 = log_table_value(i + 1); + double v3 = log_table_value(i + 2); + double v4 = log_table_value(i + 3); + log_info(heapsampling,generate)(" %.15f, %.15f, %.15f, %.15f,", v1, v2, v3, v4); + } + log_info(heapsampling,generate)("};"); + assert(i == FastLogCount, "post-loop invariant"); + } else { + // sanity check log_table - disabled when generating + for (int i = 0; i < FastLogCount; i++) { + assert(abs(log_table_value(i) - log_table[i]) < 0.0001, + "log_table deviates too much at index: %d %.15f %.15f", + i, log_table_value(i), log_table[i]); + } } - return true; } +#endif // Returns the next prng value. // pRNG is: aX+b mod c with a = 0x5DEECE66D, b = 0xB, c = 1<<48 @@ -71,9 +359,7 @@ double ThreadHeapSampler::fast_log2(const double& d) { assert(FastLogNumBits <= 20, "FastLogNumBits should be less than 20."); const uint32_t y = x_high >> (20 - FastLogNumBits) & FastLogMask; const int32_t exponent = ((x_high >> 20) & 0x7FF) - 1023; - - assert(_log_table_initialized, "log table should be initialized"); - return exponent + _log_table[y]; + return exponent + log_table[y]; } // Generates a geometric variable with the specified mean (512K by default). @@ -113,6 +399,11 @@ void ThreadHeapSampler::pick_next_geometric_sample() { } void ThreadHeapSampler::pick_next_sample(size_t overflowed_bytes) { +#ifndef PRODUCT + if (!log_table_checked) { + verify_or_generate_log_table(); + } +#endif // Explicitly test if the sampling interval is 0, return 0 to sample every // allocation. if (get_sampling_interval() == 0) { diff --git a/src/hotspot/share/runtime/threadHeapSampler.hpp b/src/hotspot/share/runtime/threadHeapSampler.hpp index 95dd83d0acd..220998c26f7 100644 --- a/src/hotspot/share/runtime/threadHeapSampler.hpp +++ b/src/hotspot/share/runtime/threadHeapSampler.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, Google and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -30,23 +30,16 @@ class ThreadHeapSampler { private: - // Statics for the fast log - static const int FastLogNumBits = 10; - static const int FastLogMask = (1 << FastLogNumBits) - 1; - size_t _bytes_until_sample; // Cheap random number generator static uint64_t _rnd; - static bool _log_table_initialized; - static double _log_table[1< KlassHashtableEntry; declare_integer_type(AccessFlags) /* FIXME: wrong type (not integer) */\ declare_toplevel_type(address) /* FIXME: should this be an integer type? */\ declare_integer_type(BasicType) /* FIXME: wrong type (not integer) */ \ - declare_toplevel_type(BreakpointInfo) \ - declare_toplevel_type(BreakpointInfo*) \ + JVMTI_ONLY(declare_toplevel_type(BreakpointInfo)) \ + JVMTI_ONLY(declare_toplevel_type(BreakpointInfo*)) \ declare_toplevel_type(CodeBlob*) \ declare_toplevel_type(RuntimeBlob*) \ declare_toplevel_type(CompressedWriteStream*) \ @@ -2603,17 +2603,17 @@ typedef HashtableEntry KlassHashtableEntry; /******************************/ \ /* -XX flags (value origin) */ \ /******************************/ \ - declare_constant(JVMFlag::DEFAULT) \ - declare_constant(JVMFlag::COMMAND_LINE) \ - declare_constant(JVMFlag::ENVIRON_VAR) \ - declare_constant(JVMFlag::CONFIG_FILE) \ - declare_constant(JVMFlag::MANAGEMENT) \ - declare_constant(JVMFlag::ERGONOMIC) \ - declare_constant(JVMFlag::ATTACH_ON_DEMAND) \ - declare_constant(JVMFlag::INTERNAL) \ - declare_constant(JVMFlag::JIMAGE_RESOURCE) \ + declare_constant(JVMFlagOrigin::DEFAULT) \ + declare_constant(JVMFlagOrigin::COMMAND_LINE) \ + declare_constant(JVMFlagOrigin::ENVIRON_VAR) \ + declare_constant(JVMFlagOrigin::CONFIG_FILE) \ + declare_constant(JVMFlagOrigin::MANAGEMENT) \ + declare_constant(JVMFlagOrigin::ERGONOMIC) \ + declare_constant(JVMFlagOrigin::ATTACH_ON_DEMAND) \ + declare_constant(JVMFlagOrigin::INTERNAL) \ + declare_constant(JVMFlagOrigin::JIMAGE_RESOURCE) \ declare_constant(JVMFlag::VALUE_ORIGIN_MASK) \ - declare_constant(JVMFlag::ORIG_COMMAND_LINE) + declare_constant(JVMFlag::WAS_SET_ON_COMMAND_LINE) //-------------------------------------------------------------------------------- // VM_LONG_CONSTANTS diff --git a/src/hotspot/share/services/attachListener.cpp b/src/hotspot/share/services/attachListener.cpp index d8ab4dbcd9c..7a2d1024893 100644 --- a/src/hotspot/share/services/attachListener.cpp +++ b/src/hotspot/share/services/attachListener.cpp @@ -303,7 +303,7 @@ static jint set_flag(AttachOperation* op, outputStream* out) { FormatBuffer<80> err_msg("%s", ""); - int ret = WriteableFlags::set_flag(op->arg(0), op->arg(1), JVMFlag::ATTACH_ON_DEMAND, err_msg); + int ret = WriteableFlags::set_flag(op->arg(0), op->arg(1), JVMFlagOrigin::ATTACH_ON_DEMAND, err_msg); if (ret != JVMFlag::SUCCESS) { if (ret == JVMFlag::NON_WRITABLE) { // if the flag is not manageable try to change it through diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index d642e4489e5..1f0c69c0012 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp @@ -111,6 +111,9 @@ void DCmdRegistrant::register_dcmds(){ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); +#ifdef LINUX + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); +#endif // LINUX DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); @@ -276,7 +279,7 @@ void SetVMFlagDCmd::execute(DCmdSource source, TRAPS) { } FormatBuffer<80> err_msg("%s", ""); - int ret = WriteableFlags::set_flag(_flag.value(), val, JVMFlag::MANAGEMENT, err_msg); + int ret = WriteableFlags::set_flag(_flag.value(), val, JVMFlagOrigin::MANAGEMENT, err_msg); if (ret != JVMFlag::SUCCESS) { output()->print_cr("%s", err_msg.buffer()); @@ -301,6 +304,7 @@ void JVMTIDataDumpDCmd::execute(DCmdSource source, TRAPS) { } #if INCLUDE_SERVICES +#if INCLUDE_JVMTI JVMTIAgentLoadDCmd::JVMTIAgentLoadDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), _libpath("library path", "Absolute path of the JVMTI agent to load.", @@ -360,6 +364,7 @@ int JVMTIAgentLoadDCmd::num_arguments() { return 0; } } +#endif // INCLUDE_JVMTI #endif // INCLUDE_SERVICES void PrintSystemPropertiesDCmd::execute(DCmdSource source, TRAPS) { @@ -893,6 +898,12 @@ void CodeCacheDCmd::execute(DCmdSource source, TRAPS) { CodeCache::print_layout(output()); } +#ifdef LINUX +void PerfMapDCmd::execute(DCmdSource source, TRAPS) { + CodeCache::write_perf_map(); +} +#endif // LINUX + //---< BEGIN >--- CodeHeap State Analytics. CodeHeapAnalyticsDCmd::CodeHeapAnalyticsDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), diff --git a/src/hotspot/share/services/diagnosticCommand.hpp b/src/hotspot/share/services/diagnosticCommand.hpp index 4e6bb507304..6587c046ad1 100644 --- a/src/hotspot/share/services/diagnosticCommand.hpp +++ b/src/hotspot/share/services/diagnosticCommand.hpp @@ -603,6 +603,29 @@ class CompileQueueDCmd : public DCmd { virtual void execute(DCmdSource source, TRAPS); }; +#ifdef LINUX +class PerfMapDCmd : public DCmd { +public: + PerfMapDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} + static const char* name() { + return "Compiler.perfmap"; + } + static const char* description() { + return "Write map file for Linux perf tool."; + } + static const char* impact() { + return "Low"; + } + static const JavaPermission permission() { + JavaPermission p = {"java.lang.management.ManagementPermission", + "monitor", NULL}; + return p; + } + static int num_arguments() { return 0; } + virtual void execute(DCmdSource source, TRAPS); +}; +#endif // LINUX + class CodeListDCmd : public DCmd { public: CodeListDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} @@ -624,7 +647,6 @@ class CodeListDCmd : public DCmd { virtual void execute(DCmdSource source, TRAPS); }; - class CodeCacheDCmd : public DCmd { public: CodeCacheDCmd(outputStream* output, bool heap) : DCmd(output, heap) {} diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp index 92f086619d4..65a8481ad53 100644 --- a/src/hotspot/share/services/management.cpp +++ b/src/hotspot/share/services/management.cpp @@ -1474,25 +1474,25 @@ bool add_global_entry(Handle name, jmmVMGlobal *global, JVMFlag *flag, TRAPS) { global->writeable = flag->is_writeable(); global->external = flag->is_external(); switch (flag->get_origin()) { - case JVMFlag::DEFAULT: + case JVMFlagOrigin::DEFAULT: global->origin = JMM_VMGLOBAL_ORIGIN_DEFAULT; break; - case JVMFlag::COMMAND_LINE: + case JVMFlagOrigin::COMMAND_LINE: global->origin = JMM_VMGLOBAL_ORIGIN_COMMAND_LINE; break; - case JVMFlag::ENVIRON_VAR: + case JVMFlagOrigin::ENVIRON_VAR: global->origin = JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR; break; - case JVMFlag::CONFIG_FILE: + case JVMFlagOrigin::CONFIG_FILE: global->origin = JMM_VMGLOBAL_ORIGIN_CONFIG_FILE; break; - case JVMFlag::MANAGEMENT: + case JVMFlagOrigin::MANAGEMENT: global->origin = JMM_VMGLOBAL_ORIGIN_MANAGEMENT; break; - case JVMFlag::ERGONOMIC: + case JVMFlagOrigin::ERGONOMIC: global->origin = JMM_VMGLOBAL_ORIGIN_ERGONOMIC; break; - case JVMFlag::ATTACH_ON_DEMAND: + case JVMFlagOrigin::ATTACH_ON_DEMAND: global->origin = JMM_VMGLOBAL_ORIGIN_ATTACH_ON_DEMAND; break; default: @@ -1584,7 +1584,7 @@ JVM_ENTRY(void, jmm_SetVMGlobal(JNIEnv *env, jstring flag_name, jvalue new_value char* name = java_lang_String::as_utf8_string(fn); FormatBuffer<80> error_msg("%s", ""); - int succeed = WriteableFlags::set_flag(name, new_value, JVMFlag::MANAGEMENT, error_msg); + int succeed = WriteableFlags::set_flag(name, new_value, JVMFlagOrigin::MANAGEMENT, error_msg); if (succeed != JVMFlag::SUCCESS) { if (succeed == JVMFlag::MISSING_VALUE) { diff --git a/src/hotspot/share/services/writeableFlags.cpp b/src/hotspot/share/services/writeableFlags.cpp index e9d0e929ab5..dc5f62b4bf8 100644 --- a/src/hotspot/share/services/writeableFlags.cpp +++ b/src/hotspot/share/services/writeableFlags.cpp @@ -97,7 +97,7 @@ static void print_flag_error_message_if_needed(JVMFlag::Error error, const JVMFl } // set a boolean global flag -JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { if ((strcasecmp(arg, "true") == 0) || (*arg == '1' && *(arg + 1) == 0)) { return set_bool_flag(name, true, origin, err_msg); } else if ((strcasecmp(arg, "false") == 0) || (*arg == '0' && *(arg + 1) == 0)) { @@ -107,7 +107,7 @@ JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, const char* arg, return JVMFlag::WRONG_FORMAT; } -JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, bool value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, bool value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag::Error err = JVMFlagAccess::boolAtPut(flag, &value, origin); print_flag_error_message_if_needed(err, flag, err_msg); @@ -115,7 +115,7 @@ JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, bool value, JVMFl } // set a int global flag -JVMFlag::Error WriteableFlags::set_int_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_int_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { int value; if (sscanf(arg, "%d", &value) == 1) { @@ -125,7 +125,7 @@ JVMFlag::Error WriteableFlags::set_int_flag(const char* name, const char* arg, J return JVMFlag::WRONG_FORMAT; } -JVMFlag::Error WriteableFlags::set_int_flag(const char* name, int value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_int_flag(const char* name, int value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag::Error err = JVMFlagAccess::intAtPut(flag, &value, origin); print_flag_error_message_if_needed(err, flag, err_msg); @@ -133,7 +133,7 @@ JVMFlag::Error WriteableFlags::set_int_flag(const char* name, int value, JVMFlag } // set a uint global flag -JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { uint value; if (sscanf(arg, "%u", &value) == 1) { @@ -143,7 +143,7 @@ JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, const char* arg, return JVMFlag::WRONG_FORMAT; } -JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, uint value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, uint value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag::Error err = JVMFlagAccess::uintAtPut(flag, &value, origin); print_flag_error_message_if_needed(err, flag, err_msg); @@ -151,7 +151,7 @@ JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, uint value, JVMFl } // set a intx global flag -JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { intx value; if (sscanf(arg, INTX_FORMAT, &value) == 1) { @@ -161,7 +161,7 @@ JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, const char* arg, return JVMFlag::WRONG_FORMAT; } -JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, intx value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, intx value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag::Error err = JVMFlagAccess::intxAtPut(flag, &value, origin); print_flag_error_message_if_needed(err, flag, err_msg); @@ -169,7 +169,7 @@ JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, intx value, JVMFl } // set a uintx global flag -JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { uintx value; if (sscanf(arg, UINTX_FORMAT, &value) == 1) { @@ -179,7 +179,7 @@ JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, const char* arg, return JVMFlag::WRONG_FORMAT; } -JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, uintx value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, uintx value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag::Error err = JVMFlagAccess::uintxAtPut(flag, &value, origin); print_flag_error_message_if_needed(err, flag, err_msg); @@ -187,7 +187,7 @@ JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, uintx value, JVM } // set a uint64_t global flag -JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { uint64_t value; if (sscanf(arg, UINT64_FORMAT, &value) == 1) { @@ -197,7 +197,7 @@ JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, const char* a return JVMFlag::WRONG_FORMAT; } -JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, uint64_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, uint64_t value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag::Error err = JVMFlagAccess::uint64_tAtPut(flag, &value, origin); print_flag_error_message_if_needed(err, flag, err_msg); @@ -205,7 +205,7 @@ JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, uint64_t valu } // set a size_t global flag -JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { size_t value; if (sscanf(arg, SIZE_FORMAT, &value) == 1) { @@ -215,7 +215,7 @@ JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, const char* arg return JVMFlag::WRONG_FORMAT; } -JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, size_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, size_t value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag::Error err = JVMFlagAccess::size_tAtPut(flag, &value, origin); print_flag_error_message_if_needed(err, flag, err_msg); @@ -223,7 +223,7 @@ JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, size_t value, J } // set a double global flag -JVMFlag::Error WriteableFlags::set_double_flag(const char* name, const char* arg, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_double_flag(const char* name, const char* arg, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { double value; if (sscanf(arg, "%lf", &value) == 1) { @@ -233,7 +233,7 @@ JVMFlag::Error WriteableFlags::set_double_flag(const char* name, const char* arg return JVMFlag::WRONG_FORMAT; } -JVMFlag::Error WriteableFlags::set_double_flag(const char* name, double value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_double_flag(const char* name, double value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag::Error err = JVMFlagAccess::doubleAtPut(flag, &value, origin); print_flag_error_message_if_needed(err, flag, err_msg); @@ -241,7 +241,7 @@ JVMFlag::Error WriteableFlags::set_double_flag(const char* name, double value, J } // set a string global flag using value from AttachOperation -JVMFlag::Error WriteableFlags::set_ccstr_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_ccstr_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { JVMFlag* flag = JVMFlag::find_flag(name); JVMFlag::Error err = JVMFlagAccess::ccstrAtPut(flag, &value, origin); print_flag_error_message_if_needed(err, flag, err_msg); @@ -253,7 +253,7 @@ JVMFlag::Error WriteableFlags::set_ccstr_flag(const char* name, const char* valu * - return status is one of the WriteableFlags::err enum values * - an eventual error message will be generated to the provided err_msg buffer */ -JVMFlag::Error WriteableFlags::set_flag(const char* flag_name, const char* flag_value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_flag(const char* flag_name, const char* flag_value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { return set_flag(flag_name, &flag_value, set_flag_from_char, origin, err_msg); } @@ -262,12 +262,12 @@ JVMFlag::Error WriteableFlags::set_flag(const char* flag_name, const char* flag_ * - return status is one of the WriteableFlags::err enum values * - an eventual error message will be generated to the provided err_msg buffer */ -JVMFlag::Error WriteableFlags::set_flag(const char* flag_name, jvalue flag_value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_flag(const char* flag_name, jvalue flag_value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { return set_flag(flag_name, &flag_value, set_flag_from_jvalue, origin, err_msg); } // a writeable flag setter accepting either 'jvalue' or 'char *' values -JVMFlag::Error WriteableFlags::set_flag(const char* name, const void* value, JVMFlag::Error(*setter)(JVMFlag*,const void*,JVMFlag::Flags,FormatBuffer<80>&), JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_flag(const char* name, const void* value, JVMFlag::Error(*setter)(JVMFlag*,const void*,JVMFlagOrigin,FormatBuffer<80>&), JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { if (name == NULL) { err_msg.print("flag name is missing"); return JVMFlag::MISSING_NAME; @@ -293,7 +293,7 @@ JVMFlag::Error WriteableFlags::set_flag(const char* name, const void* value, JVM } // a writeable flag setter accepting 'char *' values -JVMFlag::Error WriteableFlags::set_flag_from_char(JVMFlag* f, const void* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) { +JVMFlag::Error WriteableFlags::set_flag_from_char(JVMFlag* f, const void* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { char* flag_value = *(char**)value; if (flag_value == NULL) { err_msg.print("flag value is missing"); @@ -324,7 +324,7 @@ JVMFlag::Error WriteableFlags::set_flag_from_char(JVMFlag* f, const void* value, } // a writeable flag setter accepting 'jvalue' values -JVMFlag::Error WriteableFlags::set_flag_from_jvalue(JVMFlag* f, const void* value, JVMFlag::Flags origin, +JVMFlag::Error WriteableFlags::set_flag_from_jvalue(JVMFlag* f, const void* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg) { jvalue new_value = *(jvalue*)value; if (f->is_bool()) { diff --git a/src/hotspot/share/services/writeableFlags.hpp b/src/hotspot/share/services/writeableFlags.hpp index a49fde390fe..1488d1c7cfd 100644 --- a/src/hotspot/share/services/writeableFlags.hpp +++ b/src/hotspot/share/services/writeableFlags.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,46 +32,46 @@ class WriteableFlags : AllStatic { private: // a writeable flag setter accepting either 'jvalue' or 'char *' values - static JVMFlag::Error set_flag(const char* name, const void* value, JVMFlag::Error(*setter)(JVMFlag*, const void*, JVMFlag::Flags, FormatBuffer<80>&), JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_flag(const char* name, const void* value, JVMFlag::Error(*setter)(JVMFlag*, const void*, JVMFlagOrigin, FormatBuffer<80>&), JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // a writeable flag setter accepting 'char *' values - static JVMFlag::Error set_flag_from_char(JVMFlag* f, const void* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_flag_from_char(JVMFlag* f, const void* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // a writeable flag setter accepting 'jvalue' values - static JVMFlag::Error set_flag_from_jvalue(JVMFlag* f, const void* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_flag_from_jvalue(JVMFlag* f, const void* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a boolean global flag - static JVMFlag::Error set_bool_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_bool_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a int global flag - static JVMFlag::Error set_int_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_int_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a uint global flag - static JVMFlag::Error set_uint_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_uint_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a intx global flag - static JVMFlag::Error set_intx_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_intx_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a uintx global flag - static JVMFlag::Error set_uintx_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_uintx_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a uint64_t global flag - static JVMFlag::Error set_uint64_t_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_uint64_t_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a size_t global flag using value from AttachOperation - static JVMFlag::Error set_size_t_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_size_t_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a double global flag using value from AttachOperation - static JVMFlag::Error set_double_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_double_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a boolean global flag - static JVMFlag::Error set_bool_flag(const char* name, bool value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_bool_flag(const char* name, bool value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a int global flag - static JVMFlag::Error set_int_flag(const char* name, int value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_int_flag(const char* name, int value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a uint global flag - static JVMFlag::Error set_uint_flag(const char* name, uint value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_uint_flag(const char* name, uint value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a intx global flag - static JVMFlag::Error set_intx_flag(const char* name, intx value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_intx_flag(const char* name, intx value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a uintx global flag - static JVMFlag::Error set_uintx_flag(const char* name, uintx value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_uintx_flag(const char* name, uintx value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a uint64_t global flag - static JVMFlag::Error set_uint64_t_flag(const char* name, uint64_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_uint64_t_flag(const char* name, uint64_t value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a size_t global flag using value from AttachOperation - static JVMFlag::Error set_size_t_flag(const char* name, size_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_size_t_flag(const char* name, size_t value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a double global flag using value from AttachOperation - static JVMFlag::Error set_double_flag(const char* name, double value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_double_flag(const char* name, double value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); // set a string global flag - static JVMFlag::Error set_ccstr_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_ccstr_flag(const char* name, const char* value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); public: /* sets a writeable flag to the provided value @@ -79,14 +79,14 @@ class WriteableFlags : AllStatic { * - return status is one of the WriteableFlags::err enum values * - an eventual error message will be generated to the provided err_msg buffer */ - static JVMFlag::Error set_flag(const char* flag_name, const char* flag_value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_flag(const char* flag_name, const char* flag_value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); /* sets a writeable flag to the provided value * * - return status is one of the WriteableFlags::err enum values * - an eventual error message will be generated to the provided err_msg buffer */ - static JVMFlag::Error set_flag(const char* flag_name, jvalue flag_value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg); + static JVMFlag::Error set_flag(const char* flag_name, jvalue flag_value, JVMFlagOrigin origin, FormatBuffer<80>& err_msg); }; #endif // SHARE_SERVICES_WRITEABLEFLAGS_HPP diff --git a/src/hotspot/share/utilities/enumIterator.hpp b/src/hotspot/share/utilities/enumIterator.hpp index b876531207e..45a1a0fe082 100644 --- a/src/hotspot/share/utilities/enumIterator.hpp +++ b/src/hotspot/share/utilities/enumIterator.hpp @@ -210,6 +210,10 @@ class EnumRange { constexpr Iterator end() const { return Iterator(static_cast(_end)); } + + constexpr size_t size() const { + return static_cast(_end - _start); // _end is exclusive + } }; #endif // SHARE_UTILITIES_ENUMITERATOR_HPP diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index bdc4996c6cb..88540224828 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -446,6 +446,21 @@ inline size_t pointer_delta(const MetaWord* left, const MetaWord* right) { #define CAST_TO_FN_PTR(func_type, value) (reinterpret_cast(value)) #define CAST_FROM_FN_PTR(new_type, func_ptr) ((new_type)((address_word)(func_ptr))) +// In many places we've added C-style casts to silence compiler +// warnings, for example when truncating a size_t to an int when we +// know the size_t is a small struct. Such casts are risky because +// they effectively disable useful compiler warnings. We can make our +// lives safer with this function, which ensures that any cast is +// reversible without loss of information. It doesn't check +// everything: it isn't intended to make sure that pointer types are +// compatible, for example. +template +T2 checked_cast(T1 thing) { + T2 result = static_cast(thing); + assert(static_cast(result) == thing, "must be"); + return result; +} + // Need the correct linkage to call qsort without warnings extern "C" { typedef int (*_sort_Fn)(const void *, const void *); diff --git a/src/hotspot/share/utilities/vmEnums.hpp b/src/hotspot/share/utilities/vmEnums.hpp index 2430c37af8d..bc044e675e8 100644 --- a/src/hotspot/share/utilities/vmEnums.hpp +++ b/src/hotspot/share/utilities/vmEnums.hpp @@ -29,6 +29,7 @@ // you don't use their members directly. This way you don't need to include the // complex header files that have the full definitions of these enums. +enum class JVMFlagOrigin : int; enum JVMFlagsEnum : int; enum class vmSymbolID : int; diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index 4a9ecebbec9..9567eabb54d 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -1321,19 +1321,6 @@ void VMError::report_and_die(Thread* thread, unsigned int sig, address pc, void* report_and_die(thread, sig, pc, siginfo, context, "%s", ""); } -void VMError::report_and_die(const char* message, const char* detail_fmt, ...) -{ - va_list detail_args; - va_start(detail_args, detail_fmt); - report_and_die(INTERNAL_ERROR, message, detail_fmt, detail_args, NULL, NULL, NULL, NULL, NULL, 0, 0); - va_end(detail_args); -} - -void VMError::report_and_die(const char* message) -{ - report_and_die(message, "%s", ""); -} - void VMError::report_and_die(Thread* thread, void* context, const char* filename, int lineno, const char* message, const char* detail_fmt, va_list detail_args) { diff --git a/src/hotspot/share/utilities/vmError.hpp b/src/hotspot/share/utilities/vmError.hpp index 2e7b0c26d72..172ddb52fb8 100644 --- a/src/hotspot/share/utilities/vmError.hpp +++ b/src/hotspot/share/utilities/vmError.hpp @@ -118,7 +118,6 @@ class VMError : public AllStatic { static void report_and_die(Thread* thread, unsigned int sig, address pc, void* siginfo, void* context, const char* detail_fmt, ...) ATTRIBUTE_PRINTF(6, 7); - static void report_and_die(const char* message, const char* detail_fmt, ...) ATTRIBUTE_PRINTF(2, 3); // Timeout handling. // Hook functions for platform dependend functionality: @@ -161,8 +160,6 @@ class VMError : public AllStatic { VMErrorType vm_err_type, const char* detail_fmt, va_list detail_args) ATTRIBUTE_PRINTF(6, 0); - static void report_and_die(const char* message); - // reporting OutOfMemoryError static void report_java_out_of_memory(const char* message); diff --git a/src/java.base/share/classes/java/io/InputStream.java b/src/java.base/share/classes/java/io/InputStream.java index e260e0e1445..df398373b50 100644 --- a/src/java.base/share/classes/java/io/InputStream.java +++ b/src/java.base/share/classes/java/io/InputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -416,6 +416,9 @@ public byte[] readNBytes(int len) throws IOException { if (MAX_BUFFER_SIZE - total < nread) { throw new OutOfMemoryError("Required array size too large"); } + if (nread < buf.length) { + buf = Arrays.copyOfRange(buf, 0, nread); + } total += nread; if (result == null) { result = buf; diff --git a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java index 115f5257907..759848063cb 100644 --- a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java +++ b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java @@ -1028,12 +1028,12 @@ public String substring(int start) { *

An invocation of this method of the form * *

{@code
-     * sb.subSequence(begin, end)}
+ * sb.subSequence(begin, end)} * * behaves in exactly the same way as the invocation * *
{@code
-     * sb.substring(begin, end)}
+ * sb.substring(begin, end)} * * This method is provided so that this class can * implement the {@link CharSequence} interface. diff --git a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java index f138da50b7e..7d7c47c971f 100644 --- a/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java +++ b/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java @@ -28,6 +28,7 @@ import jdk.internal.misc.CDS; import jdk.internal.org.objectweb.asm.*; import sun.invoke.util.BytecodeDescriptor; +import sun.invoke.util.VerifyAccess; import sun.security.action.GetPropertyAction; import sun.security.action.GetBooleanAction; @@ -66,7 +67,6 @@ private static final String DESCR_METHOD_WRITE_REPLACE = "()Ljava/lang/Object;"; private static final String DESCR_METHOD_WRITE_OBJECT = "(Ljava/io/ObjectOutputStream;)V"; private static final String DESCR_METHOD_READ_OBJECT = "(Ljava/io/ObjectInputStream;)V"; - private static final String DESCR_SET_IMPL_METHOD = "(Ljava/lang/invoke/MethodHandle;)V"; private static final String NAME_METHOD_WRITE_REPLACE = "writeReplace"; private static final String NAME_METHOD_READ_OBJECT = "readObject"; @@ -169,8 +169,8 @@ public InnerClassLambdaMetafactory(MethodHandles.Lookup caller, implMethodDesc = implInfo.getMethodType().toMethodDescriptorString(); constructorType = invokedType.changeReturnType(Void.TYPE); lambdaClassName = lambdaClassName(targetClass); - useImplMethodHandle = !implClass.getPackageName().equals(implInfo.getDeclaringClass().getPackageName()) - && !Modifier.isPublic(implInfo.getModifiers()); + useImplMethodHandle = !Modifier.isPublic(implInfo.getModifiers()) && + !VerifyAccess.isSamePackage(implClass, implInfo.getDeclaringClass()); cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); int parameterCount = invokedType.parameterCount(); if (parameterCount > 0) { diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index eab9133db95..0f9e8f6eff9 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -62,6 +62,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import static java.lang.invoke.LambdaForm.BasicType.V_TYPE; import static java.lang.invoke.MethodHandleImpl.Intrinsic; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException; @@ -4768,23 +4769,24 @@ static boolean permuteArgumentChecks(int[] reorder, MethodType newType, MethodTy if (newType.returnType() != oldType.returnType()) throw newIllegalArgumentException("return types do not match", oldType, newType); - if (reorder.length == oldType.parameterCount()) { - int limit = newType.parameterCount(); - boolean bad = false; - for (int j = 0; j < reorder.length; j++) { - int i = reorder[j]; - if (i < 0 || i >= limit) { - bad = true; break; - } - Class src = newType.parameterType(i); - Class dst = oldType.parameterType(j); - if (src != dst) - throw newIllegalArgumentException("parameter types do not match after reorder", - oldType, newType); + if (reorder.length != oldType.parameterCount()) + throw newIllegalArgumentException("old type parameter count and reorder array length do not match", + oldType, Arrays.toString(reorder)); + + int limit = newType.parameterCount(); + for (int j = 0; j < reorder.length; j++) { + int i = reorder[j]; + if (i < 0 || i >= limit) { + throw newIllegalArgumentException("index is out of bounds for new type", + i, newType); } - if (!bad) return true; + Class src = newType.parameterType(i); + Class dst = oldType.parameterType(j); + if (src != dst) + throw newIllegalArgumentException("parameter types do not match after reorder", + oldType, newType); } - throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder)); + return true; } /** @@ -5239,6 +5241,28 @@ public static MethodHandle dropArgumentsToMatch(MethodHandle target, int skip, L return dropArgumentsToMatch(target, skip, newTypes, pos, false); } + /** + * Drop the return value of the target handle (if any). + * The returned method handle will have a {@code void} return type. + * + * @param target the method handle to adapt + * @return a possibly adapted method handle + * @throws NullPointerException if {@code target} is null + * @since 16 + */ + public static MethodHandle dropReturn(MethodHandle target) { + Objects.requireNonNull(target); + MethodType oldType = target.type(); + Class oldReturnType = oldType.returnType(); + if (oldReturnType == void.class) + return target; + MethodType newType = oldType.changeReturnType(void.class); + BoundMethodHandle result = target.rebind(); + LambdaForm lform = result.editor().filterReturnForm(V_TYPE, true); + result = result.copyWith(newType, lform); + return result; + } + /** * Adapts a target method handle by pre-processing * one or more of its arguments, each with its own unary filter function, diff --git a/src/java.base/share/classes/java/lang/module/package-info.java b/src/java.base/share/classes/java/lang/module/package-info.java index 3bf75431bd2..3deaf3ad0a1 100644 --- a/src/java.base/share/classes/java/lang/module/package-info.java +++ b/src/java.base/share/classes/java/lang/module/package-info.java @@ -147,7 +147,7 @@ *

Otherwise, resolution succeeds, and the result of resolution is the * readability graph. * - *

Root modules

+ *

Root modules

* *

The set of root modules at compile-time is usually the set of modules * being compiled. At run-time, the set of root modules is usually the diff --git a/src/java.base/share/classes/java/lang/ref/PhantomReference.java b/src/java.base/share/classes/java/lang/ref/PhantomReference.java index bb7c654fefd..84e176b6e6d 100644 --- a/src/java.base/share/classes/java/lang/ref/PhantomReference.java +++ b/src/java.base/share/classes/java/lang/ref/PhantomReference.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,6 +63,14 @@ public T get() { return null; } + /* Override the implementation of Reference.refersTo. + * Phantom references are weaker than finalization, so the referent + * access needs to be handled differently for garbage collectors that + * do reference processing concurrently. + */ + @Override + native final boolean refersTo0(Object o); + /** * Creates a new phantom reference that refers to the given object and * is registered with the given queue. diff --git a/src/java.base/share/classes/java/lang/ref/Reference.java b/src/java.base/share/classes/java/lang/ref/Reference.java index fe680a54a83..4c119e3d4b9 100644 --- a/src/java.base/share/classes/java/lang/ref/Reference.java +++ b/src/java.base/share/classes/java/lang/ref/Reference.java @@ -325,14 +325,40 @@ public void runFinalization() { * been cleared, either by the program or by the garbage collector, then * this method returns {@code null}. * + * @apiNote + * This method returns a strong reference to the referent. This may cause + * the garbage collector to treat it as strongly reachable until some later + * collection cycle. The {@link #refersTo(Object) refersTo} method can be + * used to avoid such strengthening when testing whether some object is + * the referent of a reference object; that is, use {@code ref.refersTo(obj)} + * rather than {@code ref.get() == obj}. + * * @return The object to which this reference refers, or * {@code null} if this reference object has been cleared + * @see refersTo */ @IntrinsicCandidate public T get() { return this.referent; } + /** + * Tests if the referent of this reference object is {@code obj}. + * Using a {@code null} {@code obj} returns {@code true} if the + * reference object has been cleared. + * + * @param obj the object to compare with this reference object's referent + * @return {@code true} if {@code obj} is the referent of this reference object + * @since 16 + */ + public final boolean refersTo(T obj) { + return refersTo0(obj); + } + + /* Implementation of refersTo(), overridden for phantom references. + */ + native boolean refersTo0(Object o); + /** * Clears this reference object. Invoking this method will not cause this * object to be enqueued. diff --git a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java index c7a09e56232..521eca47fd4 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java @@ -1556,11 +1556,11 @@ public DateTimeFormatterBuilder appendOptional(DateTimeFormatter formatter) { * GGGGG 5 appendText(ChronoField.ERA, TextStyle.NARROW) * * u 1 appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL) - * uu 2 appendValueReduced(ChronoField.YEAR, 2, 2000) + * uu 2 appendValueReduced(ChronoField.YEAR, 2, 2, 2000) * uuu 3 appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL) * u..u 4..n appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD) * y 1 appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL) - * yy 2 appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000) + * yy 2 appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2, 2000) * yyy 3 appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL) * y..y 4..n appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD) * Y 1 append special localized WeekFields element for numeric week-based-year diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index 2a2e3534e18..4c53855abfe 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -1335,18 +1335,6 @@ private final void checkEncoding(ZipCoder zc, byte[] a, int pos, int nlen) throw } } - private static final int hashN(byte[] a, int off, int len) { - int h = 1; - while (len-- > 0) { - h = 31 * h + a[off++]; - } - return h; - } - - private static final int hash_append(int hash, byte b) { - return hash * 31 + b; - } - private static class End { int centot; // 4 bytes long cenlen; // 4 bytes diff --git a/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java b/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java index 40f53990964..33dd332d18c 100644 --- a/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java +++ b/src/java.base/share/classes/jdk/internal/icu/text/BidiBase.java @@ -4590,13 +4590,13 @@ public static void reorderVisually(byte[] levels, } if (0 > objectStart || objects.length <= objectStart) { throw new IllegalArgumentException("Value objectStart " + - levelStart + " is out of range 0 to " + + objectStart + " is out of range 0 to " + (objects.length-1)); } if (0 > count || objects.length < (objectStart+count)) { throw new IllegalArgumentException("Value count " + - levelStart + " is out of range 0 to " + - (objects.length - objectStart)); + count + " is less than zero, or objectStart + count" + + " is beyond objects length " + objects.length); } byte[] reorderLevels = new byte[count]; diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 674ab94d01e..97f2b08e309 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -208,7 +208,7 @@ jdk.jartool, jdk.jfr, jdk.jlink, - jdk.incubator.jpackage; + jdk.jpackage; exports jdk.internal.perf to java.management, jdk.management.agent, diff --git a/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java b/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java index bb42cc1dff3..442860138c5 100644 --- a/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java +++ b/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java @@ -29,15 +29,16 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Base64; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.List; -import java.util.TimeZone; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -1739,19 +1740,8 @@ public long getSize(String path) throws sun.net.ftp.FtpProtocolException, IOExce return -1; } - private static final SimpleDateFormat[] dateFormats; - - static { - String[] formats = { - "yyyyMMddHHmmss.SSS", - "yyyyMMddHHmmss" - }; - dateFormats = new SimpleDateFormat[formats.length]; - for (int i = 0; i < formats.length; ++i) { - dateFormats[i] = new SimpleDateFormat(formats[i]); - dateFormats[i].setTimeZone(TimeZone.getTimeZone("GMT")); - } - } + private static final DateTimeFormatter RFC3659_DATETIME_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss[.SSS]") + .withZone(ZoneOffset.UTC); /** * Issues the MDTM [path] command to the server to get the modification @@ -1768,24 +1758,20 @@ public long getSize(String path) throws sun.net.ftp.FtpProtocolException, IOExce public Date getLastModified(String path) throws sun.net.ftp.FtpProtocolException, IOException { issueCommandCheck("MDTM " + path); if (lastReplyCode == FtpReplyCode.FILE_STATUS) { - String s = getResponseString().substring(4); - return parseRfc3659TimeValue(s); + String s = getResponseString(); + return parseRfc3659TimeValue(s.substring(4, s.length() - 1)); } return null; } private static Date parseRfc3659TimeValue(String s) { - Date d = null; - for (SimpleDateFormat dateFormat : dateFormats) { - try { - d = dateFormat.parse(s); - } catch (ParseException ex) { - } - if (d != null) { - return d; - } + Date result = null; + try { + var d = ZonedDateTime.parse(s, RFC3659_DATETIME_FORMAT); + result = Date.from(d.toInstant()); + } catch (DateTimeParseException ex) { } - return d; + return result; } /** diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS7.java b/src/java.base/share/classes/sun/security/pkcs/PKCS7.java index bac69e07842..0dca814eb76 100644 --- a/src/java.base/share/classes/sun/security/pkcs/PKCS7.java +++ b/src/java.base/share/classes/sun/security/pkcs/PKCS7.java @@ -28,9 +28,6 @@ import java.io.*; import java.math.BigInteger; import java.net.URI; -import java.security.interfaces.EdECPrivateKey; -import java.security.spec.InvalidParameterSpecException; -import java.security.spec.PSSParameterSpec; import java.util.*; import java.security.cert.X509Certificate; import java.security.cert.CertificateException; diff --git a/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java b/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java index 23fedb789dd..d84e7182216 100644 --- a/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java +++ b/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java @@ -260,8 +260,6 @@ public void derEncode(OutputStream out) throws IOException { out.write(tmp.toByteArray()); } - - /* * Returns the (user) certificate pertaining to this SignerInfo. */ @@ -503,24 +501,27 @@ SignerInfo verify(PKCS7 block, byte[] data) /** * Derives the signature algorithm name from the digest algorithm - * name and the encryption algorithm name inside a PKCS7 SignerInfo. + * and the encryption algorithm inside a PKCS7 SignerInfo. + * + * The digest algorithm is in the form "DIG", and the encryption + * algorithm can be in any of the 3 forms: * - * For old style PKCS7 files where we use RSA, DSA, EC as encAlgId - * a DIGESTwithENC algorithm is returned. For new style RSASSA-PSS - * and EdDSA encryption, this method ensures digAlgId is compatible - * with the algorithm. + * 1. Old style key algorithm like RSA, DSA, EC, this method returns + * DIGwithKEY. + * 2. New style signature algorithm in the form of HASHwithKEY, this + * method returns DIGwithKEY. Please note this is not HASHwithKEY. + * 3. Modern signature algorithm like RSASSA-PSS and EdDSA, this method + * returns the signature algorithm itself but ensures digAlgId is + * compatible with the algorithm as described in RFC 4056 and 8419. * * @param digAlgId the digest algorithm - * @param encAlgId the encryption or signature algorithm + * @param encAlgId the encryption algorithm * @param directSign whether the signature is calculated on the content * directly. This makes difference for Ed448. */ public static String makeSigAlg(AlgorithmId digAlgId, AlgorithmId encAlgId, boolean directSign) throws NoSuchAlgorithmException { String encAlg = encAlgId.getName(); - if (encAlg.contains("with")) { - return encAlg; - } switch (encAlg) { case "RSASSA-PSS": PSSParameterSpec spec = (PSSParameterSpec) @@ -547,11 +548,16 @@ public static String makeSigAlg(AlgorithmId digAlgId, AlgorithmId encAlgId, return encAlg; default: String digAlg = digAlgId.getName(); + String keyAlg = SignatureUtil.extractKeyAlgFromDwithE(encAlg); + if (keyAlg == null) { + // The encAlg used to be only the key alg + keyAlg = encAlg; + } if (digAlg.startsWith("SHA-")) { digAlg = "SHA" + digAlg.substring(4); } - if (encAlg.equals("EC")) encAlg = "ECDSA"; - return digAlg + "with" + encAlg; + if (keyAlg.equals("EC")) keyAlg = "ECDSA"; + return digAlg + "with" + keyAlg; } } diff --git a/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java index ca8e208f28a..f9b5357e269 100644 --- a/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java +++ b/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java @@ -65,6 +65,7 @@ import javax.security.auth.DestroyFailedException; import javax.security.auth.x500.X500Principal; +import sun.security.action.GetPropertyAction; import sun.security.tools.KeyStoreUtil; import sun.security.util.*; import sun.security.pkcs.ContentInfo; @@ -79,48 +80,10 @@ * Implements the PKCS#12 PFX protected using the Password privacy mode. * The contents are protected using Password integrity mode. * - * Currently these PBE algorithms are used by default: - * - PBEWithSHA1AndDESede to encrypt private keys, iteration count 50000. - * - PBEWithSHA1AndRC2_40 to encrypt certificates, iteration count 50000. - * - * The default Mac algorithm is HmacPBESHA1, iteration count 100000. - * - * Supported encryption of various implementations : - * - * Software and mode. Certificate encryption Private key encryption - * --------------------------------------------------------------------- - * MSIE4 (domestic 40 bit RC2. 40 bit RC2 - * and xport versions) - * PKCS#12 export. - * - * MSIE4, 5 (domestic 40 bit RC2, 40 bit RC2, - * and export versions) 3 key triple DES 3 key triple DES - * PKCS#12 import. - * - * MSIE5 40 bit RC2 3 key triple DES, - * PKCS#12 export. with SHA1 (168 bits) - * - * Netscape Communicator 40 bit RC2 3 key triple DES, - * (domestic and export with SHA1 (168 bits) - * versions) PKCS#12 export - * - * Netscape Communicator 40 bit ciphers only All. - * (export version) - * PKCS#12 import. - * - * Netscape Communicator All. All. - * (domestic or fortified - * version) PKCS#12 import. - * - * OpenSSL PKCS#12 code. All. All. - * --------------------------------------------------------------------- - * - * NOTE: PKCS12 KeyStore supports PrivateKeyEntry and TrustedCertficateEntry. - * PKCS#12 is mainly used to deliver private keys with their associated - * certificate chain and aliases. In a PKCS12 keystore, entries are - * identified by the alias, and a localKeyId is required to match the - * private key with the certificate. Trusted certificate entries are identified - * by the presence of an trustedKeyUsage attribute. + * NOTE: In a PKCS12 keystore, entries are identified by the alias, and + * a localKeyId is required to match the private key with the certificate. + * Trusted certificate entries are identified by the presence of an + * trustedKeyUsage attribute. * * @author Seema Malkani * @author Jeff Nisewanger @@ -130,6 +93,32 @@ */ public final class PKCS12KeyStore extends KeyStoreSpi { + // Hardcoded defaults. They should be the same with commented out + // lines inside the java.security file. + private static final String DEFAULT_CERT_PBE_ALGORITHM + = "PBEWithHmacSHA256AndAES_256"; + private static final String DEFAULT_KEY_PBE_ALGORITHM + = "PBEWithHmacSHA256AndAES_256"; + private static final String DEFAULT_MAC_ALGORITHM = "HmacPBESHA256"; + private static final int DEFAULT_CERT_PBE_ITERATION_COUNT = 10000; + private static final int DEFAULT_KEY_PBE_ITERATION_COUNT = 10000; + private static final int DEFAULT_MAC_ITERATION_COUNT = 10000; + + // Legacy settings. Used when "keystore.pkcs12.legacy" is set. + private static final String LEGACY_CERT_PBE_ALGORITHM + = "PBEWithSHA1AndRC2_40"; + private static final String LEGACY_KEY_PBE_ALGORITHM + = "PBEWithSHA1AndDESede"; + private static final String LEGACY_MAC_ALGORITHM = "HmacPBESHA1"; + private static final int LEGACY_PBE_ITERATION_COUNT = 50000; + private static final int LEGACY_MAC_ITERATION_COUNT = 100000; + + // Big switch. When this system property is set. Legacy settings + // are used no matter what other keystore.pkcs12.* properties are set. + // Note: This is only a system property, there's no same-name + // security property defined. + private static final String USE_LEGACY_PROP = "keystore.pkcs12.legacy"; + // special PKCS12 keystore that supports PKCS12 and JKS file formats public static final class DualFormatPKCS12 extends KeyStoreDelegator { public DualFormatPKCS12() { @@ -845,9 +834,6 @@ private SecretKey getPBEKey(char[] password) throws IOException * Encrypt private key or secret key using Password-based encryption (PBE) * as defined in PKCS#5. * - * NOTE: By default, pbeWithSHAAnd3-KeyTripleDES-CBC algorithmID is - * used to derive the key and IV. - * * @return encrypted private key or secret key encoded as * EncryptedPrivateKeyInfo */ @@ -1866,9 +1852,6 @@ private byte[] createSafeContent() * Encrypt the contents using Password-based (PBE) encryption * as defined in PKCS #5. * - * NOTE: Currently pbeWithSHAAnd40BiteRC2-CBC algorithmID is used - * to derive the key and IV. - * * @return encrypted contents encoded as EncryptedContentInfo */ private byte[] encryptContent(byte[] data, char[] password) @@ -2640,25 +2623,42 @@ public boolean engineProbe(InputStream stream) throws IOException { return result; } - // 8076190: Customizing the generation of a PKCS12 keystore + // The following methods are related to customizing + // the generation of a PKCS12 keystore or private/secret + // key entries. + + private static boolean useLegacy() { + return GetPropertyAction.privilegedGetProperty( + USE_LEGACY_PROP) != null; + } private static String defaultCertProtectionAlgorithm() { + if (useLegacy()) { + return LEGACY_CERT_PBE_ALGORITHM; + } String result = SecurityProperties.privilegedGetOverridable( "keystore.pkcs12.certProtectionAlgorithm"); return (result != null && !result.isEmpty()) - ? result : "PBEWithSHA1AndRC2_40"; + ? result : DEFAULT_CERT_PBE_ALGORITHM; } private static int defaultCertPbeIterationCount() { + if (useLegacy()) { + return LEGACY_PBE_ITERATION_COUNT; + } String result = SecurityProperties.privilegedGetOverridable( "keystore.pkcs12.certPbeIterationCount"); return (result != null && !result.isEmpty()) - ? string2IC("certPbeIterationCount", result) : 50000; + ? string2IC("certPbeIterationCount", result) + : DEFAULT_CERT_PBE_ITERATION_COUNT; } // Read both "keystore.pkcs12.keyProtectionAlgorithm" and // "keystore.PKCS12.keyProtectionAlgorithm" for compatibility. private static String defaultKeyProtectionAlgorithm() { + if (useLegacy()) { + return LEGACY_KEY_PBE_ALGORITHM; + } String result = AccessController.doPrivileged(new PrivilegedAction() { public String run() { String result; @@ -2680,28 +2680,39 @@ public String run() { } }); return (result != null && !result.isEmpty()) - ? result : "PBEWithSHA1AndDESede"; + ? result : DEFAULT_KEY_PBE_ALGORITHM; } private static int defaultKeyPbeIterationCount() { + if (useLegacy()) { + return LEGACY_PBE_ITERATION_COUNT; + } String result = SecurityProperties.privilegedGetOverridable( "keystore.pkcs12.keyPbeIterationCount"); return (result != null && !result.isEmpty()) - ? string2IC("keyPbeIterationCount", result) : 50000; + ? string2IC("keyPbeIterationCount", result) + : DEFAULT_KEY_PBE_ITERATION_COUNT; } private static String defaultMacAlgorithm() { + if (useLegacy()) { + return LEGACY_MAC_ALGORITHM; + } String result = SecurityProperties.privilegedGetOverridable( "keystore.pkcs12.macAlgorithm"); return (result != null && !result.isEmpty()) - ? result : "HmacPBESHA1"; + ? result : DEFAULT_MAC_ALGORITHM; } private static int defaultMacIterationCount() { + if (useLegacy()) { + return LEGACY_MAC_ITERATION_COUNT; + } String result = SecurityProperties.privilegedGetOverridable( "keystore.pkcs12.macIterationCount"); return (result != null && !result.isEmpty()) - ? string2IC("macIterationCount", result) : 100000; + ? string2IC("macIterationCount", result) + : DEFAULT_MAC_ITERATION_COUNT; } private static int string2IC(String type, String value) { diff --git a/src/java.base/share/classes/sun/security/util/Cache.java b/src/java.base/share/classes/sun/security/util/Cache.java index 9a2e2fc29b0..5e1eef17ee4 100644 --- a/src/java.base/share/classes/sun/security/util/Cache.java +++ b/src/java.base/share/classes/sun/security/util/Cache.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -265,8 +265,7 @@ public MemoryCache(boolean soft, int maxSize, int lifetime) { else this.queue = null; - int buckets = (int)(maxSize / LOAD_FACTOR) + 1; - cacheMap = new LinkedHashMap<>(buckets, LOAD_FACTOR, true); + cacheMap = new LinkedHashMap<>(1, LOAD_FACTOR, true); } /** diff --git a/src/java.base/share/classes/sun/security/util/SignatureUtil.java b/src/java.base/share/classes/sun/security/util/SignatureUtil.java index 4ad03a6f731..0a17105355b 100644 --- a/src/java.base/share/classes/sun/security/util/SignatureUtil.java +++ b/src/java.base/share/classes/sun/security/util/SignatureUtil.java @@ -282,6 +282,32 @@ public static String extractDigestAlgFromDwithE(String signatureAlgorithm) { } } + /** + * Extracts the key algorithm name from a signature + * algorithm name in either the "DIGESTwithENCRYPTION" or the + * "DIGESTwithENCRYPTIONandWHATEVER" format. + * + * @return the key algorithm name, or null if the input + * is not in either of the formats. + */ + public static String extractKeyAlgFromDwithE(String signatureAlgorithm) { + signatureAlgorithm = signatureAlgorithm.toUpperCase(Locale.ENGLISH); + int with = signatureAlgorithm.indexOf("WITH"); + String keyAlgorithm = null; + if (with > 0) { + int and = signatureAlgorithm.indexOf("AND", with + 4); + if (and > 0) { + keyAlgorithm = signatureAlgorithm.substring(with + 4, and); + } else { + keyAlgorithm = signatureAlgorithm.substring(with + 4); + } + if (keyAlgorithm.equalsIgnoreCase("ECDSA")) { + keyAlgorithm = "EC"; + } + } + return keyAlgorithm; + } + /** * Returns default AlgorithmParameterSpec for a key used in a signature. * This is only useful for RSASSA-PSS now, which is the only algorithm diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index b84a9d3e0cc..ddc4b87d6ee 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -1144,33 +1144,33 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep # The algorithm used to encrypt a certificate. This can be any non-Hmac PBE # algorithm defined in the Cipher section of the Java Security Standard # Algorithm Names Specification. When set to "NONE", the certificate -# is not encrypted. The default value is "PBEWithSHA1AndRC2_40". -#keystore.pkcs12.certProtectionAlgorithm = PBEWithSHA1AndRC2_40 +# is not encrypted. The default value is "PBEWithHmacSHA256AndAES_256". +#keystore.pkcs12.certProtectionAlgorithm = PBEWithHmacSHA256AndAES_256 # The iteration count used by the PBE algorithm when encrypting a certificate. -# This value must be a positive integer. The default value is 50000. -#keystore.pkcs12.certPbeIterationCount = 50000 +# This value must be a positive integer. The default value is 10000. +#keystore.pkcs12.certPbeIterationCount = 10000 # The algorithm used to encrypt a private key or secret key. This can be # any non-Hmac PBE algorithm defined in the Cipher section of the Java # Security Standard Algorithm Names Specification. The value must not be "NONE". -# The default value is "PBEWithSHA1AndDESede". -#keystore.pkcs12.keyProtectionAlgorithm = PBEWithSHA1AndDESede +# The default value is "PBEWithHmacSHA256AndAES_256". +#keystore.pkcs12.keyProtectionAlgorithm = PBEWithHmacSHA256AndAES_256 # The iteration count used by the PBE algorithm when encrypting a private key # or a secret key. This value must be a positive integer. The default value -# is 50000. -#keystore.pkcs12.keyPbeIterationCount = 50000 +# is 10000. +#keystore.pkcs12.keyPbeIterationCount = 10000 # The algorithm used to calculate the optional MacData at the end of a PKCS12 # file. This can be any HmacPBE algorithm defined in the Mac section of the # Java Security Standard Algorithm Names Specification. When set to "NONE", -# no Mac is generated. The default value is "HmacPBESHA1". -#keystore.pkcs12.macAlgorithm = HmacPBESHA1 +# no Mac is generated. The default value is "HmacPBESHA256". +#keystore.pkcs12.macAlgorithm = HmacPBESHA256 # The iteration count used by the MacData algorithm. This value must be a -# positive integer. The default value is 100000. -#keystore.pkcs12.macIterationCount = 100000 +# positive integer. The default value is 10000. +#keystore.pkcs12.macIterationCount = 10000 # # Enhanced exception message information @@ -1308,4 +1308,4 @@ jdk.io.permissionsUseCanonicalPath=false # properties. In the case that both properties are simultaneously set, the # System value prevails. The default value of the property is "false". # -#jdk.security.allowNonCaAnchor=true \ No newline at end of file +#jdk.security.allowNonCaAnchor=true diff --git a/src/java.base/share/man/java.1 b/src/java.base/share/man/java.1 index 3a003645616..fd78f50e156 100644 --- a/src/java.base/share/man/java.1 +++ b/src/java.base/share/man/java.1 @@ -1,4 +1,3 @@ -.\"t .\" Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" @@ -8,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -20,9 +19,10 @@ .\" or visit www.oracle.com if you need additional information or have any .\" questions. .\" +.\"t .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAVA" "1" "2020" "JDK 15" "JDK Commands" +.TH "JAVA" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP @@ -181,7 +181,7 @@ with new values added and old values removed. You\[aq]ll get an error message if you use a value of \f[I]N\f[R] that is no longer supported. The supported values of \f[I]N\f[R] are the current Java SE release -(\f[CB]15\f[R]) and a limited number of previous releases, detailed in the +(\f[CB]16\f[R]) and a limited number of previous releases, detailed in the command\-line help for \f[CB]javac\f[R], under the \f[CB]\-\-source\f[R] and \f[CB]\-\-release\f[R] options. .RE @@ -4089,14 +4089,6 @@ This option was deprecated in JDK 8 and superseded by the \f[CB]\-XX:MetaspaceSize\f[R] option. .RS .RE -.TP -.B \f[CB]\-XX:+UseParallelOldGC\f[R] -Enables the use of the parallel garbage collector for full GCs. -By default, this option is disabled. -Enabling it automatically enables the \f[CB]\-XX:+UseParallelGC\f[R] -option. -.RS -.RE .SH REMOVED JAVA OPTIONS .PP These \f[CB]java\f[R] options have been removed in JDK 15 and using them @@ -4106,28 +4098,20 @@ results in an error of: \f[CB]Unrecognized\ VM\ option\f[R] \f[I]option\-name\f[R] .RE .TP -.B \f[CB]\-XX:+FailOverToOldVerifier\f[R] -Enables automatic failover to the old verifier when the new type checker -fails. -By default, this option is disabled and it\[aq]s ignored (that is, -treated as disabled) for classes with a recent bytecode version. -You can enable it only for classes with older versions of the bytecode. -.RS -.RE -.TP -.B \f[CB]\-XX:+UseConcMarkSweepGC\f[R] -Enables the use of the CMS garbage collector for the old generation. -CMS is an alternative to the default garbage collector (G1), which also -focuses on meeting application latency requirements. -By default, this option is disabled and the collector is selected -automatically based on the configuration of the machine and type of the -JVM. +.B \f[CB]\-XX:+UseParallelOldGC\f[R] +Enables the use of the parallel garbage collector for full GCs. +By default, this option is disabled. +Enabling it automatically enables the \f[CB]\-XX:+UseParallelGC\f[R] +option. .RS .RE .PP For the lists and descriptions of options removed in previous releases see the \f[I]Removed Java Options\f[R] section in: .IP \[bu] 2 +\f[B]Java Platform, Standard Edition Tools Reference, Release 15\f[R] +[https://docs.oracle.com/en/java/javase/15/docs/specs/man/java.html] +.IP \[bu] 2 \f[B]Java Platform, Standard Edition Tools Reference, Release 14\f[R] [https://docs.oracle.com/en/java/javase/14/docs/specs/man/java.html] .IP \[bu] 2 diff --git a/src/java.base/share/man/keytool.1 b/src/java.base/share/man/keytool.1 index 38008bfd7f8..8067f45fdd2 100644 --- a/src/java.base/share/man/keytool.1 +++ b/src/java.base/share/man/keytool.1 @@ -1,4 +1,3 @@ -.\"t .\" Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" @@ -8,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -20,9 +19,10 @@ .\" or visit www.oracle.com if you need additional information or have any .\" questions. .\" +.\"t .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "KEYTOOL" "1" "2020" "JDK 15" "JDK Commands" +.TH "KEYTOOL" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP @@ -980,6 +980,28 @@ Sockets Layer (SSL) server host and port .IP \[bu] 2 {\f[CB]\-jarfile\f[R] \f[I]JAR_file\f[R]}: Signed \f[CB]\&.jar\f[R] file .IP \[bu] 2 +{\f[CB]\-keystore\f[R] \f[I]keystore\f[R]}: Keystore name +.IP \[bu] 2 +{\f[CB]\-trustcacerts\f[R]}: Trust certificates from cacerts +.IP \[bu] 2 +[\f[CB]\-storepass\f[R] \f[I]arg\f[R]]: Keystore password +.IP \[bu] 2 +{\f[CB]\-storetype\f[R] \f[I]type\f[R]}: Keystore type +.IP \[bu] 2 +{\f[CB]\-providername\f[R] \f[I]name\f[R]}: Provider name +.IP \[bu] 2 +{\f[CB]\-addprovider\f[R] \f[I]name\f[R] [\f[CB]\-providerarg\f[R] +\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with +an optional configure argument. +.IP \[bu] 2 +{\f[CB]\-providerclass\f[R] \f[I]class\f[R] [\f[CB]\-providerarg\f[R] +\f[I]arg\f[R]]}: Add security provider by fully qualified class name with +an optional configure argument. +.IP \[bu] 2 +{\f[CB]\-providerpath\f[R] \f[I]list\f[R]}: Provider classpath +.IP \[bu] 2 +{\f[CB]\-protected\f[R]}: Password is provided through protected mechanism +.IP \[bu] 2 {\f[CB]\-v\f[R]}: Verbose output .PP Use the \f[CB]\-printcert\f[R] command to read and print the certificate @@ -1012,7 +1034,11 @@ command line for proxy tunneling. .PP \f[B]Note:\f[R] .PP -This option can be used independently of a keystore. +This command can be used independently of a keystore. +This command does not check for the weakness of a certificate\[aq]s +signature algorithm if it is a trusted certificate in the user keystore +(specified by \f[CB]\-keystore\f[R]) or in the \f[CB]cacerts\f[R] keystore +(if \f[CB]\-trustcacerts\f[R] is specified). .RE .TP .B \f[CB]\-printcertreq\f[R] @@ -1038,6 +1064,28 @@ command: .IP \[bu] 2 {\f[CB]\-file\ crl\f[R]}: Input file name .IP \[bu] 2 +{\f[CB]\-keystore\f[R] \f[I]keystore\f[R]}: Keystore name +.IP \[bu] 2 +{\f[CB]\-trustcacerts\f[R]}: Trust certificates from cacerts +.IP \[bu] 2 +[\f[CB]\-storepass\f[R] \f[I]arg\f[R]]: Keystore password +.IP \[bu] 2 +{\f[CB]\-storetype\f[R] \f[I]type\f[R]}: Keystore type +.IP \[bu] 2 +{\f[CB]\-providername\f[R] \f[I]name\f[R]}: Provider name +.IP \[bu] 2 +{\f[CB]\-addprovider\f[R] \f[I]name\f[R] [\f[CB]\-providerarg\f[R] +\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with +an optional configure argument. +.IP \[bu] 2 +{\f[CB]\-providerclass\f[R] \f[I]class\f[R] [\f[CB]\-providerarg\f[R] +\f[I]arg\f[R]]}: Add security provider by fully qualified class name with +an optional configure argument. +.IP \[bu] 2 +{\f[CB]\-providerpath\f[R] \f[I]list\f[R]}: Provider classpath +.IP \[bu] 2 +{\f[CB]\-protected\f[R]}: Password is provided through protected mechanism +.IP \[bu] 2 {\f[CB]\-v\f[R]}: Verbose output .PP Use the \f[CB]\-printcrl\f[R] command to read the Certificate Revocation @@ -1048,7 +1096,11 @@ The CA generates the \f[CB]crl\f[R] file. .PP \f[B]Note:\f[R] .PP -This option can be used independently of a keystore. +This command can be used independently of a keystore. +This command attempts to verify the CRL using a certificate from the +user keystore (specified by \f[CB]\-keystore\f[R]) or the \f[CB]cacerts\f[R] +keystore (if \f[CB]\-trustcacerts\f[R] is specified), and will print out a +warning if it cannot be verified. .RE .SH COMMANDS FOR MANAGING THE KEYSTORE .TP @@ -1479,9 +1531,9 @@ The following examples show the defaults for various option values: \-alias\ "mykey" \-keysize -\ \ \ \ 2048\ (when\ using\ \-genkeypair\ and\ \-keyalg\ is\ "RSA") -\ \ \ \ 2048\ (when\ using\ \-genkeypair\ and\ \-keyalg\ is\ "DSA") +\ \ \ \ 2048\ (when\ using\ \-genkeypair\ and\ \-keyalg\ is\ "RSA",\ "DSA",\ or\ "RSASSA\-PSS") \ \ \ \ 256\ (when\ using\ \-genkeypair\ and\ \-keyalg\ is\ "EC") +\ \ \ \ 255\ (when\ using\ \-genkeypair\ and\ \-keyalg\ is\ "EdDSA") \ \ \ \ 56\ (when\ using\ \-genseckey\ and\ \-keyalg\ is\ "DES") \ \ \ \ 168\ (when\ using\ \-genseckey\ and\ \-keyalg\ is\ "DESede") @@ -1564,7 +1616,66 @@ T}@T{ T}@T{ SHA512withECDSA T} +T{ +RSASSA\-PSS +T}@T{ +<= 3072 +T}@T{ +RSASSA\-PSS (with SHA\-256) +T} +T{ +T}@T{ +<= 7680 +T}@T{ +RSASSA\-PSS (with SHA\-384) +T} +T{ +T}@T{ +> 7680 +T}@T{ +RSASSA\-PSS (with SHA\-512) +T} +T{ +EdDSA +T}@T{ +255 +T}@T{ +Ed25519 +T} +T{ +T}@T{ +448 +T}@T{ +Ed448 +T} +T{ +Ed25519 +T}@T{ +255 +T}@T{ +Ed25519 +T} +T{ +Ed448 +T}@T{ +448 +T}@T{ +Ed448 +T} .TE +.IP \[bu] 2 +An RSASSA\-PSS signature algorithm uses a \f[CB]MessageDigest\f[R] +algorithm as its hash and MGF1 algorithms. +.IP \[bu] 2 +EdDSA supports 2 key sizes: Ed25519 and Ed448. +When generating an EdDSA key pair using \f[CB]\-keyalg\ EdDSA\f[R], a user +can specify \f[CB]\-keysize\ 255\f[R] or \f[CB]\-keysize\ 448\f[R] to +generate Ed25519 or Ed448 key pairs. +When no \f[CB]\-keysize\f[R] is specified, an Ed25519 key pair is +generated. +A user can also directly specify \f[CB]\-keyalg\ Ed25519\f[R] or +\f[CB]\-keyalg\ Ed448\f[R] to generate a key pair with the expected key +size. .PP \f[B]Note:\f[R] .PP diff --git a/src/java.base/share/native/libjava/PhantomReference.c b/src/java.base/share/native/libjava/PhantomReference.c new file mode 100644 index 00000000000..b6d6e7297f1 --- /dev/null +++ b/src/java.base/share/native/libjava/PhantomReference.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "jvm.h" +#include "java_lang_ref_PhantomReference.h" + +JNIEXPORT jboolean JNICALL +Java_java_lang_ref_PhantomReference_refersTo0(JNIEnv *env, jobject ref, jobject o) +{ + return JVM_PhantomReferenceRefersTo(env, ref, o); +} diff --git a/src/java.base/share/native/libjava/Reference.c b/src/java.base/share/native/libjava/Reference.c index 92c518c5d90..20d33e6ead6 100644 --- a/src/java.base/share/native/libjava/Reference.c +++ b/src/java.base/share/native/libjava/Reference.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,3 +43,9 @@ Java_java_lang_ref_Reference_waitForReferencePendingList(JNIEnv *env, jclass ign { JVM_WaitForReferencePendingList(env); } + +JNIEXPORT jboolean JNICALL +Java_java_lang_ref_Reference_refersTo0(JNIEnv *env, jobject ref, jobject o) +{ + return JVM_ReferenceRefersTo(env, ref, o); +} diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java index f0236ba3d53..72f8b05895e 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java @@ -257,6 +257,7 @@ public Iterator iterator() { @Override public final Path getPath(String first, String... more) { + Objects.requireNonNull(first); String path; if (more.length == 0) { path = first; diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java index 0a927d01d71..5443f8cac63 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java @@ -352,7 +352,14 @@ public boolean isHidden(Path obj) { UnixPath name = file.getFileName(); if (name == null) return false; - return (name.asByteArray()[0] == '.'); + + byte[] path; + if (name.isEmpty()) { // corner case for empty paths + path = name.getFileSystem().defaultDirectory(); + } else { + path = name.asByteArray(); + } + return path[0] == '.'; } /** diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixPath.java b/src/java.base/unix/classes/sun/nio/fs/UnixPath.java index 804b5632846..92d71c53591 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixPath.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixPath.java @@ -243,7 +243,7 @@ private void initOffsets() { } // returns {@code true} if this path is an empty path - private boolean isEmpty() { + boolean isEmpty() { return path.length == 0; } diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java index e9a65218163..669ef3c087d 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -211,6 +211,7 @@ public Set supportedFileAttributeViews() { @Override public final Path getPath(String first, String... more) { + Objects.requireNonNull(first); String path; if (more.length == 0) { path = first; diff --git a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java index bf64e4f34b9..95cb8263afa 100644 --- a/src/java.compiler/share/classes/javax/lang/model/util/Elements.java +++ b/src/java.compiler/share/classes/javax/lang/model/util/Elements.java @@ -51,11 +51,30 @@ public interface Elements { /** - * Returns a package given its fully qualified name if the package is unique in the environment. - * If running with modules, all modules in the modules graph are searched for matching packages. - * - * @param name fully qualified package name, or an empty string for an unnamed package - * @return the specified package, or {@code null} if it cannot be uniquely found + * Returns a package given its fully qualified name if the package is uniquely + * determinable in the environment. + * + * If running with modules, packages of the given name are searched in a + * two-stage process: + *

    + *
  • find non-empty packages with the given name returned by + * {@link #getPackageElement(ModuleElement, CharSequence)}, + * where the provided ModuleSymbol is any + * root module, + *
  • + *
  • if the above yields an empty list, search + * {@link #getAllModuleElements() all modules} for observable + * packages with the given name + *
  • + *
+ * + * If this process leads to a list with a single element, + * the single element is returned, otherwise null is returned. + * + * @param name fully qualified package name, + * or an empty string for an unnamed package + * @return the specified package, + * or {@code null} if no package can be uniquely determined. */ PackageElement getPackageElement(CharSequence name); @@ -119,12 +138,29 @@ default Set getAllPackageElements(CharSequence name) { } /** - * Returns a type element given its canonical name if the type element is unique in the environment. - * If running with modules, all modules in the modules graph are searched for matching - * type elements. - * - * @param name the canonical name - * @return the named type element, or {@code null} if it cannot be uniquely found + * Returns a type element given its canonical name if the type element is uniquely + * determinable in the environment. + * + * If running with modules, type elements of the given name are + * searched in a two-stage process: + *
    + *
  • find type elements with the given name returned by + * {@link #getTypeElement(ModuleElement, CharSequence)}, + * where the provided ModuleSymbol is any + * root module, + *
  • + *
  • if the above yields an empty list, search + * {@link #getAllModuleElements() all modules} for observable + * type elements with the given name + *
  • + *
+ * + * If this process leads to a list with a single element, + * the single element is returned, otherwise null is returned. + * + * @param name the canonical name + * @return the named type element, + * or {@code null} if no type element can be uniquely determined. */ TypeElement getTypeElement(CharSequence name); diff --git a/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m b/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m index 72246e7a887..4cb5bc0ca57 100644 --- a/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m +++ b/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -334,6 +334,7 @@ + (void) runAWTLoopWithApp:(NSApplication*)app { [app run]; } @catch (NSException* e) { NSLog(@"Apple AWT Startup Exception: %@", [e description]); + NSLog(@"Apple AWT Startup Exception callstack: %@", [e callStackSymbols]); NSLog(@"Apple AWT Restarting Native Event Thread"); [app stop:app]; diff --git a/src/java.desktop/share/classes/java/awt/Component.java b/src/java.desktop/share/classes/java/awt/Component.java index ad19383cd58..98a8cdc03b7 100644 --- a/src/java.desktop/share/classes/java/awt/Component.java +++ b/src/java.desktop/share/classes/java/awt/Component.java @@ -207,7 +207,7 @@ * * How to Use the Focus Subsystem, * a section in The Java Tutorial, and the - * Focus Specification + * Focus Specification * for more information. * * @author Arthur van Hoff @@ -7651,7 +7651,7 @@ public void requestFocus(FocusEvent.Cause cause) { * @param temporary true if the focus change is temporary, * such as when the window loses the focus; for * more information on temporary focus changes see the - *Focus Specification + *Focus Specification * @return {@code false} if the focus change request is guaranteed to * fail; {@code true} if it is likely to succeed * @see java.awt.event.FocusEvent @@ -7719,7 +7719,7 @@ protected boolean requestFocus(boolean temporary) { * @param temporary true if the focus change is temporary, * such as when the window loses the focus; for * more information on temporary focus changes see the - *Focus Specification + *Focus Specification * * @param cause the cause why the focus is requested * @return {@code false} if the focus change request is guaranteed to @@ -7886,7 +7886,7 @@ public boolean requestFocusInWindow(FocusEvent.Cause cause) { * @param temporary true if the focus change is temporary, * such as when the window loses the focus; for * more information on temporary focus changes see the - *Focus Specification + *Focus Specification * @return {@code false} if the focus change request is guaranteed to * fail; {@code true} if it is likely to succeed * @see #requestFocus diff --git a/src/java.desktop/share/classes/java/awt/Container.java b/src/java.desktop/share/classes/java/awt/Container.java index ee754201f5e..557111c07d3 100644 --- a/src/java.desktop/share/classes/java/awt/Container.java +++ b/src/java.desktop/share/classes/java/awt/Container.java @@ -83,7 +83,7 @@ * * How to Use the Focus Subsystem, * a section in The Java Tutorial, and the - * Focus Specification + * Focus Specification * for more information. * * @author Arthur van Hoff diff --git a/src/java.desktop/share/classes/java/awt/DefaultFocusTraversalPolicy.java b/src/java.desktop/share/classes/java/awt/DefaultFocusTraversalPolicy.java index 4a9e10166fa..ebfa17302ee 100644 --- a/src/java.desktop/share/classes/java/awt/DefaultFocusTraversalPolicy.java +++ b/src/java.desktop/share/classes/java/awt/DefaultFocusTraversalPolicy.java @@ -57,7 +57,7 @@ * * How to Use the Focus Subsystem, * a section in The Java Tutorial, and the - * Focus Specification + * Focus Specification * for more information. * * @author David Mendenhall diff --git a/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java b/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java index de60e1e747c..47ddefaabd2 100644 --- a/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java +++ b/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java @@ -52,7 +52,7 @@ * * How to Use the Focus Subsystem, * a section in The Java Tutorial, and the - * Focus Specification + * Focus Specification * for more information. * * @author David Mendenhall diff --git a/src/java.desktop/share/classes/java/awt/FocusTraversalPolicy.java b/src/java.desktop/share/classes/java/awt/FocusTraversalPolicy.java index 9bcc326771f..551de6a89b8 100644 --- a/src/java.desktop/share/classes/java/awt/FocusTraversalPolicy.java +++ b/src/java.desktop/share/classes/java/awt/FocusTraversalPolicy.java @@ -52,7 +52,7 @@ * * How to Use the Focus Subsystem, * a section in The Java Tutorial, and the - * Focus Specification + * Focus Specification * for more information. * * @author David Mendenhall diff --git a/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java b/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java index f6079ede2ec..b317513756a 100644 --- a/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java +++ b/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,7 +88,7 @@ * * How to Use the Focus Subsystem, * a section in The Java Tutorial, and the - * Focus Specification + * Focus Specification * for more information. * * @author David Mendenhall diff --git a/src/java.desktop/share/classes/java/awt/doc-files/DesktopProperties.html b/src/java.desktop/share/classes/java/awt/doc-files/DesktopProperties.html index e6790a53bcf..1e68b086e4e 100644 --- a/src/java.desktop/share/classes/java/awt/doc-files/DesktopProperties.html +++ b/src/java.desktop/share/classes/java/awt/doc-files/DesktopProperties.html @@ -36,8 +36,8 @@

AWT Desktop Properties

The following refers to standard AWT desktop properties that may be obtained via the - -Toolkit.getDesktopProperty method. +{@link java.awt.Toolkit#getDesktopProperty(java.lang.String) +Toolkit.getDesktopProperty} method.

Each desktop property is named by a unique string, which is the "name" of that property. @@ -86,9 +86,9 @@

Desktop Font Rendering Hints

These are applied by platform-specific heavyweight components. However an application may want to render text using the same text antialiasing on a drawing surface or lightweight (non-platform) component using - Graphics2D methods. +{@link java.awt.Graphics2D Graphics2D} methods. This is particularly important when creating - Swing components which +{@link javax.swing.JComponent Swing components} which are required to appear consistent with native desktop components or other Swing components. @@ -97,9 +97,8 @@

Basic Usage

"awt.font.desktophints" can be used to obtain the rendering hints that best match the desktop settings. -The return value is a - Map of - RenderingHints which +The return value is a {@link java.util.Map Map} of +{@link java.awt.RenderingHints RenderingHints} which can be directly applied to a Graphics2D.

It is a Map as more than one hint may be needed. @@ -116,8 +115,7 @@

Advanced Usage Tips

Listening for changes

An application can listen for changes in the property -using a -PropertyChangeListener : +using a {@link java.beans.PropertyChangeListener PropertyChangeListener}:


 tk.addPropertyChangeListener("awt.font.desktophints", pcl);
 
@@ -134,10 +132,10 @@

Listening for changes

Text Measurement

Text always needs to be measured using the same - FontRenderContext +{@link java.awt.font.FontRenderContext FontRenderContext} as used for rendering. The text anti-aliasing hint is a component of the FontRenderContext. -A FontMetrics +A {@link java.awt.FontMetrics FontMetrics} obtained from the Graphics object on which the hint has been set will measure text appropriately. This is not a unique requirement for clients that specify this hint diff --git a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html index cfd7fdfa3ca..fc918e78eeb 100644 --- a/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html +++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html @@ -5,7 +5,7 @@ TIFF Metadata Format Specification and Usage Notes @@ -90,7 +90,7 @@

Color Conversion

Color Spaces

The raw color space assigned by default, i.e., in the absence of a -user-supplied ImageTypeSpecifier, +user-supplied {@link javax.imageio.ImageTypeSpecifier ImageTypeSpecifier}, will be the first among the following which applies:
    @@ -158,8 +158,8 @@

    Color Spaces

    ICC Profiles

    If an ICC profile is contained in the image metadata -( -BaselineTIFFTagSet.TAG_ICC_PROFILE, tag number 34675), +({@link javax.imageio.plugins.tiff.BaselineTIFFTagSet BaselineTIFFTagSet}. +TAG_ICC_PROFILE, tag number 34675), an attempt will be made to use it to create the color space of the loaded image. It will be used if the data layout is of component type and the number of samples per pixel equals or is one greater than the number @@ -174,15 +174,13 @@

    ICC Profiles

  • Obtain the image metadata from ImageReader.getImageMetadata
  • Extract the ICC profile field and its value.
  • -
  • Create an -ICC_ColorSpace from an - -ICC_Profile created from the ICC profile field data +
  • Create an {@link java.awt.color.ICC_ColorSpace ICC_ColorSpace} from an +{@link java.awt.color.ICC_Profile ICC_Profile} created from the ICC profile field data using ICC_Profile.getInstance(byte[]).
  • Create an ImageTypeSpecifier from the new color space using one of its factory methods which accepts an ICC_ColorSpace. -
  • Create a compatible ImageReadParam +
  • Create a compatible {@link javax.imageio.ImageReadParam ImageReadParam} and set the ImageTypeSpecifier using ImageReadParam.setDestinationType.
  • Pass the parameter object to the appropriate read method.
  • @@ -206,7 +204,7 @@

    Metadata Issues

    metadata. The reader is informed to disregard all metadata as usual via the ignoreMetadata parameter of ImageReader.setInput(Object,boolean,boolean). It is -informed of which TIFFTags to +informed of which {@link javax.imageio.plugins.tiff.TIFFTag TIFFTag}s to recognize or not to recognize via TIFFImageReadParam.addAllowedTagSet(TIFFTagSet) and TIFFImageReadParam.removeAllowedTagSet(TIFFTagSet). @@ -221,7 +219,7 @@

    Metadata Issues

    TIFFImageReadParam.setReadUnknownTags(boolean) has been invoked with parameter true. -

    Use of a TIFFDirectory +

    Use of a {@link javax.imageio.plugins.tiff.TIFFDirectory TIFFDirectory} object may simplify gaining access to metadata values. An instance of TIFFDirectory may be created from the IIOMetadata object returned by the TIFF reader using the @@ -481,9 +479,9 @@

    Reading Compressed Exif Images

    Writing Images

    -TIFF images are written by a ImageWriter which may be +TIFF images are written by a {@link javax.imageio.ImageWriter ImageWriter} which may be controlled by its public interface as well as via a supplied -ImageWriteParam. For an ImageWriteParam returned +{@link javax.imageio.ImageWriteParam ImageWriteParam}. For an ImageWriteParam returned by the getDefaultWriteParam() method of the TIFF ImageWriter, the canWriteTiles() and canWriteCompressed() methods will return true; the canOffsetTiles() and @@ -631,9 +629,9 @@

    ICC Profiles

    An ICC Profile field will be written if either:
    • one is present in the native image metadata -IIOMetadata instance supplied to the writer, +{@link javax.imageio.metadata.IIOMetadata IIOMetadata} instance supplied to the writer, or
    • -
    • the ColorSpace +
    • the {@link java.awt.color.ColorSpace ColorSpace} of the destination ImageTypeSpecifier is an instance of ICC_ColorSpace which is not one of the standard color spaces defined by the CS_* constants in the @@ -748,7 +746,7 @@

      Metadata Issues

      Setting up the image metadata to write to a TIFF stream may be simplified by using the TIFFDirectory class which represents a TIFF IFD. A field in a TIFF IFD is represented by an -instance of TIFFField. For each +instance of {@link javax.imageio.plugins.tiff.TIFFField TIFFField}. For each field to be written a TIFFField may be added to the TIFFDirectory and the latter converted to an IIOMetadata object by invoking diff --git a/src/java.desktop/share/classes/javax/print/DocFlavor.java b/src/java.desktop/share/classes/javax/print/DocFlavor.java index a52b0e18852..da3f4f18762 100644 --- a/src/java.desktop/share/classes/javax/print/DocFlavor.java +++ b/src/java.desktop/share/classes/javax/print/DocFlavor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -156,9 +156,9 @@ * the primary IANA name but is guaranteed to be understood by this VM. For * common flavors, the pre-defined *HOST {@code DocFlavors} may be used. *

      - * See character - * encodings for more information on the character encodings supported on - * the Java platform. + * See + * character encodings for more information on the character encodings + * supported on the Java platform. * *


      *

      Recommended DocFlavors

      diff --git a/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java b/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java index 1d1be4b484f..a100581567f 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/HTMLDocument.java @@ -194,7 +194,7 @@ * setInnerHTML * setOuterHTML * - * + * * *
      *

      Paragraph 1

      diff --git a/src/java.prefs/share/classes/java/util/prefs/Preferences.java b/src/java.prefs/share/classes/java/util/prefs/Preferences.java index 1fe279b9ab8..ff35fde4bd6 100644 --- a/src/java.prefs/share/classes/java/util/prefs/Preferences.java +++ b/src/java.prefs/share/classes/java/util/prefs/Preferences.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -194,7 +194,7 @@ *
        * *
      1. If the system property - * {@code java.util.prefs.PreferencesFactory} is defined, then it is + * {@systemProperty java.util.prefs.PreferencesFactory} is defined, then it is * taken to be the fully-qualified name of a class implementing the * {@code PreferencesFactory} interface. The class is loaded and * instantiated; if this process fails then an unspecified error is diff --git a/src/java.rmi/share/man/rmid.1 b/src/java.rmi/share/man/rmid.1 index 340a0523aa5..45e75ef4a7f 100644 --- a/src/java.rmi/share/man/rmid.1 +++ b/src/java.rmi/share/man/rmid.1 @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "RMID" "1" "2020" "JDK 15" "JDK Commands" +.TH "RMID" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/java.rmi/share/man/rmiregistry.1 b/src/java.rmi/share/man/rmiregistry.1 index ab025ce677b..9e33a66e5c5 100644 --- a/src/java.rmi/share/man/rmiregistry.1 +++ b/src/java.rmi/share/man/rmiregistry.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "RMIREGISTRY" "1" "2020" "JDK 15" "JDK Commands" +.TH "RMIREGISTRY" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/java.scripting/share/man/jrunscript.1 b/src/java.scripting/share/man/jrunscript.1 index 17c6edbfd3e..627555c93ce 100644 --- a/src/java.scripting/share/man/jrunscript.1 +++ b/src/java.scripting/share/man/jrunscript.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JRUNSCRIPT" "1" "2020" "JDK 15" "JDK Commands" +.TH "JRUNSCRIPT" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.aot/share/man/jaotc.1 b/src/jdk.aot/share/man/jaotc.1 index eb8090dc52b..e5056d02432 100644 --- a/src/jdk.aot/share/man/jaotc.1 +++ b/src/jdk.aot/share/man/jaotc.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAOTC" "1" "2020" "JDK 15" "JDK Commands" +.TH "JAOTC" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java index ab789be7708..73cd45f7fac 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java @@ -25,6 +25,7 @@ package com.sun.tools.javac.model; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -198,43 +199,48 @@ private S unboundNameToSymbol(String methodName, return (S) resultCache.computeIfAbsent(Pair.of(methodName, nameStr), p -> { Set found = new LinkedHashSet<>(); + Set allModules = new HashSet<>(modules.allModules()); - for (ModuleSymbol msym : modules.allModules()) { - S sym = nameToSymbol(msym, nameStr, clazz); + allModules.removeAll(modules.getRootModules()); - if (sym == null) - continue; + for (Set modules : Arrays.asList(modules.getRootModules(), allModules)) { + for (ModuleSymbol msym : modules) { + S sym = nameToSymbol(msym, nameStr, clazz); + + if (sym == null) + continue; - if (clazz == ClassSymbol.class) { - // Always include classes - found.add(sym); - } else if (clazz == PackageSymbol.class) { - // In module mode, ignore the "spurious" empty packages that "enclose" module-specific packages. - // For example, if a module contains classes or package info in package p.q.r, it will also appear - // to have additional packages p.q and p, even though these packages have no content other - // than the subpackage. We don't want those empty packages showing up in searches for p or p.q. - if (!sym.members().isEmpty() || ((PackageSymbol) sym).package_info != null) { + if (clazz == ClassSymbol.class) { + // Always include classes found.add(sym); + } else if (clazz == PackageSymbol.class) { + // In module mode, ignore the "spurious" empty packages that "enclose" module-specific packages. + // For example, if a module contains classes or package info in package p.q.r, it will also appear + // to have additional packages p.q and p, even though these packages have no content other + // than the subpackage. We don't want those empty packages showing up in searches for p or p.q. + if (!sym.members().isEmpty() || ((PackageSymbol) sym).package_info != null) { + found.add(sym); + } } } - } - if (found.size() == 1) { - return Optional.of(found.iterator().next()); - } else if (found.size() > 1) { - //more than one element found, produce a note: - if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) { - String moduleNames = found.stream() - .map(s -> s.packge().modle) - .map(m -> m.toString()) - .collect(Collectors.joining(", ")); - log.note(Notes.MultipleElements(methodName, nameStr, moduleNames)); + if (found.size() == 1) { + return Optional.of(found.iterator().next()); + } else if (found.size() > 1) { + //more than one element found, produce a note: + if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) { + String moduleNames = found.stream() + .map(s -> s.packge().modle) + .map(m -> m.toString()) + .collect(Collectors.joining(", ")); + log.note(Notes.MultipleElements(methodName, nameStr, moduleNames)); + } + return Optional.empty(); + } else { + //not found, try another option } - return Optional.empty(); - } else { - //not found: - return Optional.empty(); } + return Optional.empty(); }).orElse(null); } diff --git a/src/jdk.compiler/share/man/javac.1 b/src/jdk.compiler/share/man/javac.1 index a4ea5962b3c..1e2b536b35a 100644 --- a/src/jdk.compiler/share/man/javac.1 +++ b/src/jdk.compiler/share/man/javac.1 @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAVAC" "1" "2020" "JDK 15" "JDK Commands" +.TH "JAVAC" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.compiler/share/man/serialver.1 b/src/jdk.compiler/share/man/serialver.1 index f5451872557..140b940aad6 100644 --- a/src/jdk.compiler/share/man/serialver.1 +++ b/src/jdk.compiler/share/man/serialver.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "SERIALVER" "1" "2020" "JDK 15" "JDK Commands" +.TH "SERIALVER" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java index 871ba282747..b038917954d 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java @@ -118,7 +118,7 @@ public class VM { public static int Flags_INTERNAL; public static int Flags_JIMAGE_RESOURCE; private static int Flags_VALUE_ORIGIN_MASK; - private static int Flags_ORIG_COMMAND_LINE; + private static int Flags_WAS_SET_ON_COMMAND_LINE; /** This is only present in a non-core build */ private CodeCache codeCache; /** This is only present in a C1 build */ @@ -195,7 +195,7 @@ public String getOriginString() { return "management"; } else if (origin == Flags_ERGONOMIC) { String result = ""; - if ((flags & Flags_ORIG_COMMAND_LINE) == Flags_ORIG_COMMAND_LINE) { + if ((flags & Flags_WAS_SET_ON_COMMAND_LINE) == Flags_WAS_SET_ON_COMMAND_LINE) { result = "command line, "; } return result + "ergonomic"; @@ -490,17 +490,17 @@ private VM(TypeDataBase db, JVMDebugger debugger, boolean isBigEndian) { bytesPerLong = db.lookupIntConstant("BytesPerLong").intValue(); bytesPerWord = db.lookupIntConstant("BytesPerWord").intValue(); heapWordSize = db.lookupIntConstant("HeapWordSize").intValue(); - Flags_DEFAULT = db.lookupIntConstant("JVMFlag::DEFAULT").intValue(); - Flags_COMMAND_LINE = db.lookupIntConstant("JVMFlag::COMMAND_LINE").intValue(); - Flags_ENVIRON_VAR = db.lookupIntConstant("JVMFlag::ENVIRON_VAR").intValue(); - Flags_CONFIG_FILE = db.lookupIntConstant("JVMFlag::CONFIG_FILE").intValue(); - Flags_MANAGEMENT = db.lookupIntConstant("JVMFlag::MANAGEMENT").intValue(); - Flags_ERGONOMIC = db.lookupIntConstant("JVMFlag::ERGONOMIC").intValue(); - Flags_ATTACH_ON_DEMAND = db.lookupIntConstant("JVMFlag::ATTACH_ON_DEMAND").intValue(); - Flags_INTERNAL = db.lookupIntConstant("JVMFlag::INTERNAL").intValue(); - Flags_JIMAGE_RESOURCE = db.lookupIntConstant("JVMFlag::JIMAGE_RESOURCE").intValue(); + Flags_DEFAULT = db.lookupIntConstant("JVMFlagOrigin::DEFAULT").intValue(); + Flags_COMMAND_LINE = db.lookupIntConstant("JVMFlagOrigin::COMMAND_LINE").intValue(); + Flags_ENVIRON_VAR = db.lookupIntConstant("JVMFlagOrigin::ENVIRON_VAR").intValue(); + Flags_CONFIG_FILE = db.lookupIntConstant("JVMFlagOrigin::CONFIG_FILE").intValue(); + Flags_MANAGEMENT = db.lookupIntConstant("JVMFlagOrigin::MANAGEMENT").intValue(); + Flags_ERGONOMIC = db.lookupIntConstant("JVMFlagOrigin::ERGONOMIC").intValue(); + Flags_ATTACH_ON_DEMAND = db.lookupIntConstant("JVMFlagOrigin::ATTACH_ON_DEMAND").intValue(); + Flags_INTERNAL = db.lookupIntConstant("JVMFlagOrigin::INTERNAL").intValue(); + Flags_JIMAGE_RESOURCE = db.lookupIntConstant("JVMFlagOrigin::JIMAGE_RESOURCE").intValue(); Flags_VALUE_ORIGIN_MASK = db.lookupIntConstant("JVMFlag::VALUE_ORIGIN_MASK").intValue(); - Flags_ORIG_COMMAND_LINE = db.lookupIntConstant("JVMFlag::ORIG_COMMAND_LINE").intValue(); + Flags_WAS_SET_ON_COMMAND_LINE = db.lookupIntConstant("JVMFlag::WAS_SET_ON_COMMAND_LINE").intValue(); oopSize = db.lookupIntConstant("oopSize").intValue(); intType = db.lookupType("int"); diff --git a/src/jdk.hotspot.agent/share/man/jhsdb.1 b/src/jdk.hotspot.agent/share/man/jhsdb.1 index cf00c062729..c5891964668 100644 --- a/src/jdk.hotspot.agent/share/man/jhsdb.1 +++ b/src/jdk.hotspot.agent/share/man/jhsdb.1 @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JHSDB" "1" "2020" "JDK 15" "JDK Commands" +.TH "JHSDB" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpContext.java b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpContext.java index a6161e5b674..405d4acb818 100644 --- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpContext.java +++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpContext.java @@ -28,15 +28,18 @@ import java.util.Map; /** - * HttpContext represents a mapping between the root URI path of an application - * to a {@link HttpHandler} which is invoked to handle requests destined - * for that path on the associated HttpServer or HttpsServer. - *

        - * HttpContext instances are created by the create methods in HttpServer - * and HttpsServer - *

        - * A chain of {@link Filter} objects can be added to a HttpContext. All exchanges processed by the - * context can be pre- and post-processed by each Filter in the chain. + * {@code HttpContext} represents a mapping between the root {@link java.net.URI} + * path of an application to a {@link HttpHandler} which is invoked to handle + * requests destined for that path on the associated {@link HttpServer} or + * {@link HttpsServer}. + * + *

        {@code HttpContext} instances are created by the create methods in + * {@code HttpServer} and {@code HttpsServer}. + * + *

        A chain of {@link Filter} objects can be added to a {@code HttpContext}. + * All exchanges processed by the context can be pre- and post-processed by each + * {@code Filter} in the chain. + * * @since 1.6 */ public abstract class HttpContext { @@ -44,73 +47,79 @@ public abstract class HttpContext { /** * Constructor for subclasses to call. */ - protected HttpContext () { + protected HttpContext() { } /** - * returns the handler for this context - * @return the HttpHandler for this context + * Returns the handler for this context. + * + * @return the {@code HttpHandler} for this context */ - public abstract HttpHandler getHandler () ; + public abstract HttpHandler getHandler(); /** * Sets the handler for this context, if not already set. - * @param h the handler to set for this context - * @throws IllegalArgumentException if this context's handler is already set. - * @throws NullPointerException if handler is null + * + * @param handler the handler to set for this context + * @throws IllegalArgumentException if the context for this handler is already set. + * @throws NullPointerException if handler is {@code null} */ - public abstract void setHandler (HttpHandler h) ; + public abstract void setHandler(HttpHandler handler); /** - * returns the path this context was created with - * @return this context's path + * Returns the path this context was created with. + * + * @return the context of this path */ - public abstract String getPath() ; + public abstract String getPath(); /** - * returns the server this context was created with - * @return this context's server + * Returns the server this context was created with. + * + * @return the context of this server */ - public abstract HttpServer getServer () ; + public abstract HttpServer getServer(); /** - * returns a mutable Map, which can be used to pass - * configuration and other data to Filter modules - * and to the context's exchange handler. - *

        - * Every attribute stored in this Map will be visible to - * every HttpExchange processed by this context + * Returns a mutable {@link Map}, which can be used to pass configuration + * and other data to {@link Filter} modules and to the context's exchange + * handler. + * + *

        Every attribute stored in this {@code Map} will be visible to every + * {@code HttpExchange} processed by this context. * - * @return a map containing the attributes of this context + * @return a {@code Map} containing the attributes of this context */ public abstract Map getAttributes() ; /** - * returns this context's list of Filters. This is the - * actual list used by the server when dispatching requests - * so modifications to this list immediately affect the - * the handling of exchanges. + * Returns this context's {@link List} of {@linkplain Filter filters}. This + * is the actual list used by the server when dispatching requests so + * modifications to this list immediately affect the the handling of exchanges. + * + * @return a {@link List} containing the filters of this context */ public abstract List getFilters(); /** - * Sets the Authenticator for this HttpContext. Once an authenticator - * is establised on a context, all client requests must be - * authenticated, and the given object will be invoked to validate each - * request. Each call to this method replaces any previous value set. - * @param auth the authenticator to set. If null then any - * previously set authenticator is removed, - * and client authentication will no longer be required. - * @return the previous Authenticator, if any set, or null - * otherwise. + * Sets the {@link Authenticator} for this {@code HttpContext}. Once an authenticator + * is establised on a context, all client requests must be authenticated, + * and the given object will be invoked to validate each request. Each call + * to this method replaces any previous value set. + * + * @param auth the {@code Authenticator} to set. If {@code null} then any previously + * set {@code Authenticator} is removed, and client authentication + * will no longer be required. + * @return the previous {@code Authenticator}, if any set, or {@code null} otherwise. */ - public abstract Authenticator setAuthenticator (Authenticator auth); + public abstract Authenticator setAuthenticator(Authenticator auth); /** - * Returns the currently set Authenticator for this context + * Returns the currently set {@link Authenticator} for this context * if one exists. - * @return this HttpContext's Authenticator, or null - * if none is set. + * + * @return this {@linkplain HttpContext HttpContext's} {@code Authenticator}, + * or {@code null} if none is set */ - public abstract Authenticator getAuthenticator (); + public abstract Authenticator getAuthenticator(); } diff --git a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpHandler.java b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpHandler.java index 8ea7024e686..8f54bb1530f 100644 --- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpHandler.java +++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpHandler.java @@ -30,6 +30,7 @@ /** * A handler which is invoked to process HTTP exchanges. Each * HTTP exchange is handled by one of these handlers. + * * @since 1.6 */ public interface HttpHandler { @@ -37,9 +38,10 @@ public interface HttpHandler { * Handle the given request and generate an appropriate response. * See {@link HttpExchange} for a description of the steps * involved in handling an exchange. + * * @param exchange the exchange containing the request from the - * client and used to send the response - * @throws NullPointerException if exchange is null + * client and used to send the response + * @throws NullPointerException if exchange is {@code null} */ public abstract void handle (HttpExchange exchange) throws IOException; } diff --git a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpPrincipal.java b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpPrincipal.java index 863c74c9a38..43db2ab0474 100644 --- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpPrincipal.java +++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpPrincipal.java @@ -34,12 +34,14 @@ public class HttpPrincipal implements Principal { private String username, realm; /** - * creates a HttpPrincipal from the given username and realm - * @param username The name of the user within the realm - * @param realm The realm. - * @throws NullPointerException if either username or realm are null + * Creates a {@code HttpPrincipal} from the given {@code username} and + * {@code realm}. + * + * @param username the name of the user within the realm + * @param realm the realm for this user + * @throws NullPointerException if either username or realm are {@code null} */ - public HttpPrincipal (String username, String realm) { + public HttpPrincipal(String username, String realm) { if (username == null || realm == null) { throw new NullPointerException(); } @@ -48,12 +50,16 @@ public HttpPrincipal (String username, String realm) { } /** - * Compares two HttpPrincipal. Returns true - * if another is an instance of HttpPrincipal, and its - * username and realm are equal to this object's username - * and realm. Returns false otherwise. + * Compare two instances of {@code HttpPrincipal}. Returns {@code true} if + * another is an instance of {@code HttpPrincipal}, and its username + * and realm are equal to this object's username and realm. Returns {@code false} + * otherwise. + * + * @param another the object to compare this instance of {@code HttpPrincipal} against + * @return {@code true} or {@code false} depending on whether objects are + * equal or not */ - public boolean equals (Object another) { + public boolean equals(Object another) { if (!(another instanceof HttpPrincipal)) { return false; } @@ -63,41 +69,47 @@ public boolean equals (Object another) { } /** - * returns the contents of this principal in the form - * realm:username + * Returns the contents of this principal in the form + * realm:username. + * + * @return the contents of this principal in the form realm:username */ public String getName() { return username; } /** - * returns the username this object was created with. + * Returns the {@code username} this object was created with. * - * @return The name of the user assoicated with this object + * @return the name of the user associated with this object */ public String getUsername() { return username; } /** - * returns the realm this object was created with. + * Returns the {@code realm} this object was created with. * - * @return The realm associated with this object + * @return the realm associated with this object */ public String getRealm() { return realm; } /** - * returns a hashcode for this HttpPrincipal. This is calculated - * as (getUsername()+getRealm().hashCode() + * Returns a hashcode for this {@code HttpPrincipal}. This is calculated + * as {@code (getUsername()+getRealm()).hashCode()}. + * + * @return the hashcode for this object */ public int hashCode() { return (username+realm).hashCode(); } /** - * returns the same string as getName() + * Returns the same string as {@link #getName()}. + * + * @return the name associated with this object */ public String toString() { return getName(); diff --git a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpsConfigurator.java b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpsConfigurator.java index dbd46a5ac5b..8cd9e3affa2 100644 --- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpsConfigurator.java +++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpsConfigurator.java @@ -25,23 +25,17 @@ package com.sun.net.httpserver; -import java.net.*; -import java.io.*; -import java.nio.*; -import java.security.*; -import java.nio.channels.*; -import java.util.*; -import java.util.concurrent.*; -import javax.net.ssl.*; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; /** * This class is used to configure the https parameters for each incoming - * https connection on a HttpsServer. Applications need to override + * https connection on a {@link HttpsServer}. Applications need to override * the {@link #configure(HttpsParameters)} method in order to change * the default configuration. - *

        - * The following example shows how this may be done: + * + *

        The following example shows how this may be done: * *

          * SSLContext sslContext = SSLContext.getInstance (....);
        @@ -65,6 +59,7 @@
          *     }
          * });
          * 
        + * * @since 1.6 */ public class HttpsConfigurator { @@ -72,11 +67,12 @@ public class HttpsConfigurator { private SSLContext context; /** - * Creates an Https configuration, with the given SSLContext. - * @param context the SSLContext to use for this configurator - * @throws NullPointerException if no SSLContext supplied + * Creates a Https configuration, with the given {@link SSLContext}. + * + * @param context the {@code SSLContext} to use for this configurator + * @throws NullPointerException if no {@code SSLContext} supplied */ - public HttpsConfigurator (SSLContext context) { + public HttpsConfigurator(SSLContext context) { if (context == null) { throw new NullPointerException ("null SSLContext"); } @@ -84,33 +80,33 @@ public HttpsConfigurator (SSLContext context) { } /** - * Returns the SSLContext for this HttpsConfigurator. - * @return the SSLContext + * Returns the {@link SSLContext} for this {@code HttpsConfigurator}. + * + * @return the {@code SSLContext} */ public SSLContext getSSLContext() { return context; } -//BEGIN_TIGER_EXCLUDE /** - * Called by the HttpsServer to configure the parameters - * for a https connection currently being established. - * The implementation of configure() must call - * {@link HttpsParameters#setSSLParameters(SSLParameters)} - * in order to set the SSL parameters for the connection. - *

        - * The default implementation of this method uses the - * SSLParameters returned from

        - * {@code getSSLContext().getDefaultSSLParameters()} - *

        - * configure() may be overridden in order to modify this behavior. - * See, the example above. - * @param params the HttpsParameters to be configured. + * Called by the {@link HttpsServer} to configure the parameters for a https + * connection currently being established. The implementation of configure() + * must call {@link HttpsParameters#setSSLParameters(SSLParameters)} in order + * to set the SSL parameters for the connection. + * + *

        The default implementation of this method uses the + * SSLParameters returned from: + * + *

        {@code getSSLContext().getDefaultSSLParameters()} + * + *

        configure() may be overridden in order to modify this behavior. See + * example above. + * + * @param params the {@code HttpsParameters} to be configured * * @since 1.6 */ - public void configure (HttpsParameters params) { + public void configure(HttpsParameters params) { params.setSSLParameters (getSSLContext().getDefaultSSLParameters()); } -//END_TIGER_EXCLUDE } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java index 650d3f048af..b04b1fa4e8b 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java @@ -122,7 +122,11 @@ protected HotSpotConstantReflectionProvider createConstantReflection(HotSpotJVMC } private static RegisterConfig createRegisterConfig(AArch64HotSpotVMConfig config, TargetDescription target) { - return new AArch64HotSpotRegisterConfig(target, config.useCompressedOops); + // ARMv8 defines r18 as being available to the platform ABI. Windows + // and Darwin use it for such. Linux doesn't assign it and thus r18 can + // be used as an additional register. + boolean canUsePlatformRegister = config.linuxOs; + return new AArch64HotSpotRegisterConfig(target, config.useCompressedOops, canUsePlatformRegister); } protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntime runtime, TargetDescription target, RegisterConfig regConfig) { diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java index 68213e7fed1..72b13ff6ac6 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java @@ -34,6 +34,7 @@ import static jdk.vm.ci.aarch64.AArch64.rscratch1; import static jdk.vm.ci.aarch64.AArch64.rscratch2; import static jdk.vm.ci.aarch64.AArch64.r12; +import static jdk.vm.ci.aarch64.AArch64.r18; import static jdk.vm.ci.aarch64.AArch64.r27; import static jdk.vm.ci.aarch64.AArch64.r28; import static jdk.vm.ci.aarch64.AArch64.r29; @@ -122,15 +123,21 @@ public RegisterAttributes[] getAttributesMap() { */ public static final Register metaspaceMethodRegister = r12; + /** + * The platform ABI can use r18 to carry inter-procedural state (e.g. thread + * context). If not defined as such by the platform ABI, it can be used as + * additional temporary register. + */ + public static final Register platformRegister = r18; public static final Register heapBaseRegister = r27; public static final Register threadRegister = r28; public static final Register fp = r29; private static final RegisterArray reservedRegisters = new RegisterArray(rscratch1, rscratch2, threadRegister, fp, lr, r31, zr, sp); - private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase) { + private static RegisterArray initAllocatable(Architecture arch, boolean reserveForHeapBase, boolean canUsePlatformRegister) { RegisterArray allRegisters = arch.getAvailableValueRegisters(); - Register[] registers = new Register[allRegisters.size() - reservedRegisters.size() - (reserveForHeapBase ? 1 : 0)]; + Register[] registers = new Register[allRegisters.size() - reservedRegisters.size() - (reserveForHeapBase ? 1 : 0) - (!canUsePlatformRegister ? 1 : 0)]; List reservedRegistersList = reservedRegisters.asList(); int idx = 0; @@ -139,6 +146,9 @@ private static RegisterArray initAllocatable(Architecture arch, boolean reserveF // skip reserved registers continue; } + if (!canUsePlatformRegister && reg.equals(platformRegister)) { + continue; + } assert !(reg.equals(threadRegister) || reg.equals(fp) || reg.equals(lr) || reg.equals(r31) || reg.equals(zr) || reg.equals(sp)); if (reserveForHeapBase && reg.equals(heapBaseRegister)) { // skip heap base register @@ -152,8 +162,8 @@ private static RegisterArray initAllocatable(Architecture arch, boolean reserveF return new RegisterArray(registers); } - public AArch64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops) { - this(target, initAllocatable(target.arch, useCompressedOops)); + public AArch64HotSpotRegisterConfig(TargetDescription target, boolean useCompressedOops, boolean canUsePlatformRegister) { + this(target, initAllocatable(target.arch, useCompressedOops, canUsePlatformRegister)); assert callerSaved.size() >= allocatable.size(); } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java index bdccf28d68b..a7c2aa5d203 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java @@ -404,6 +404,14 @@ JavaConstant readFieldValue(HotSpotResolvedJavaField field, Object obj, boolean assert obj != null; assert !field.isStatic() || obj instanceof Class; long displacement = field.getOffset(); + if (obj instanceof Class && field.getName().equals("componentType")) { + Class clazz = (Class) obj; + if (!clazz.isArray()) { + // Class.componentType for non-array classes can transiently contain an int[] that's + // used for locking so always return null to mimic Class.getComponentType() + return JavaConstant.NULL_POINTER; + } + } assert checkRead(field.getJavaKind(), displacement, (HotSpotResolvedObjectType) runtime().getHostJVMCIBackend().getMetaAccess().lookupJavaType(field.isStatic() ? (Class) obj : obj.getClass()), diff --git a/src/jdk.jartool/share/classes/jdk/security/jarsigner/JarSigner.java b/src/jdk.jartool/share/classes/jdk/security/jarsigner/JarSigner.java index 10da7f56dd1..4a17faec022 100644 --- a/src/jdk.jartool/share/classes/jdk/security/jarsigner/JarSigner.java +++ b/src/jdk.jartool/share/classes/jdk/security/jarsigner/JarSigner.java @@ -34,7 +34,6 @@ import sun.security.pkcs.PKCS9Attributes; import sun.security.timestamp.HttpTimestamper; import sun.security.tools.PathList; -import sun.security.tools.jarsigner.TimestampedSigner; import sun.security.util.Event; import sun.security.util.ManifestDigester; import sun.security.util.SignatureFileVerifier; @@ -122,7 +121,6 @@ public static class Builder { String tSADigestAlg; boolean sectionsonly = false; boolean internalsf = false; - boolean directsign = false; String altSignerPath; String altSigner; @@ -358,10 +356,6 @@ public Builder eventHandler(BiConsumer handler) { *

      2. "sectionsonly": "true" if the .SF file only contains the hash * value for each section of the manifest and not for the whole * manifest, "false" otherwise. Default "false". - *
      3. "directsign": "true" if the signature is calculated on the - * content directly, "false" if it's calculated on signed attributes - * which itself is calculated from the content and stored in the - * signer's SignerInfo. Default "false". *
    * All property names are case-insensitive. * @@ -395,9 +389,6 @@ public Builder setProperty(String key, String value) { case "sectionsonly": this.sectionsonly = parseBoolean("sectionsonly", value); break; - case "directsign": - this.directsign = parseBoolean("directsign", value); - break; case "altsignerpath": altSignerPath = value; break; @@ -510,7 +501,6 @@ public JarSigner build() { private final String tSADigestAlg; private final boolean sectionsonly; // do not "sign" the whole manifest private final boolean internalsf; // include the .SF inside the PKCS7 block - private final boolean directsign; @Deprecated(since="16", forRemoval=true) private final String altSignerPath; @@ -561,9 +551,12 @@ private JarSigner(JarSigner.Builder builder) { this.altSigner = builder.altSigner; this.altSignerPath = builder.altSignerPath; - this.directsign = this.altSigner != null - ? true - : builder.directsign; + // altSigner cannot support modern algorithms like RSASSA-PSS and EdDSA + if (altSigner != null + && !sigalg.toUpperCase(Locale.ENGLISH).contains("WITH")) { + throw new IllegalArgumentException( + "Customized ContentSigner is not supported for " + sigalg); + } } /** @@ -666,8 +659,6 @@ public String getProperty(String key) { return Boolean.toString(sectionsonly); case "altsignerpath": return altSignerPath; - case "directsign": - return Boolean.toString(directsign); case "altsigner": return altSigner; default: @@ -855,20 +846,7 @@ private void sign0(ZipFile zipFile, OutputStream os) sf.write(baos); byte[] content = baos.toByteArray(); - // Use new method if directSign is false or it's a modern - // algorithm not supported by existing ContentSigner. - // Make this always true after we remove ContentSigner. - boolean useNewMethod = !directsign - || !sigalg.toUpperCase(Locale.ENGLISH).contains("WITH"); - - // For newer sigalg without "with", always use the new PKCS7 - // generateToken method. Otherwise, use deprecated ContentSigner. - if (useNewMethod) { - if (altSigner != null) { - throw new IllegalArgumentException(directsign - ? ("Customized ContentSigner is not supported for " + sigalg) - : "Customized ContentSigner does not support authenticated attributes"); - } + if (altSigner == null) { Function timestamper = null; if (tsaUrl != null) { timestamper = s -> { @@ -889,7 +867,7 @@ private void sign0(ZipFile zipFile, OutputStream os) } // We now create authAttrs in block data, so "direct == false". block = PKCS7.generateNewSignedData(sigalg, sigProvider, privateKey, certChain, - content, internalsf, directsign, timestamper); + content, internalsf, false, timestamper); } else { Signature signer = SignatureUtil.fromKey(sigalg, privateKey, sigProvider); signer.update(content); @@ -901,9 +879,7 @@ private void sign0(ZipFile zipFile, OutputStream os) tSADigestAlg, signature, signer.getAlgorithm(), certChain, content, zipFile); @SuppressWarnings("removal") - ContentSigner signingMechanism = (altSigner != null) - ? loadSigningMechanism(altSigner, altSignerPath) - : new TimestampedSigner(); + ContentSigner signingMechanism = loadSigningMechanism(altSigner, altSignerPath); block = signingMechanism.generateSignedData( params, !internalsf, diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java index a38c5e60623..23e04724eca 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java @@ -163,7 +163,6 @@ public static void main(String args[]) throws Exception { boolean debug = false; // debug boolean signManifest = true; // "sign" the whole manifest boolean externalSF = true; // leave the .SF out of the PKCS7 block - boolean directSign = false; // sign SF directly or thru signedAttrs boolean strict = false; // treat warnings as error boolean revocationCheck = false; // Revocation check flag @@ -473,8 +472,6 @@ String[] parseArgs(String args[]) throws Exception { signManifest = false; } else if (collator.compare(flags, "-internalsf") ==0) { externalSF = false; - } else if (collator.compare(flags, "-directsign") ==0) { - directSign = true; } else if (collator.compare(flags, "-verify") ==0) { verify = true; } else if (collator.compare(flags, "-verbose") ==0) { @@ -663,9 +660,6 @@ static void fullusage() { System.out.println(rb.getString (".internalsf.include.the.SF.file.inside.the.signature.block")); System.out.println(); - System.out.println(rb.getString - (".directsign.sign.the.SF.file.directly.no.signerinfo.signedattributes")); - System.out.println(); System.out.println(rb.getString (".sectionsonly.don.t.compute.hash.of.entire.manifest")); System.out.println(); @@ -1773,7 +1767,6 @@ void signJar(String jarName, String alias) builder.setProperty("sectionsOnly", Boolean.toString(!signManifest)); builder.setProperty("internalSF", Boolean.toString(!externalSF)); - builder.setProperty("directsign", Boolean.toString(directSign)); FileOutputStream fos = null; try { diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java index c58840ee319..7158e2f1f83 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java @@ -101,8 +101,6 @@ public class Resources extends java.util.ListResourceBundle { " (This option is deprecated and will be removed in a future release.)"}, {".internalsf.include.the.SF.file.inside.the.signature.block", "[-internalsf] include the .SF file inside the signature block"}, - {".directsign.sign.the.SF.file.directly.no.signerinfo.signedattributes", - "[-directsign] sign the .SF file directly (no SignerInfo signedAttributes)"}, {".sectionsonly.don.t.compute.hash.of.entire.manifest", "[-sectionsonly] don't compute hash of entire manifest"}, {".protected.keystore.has.protected.authentication.path", diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java deleted file mode 100644 index 035e758f490..00000000000 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.security.tools.jarsigner; - -import java.io.IOException; -import java.net.URI; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -import com.sun.jarsigner.*; -import sun.security.pkcs.PKCS7; - -/** - * This class implements a content signing service. - * It generates a timestamped signature for a given content according to - * RFC 3161. - * The signature along with a trusted timestamp and the signer's certificate - * are all packaged into a standard PKCS #7 Signed Data message. - * - * @author Vincent Ryan - */ -@Deprecated(since="16", forRemoval=true) -@SuppressWarnings("removal") -public final class TimestampedSigner extends ContentSigner { - - /** - * Instantiates a content signer that supports timestamped signatures. - */ - public TimestampedSigner() { - } - - /** - * Generates a PKCS #7 signed data message that includes a signature - * timestamp. - * This method is used when a signature has already been generated. - * The signature, a signature timestamp, the signer's certificate chain, - * and optionally the content that was signed, are packaged into a PKCS #7 - * signed data message. - * - * @param params The non-null input parameters. - * @param omitContent true if the content should be omitted from the - * signed data message. Otherwise the content is included. - * @param applyTimestamp true if the signature should be timestamped. - * Otherwise timestamping is not performed. - * @return A PKCS #7 signed data message including a signature timestamp. - * @throws NoSuchAlgorithmException The exception is thrown if the signature - * algorithm is unrecognised. - * @throws CertificateException The exception is thrown if an error occurs - * while processing the signer's certificate or the TSA's - * certificate. - * @throws IOException The exception is thrown if an error occurs while - * generating the signature timestamp or while generating the signed - * data message. - * @throws NullPointerException The exception is thrown if parameters is - * null. - */ - public byte[] generateSignedData(ContentSignerParameters params, - boolean omitContent, boolean applyTimestamp) - throws NoSuchAlgorithmException, CertificateException, IOException { - - if (params == null) { - throw new NullPointerException(); - } - - X509Certificate[] signerChain = params.getSignerCertificateChain(); - byte[] signature = params.getSignature(); - - // Include or exclude content - byte[] content = (omitContent == true) ? null : params.getContent(); - - URI tsaURI = null; - if (applyTimestamp) { - tsaURI = params.getTimestampingAuthority(); - if (tsaURI == null) { - // Examine TSA cert - tsaURI = PKCS7.getTimestampingURI( - params.getTimestampingAuthorityCertificate()); - if (tsaURI == null) { - throw new CertificateException( - "Subject Information Access extension not found"); - } - } - } - return PKCS7.generateSignedData(signature, signerChain, content, - params.getSignatureAlgorithm(), tsaURI, - params.getTSAPolicyID(), - params.getTSADigestAlg()); - } -} diff --git a/src/jdk.jartool/share/man/jar.1 b/src/jdk.jartool/share/man/jar.1 index 58e658712ca..b1861c59330 100644 --- a/src/jdk.jartool/share/man/jar.1 +++ b/src/jdk.jartool/share/man/jar.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAR" "1" "2020" "JDK 15" "JDK Commands" +.TH "JAR" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jartool/share/man/jarsigner.1 b/src/jdk.jartool/share/man/jarsigner.1 index 008c2d221c3..74001244a9f 100644 --- a/src/jdk.jartool/share/man/jarsigner.1 +++ b/src/jdk.jartool/share/man/jarsigner.1 @@ -1,4 +1,3 @@ -.\"t .\" Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" @@ -8,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -20,9 +19,10 @@ .\" or visit www.oracle.com if you need additional information or have any .\" questions. .\" +.\"t .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JARSIGNER" "1" "2020" "JDK 15" "JDK Commands" +.TH "JARSIGNER" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP @@ -290,18 +290,20 @@ implementation, then change the line to the following: .SH SUPPORTED ALGORITHMS .PP By default, the \f[CB]jarsigner\f[R] command signs a JAR file using one of -the following algorithms files depending on the type and size of the -private key: +the following algorithms and block file extensions depending on the type +and size of the private key: .PP .TS tab(@); -l l l. +l l l l. T{ keyalg T}@T{ keysize T}@T{ default sigalg +T}@T{ +block file extension T} _ T{ @@ -310,6 +312,8 @@ T}@T{ any size T}@T{ SHA256withDSA +T}@T{ +\&.DSA T} T{ RSA @@ -317,18 +321,22 @@ T}@T{ <= 3072 T}@T{ SHA256withRSA +T}@T{ +\&.RSA T} T{ T}@T{ <= 7680 T}@T{ SHA384withRSA +T}@T{ T} T{ T}@T{ > 7680 T}@T{ SHA512withRSA +T}@T{ T} T{ EC @@ -336,20 +344,70 @@ T}@T{ < 384 T}@T{ SHA256withECDSA +T}@T{ +\&.EC T} T{ T}@T{ < 512 T}@T{ SHA384withECDSA +T}@T{ T} T{ T}@T{ = 512 T}@T{ SHA512withECDSA +T}@T{ +T} +T{ +RSASSA\-PSS +T}@T{ +<= 3072 +T}@T{ +RSASSA\-PSS (with SHA\-256) +T}@T{ +\&.RSA +T} +T{ +T}@T{ +<= 7680 +T}@T{ +RSASSA\-PSS (with SHA\-384) +T}@T{ +T} +T{ +T}@T{ +> 7680 +T}@T{ +RSASSA\-PSS (with SHA\-512) +T}@T{ +T} +T{ +EdDSA +T}@T{ +255 +T}@T{ +Ed25519 +T}@T{ +\&.EC +T} +T{ +T}@T{ +448 +T}@T{ +Ed448 +T}@T{ T} .TE +.IP \[bu] 2 +If an RSASSA\-PSS key is encoded with parameters, then jarsigner will +use the same parameters in the signature. +Otherwise, jarsigner will use parameters that are determined by the size +of the key as specified in the table above. +For example, an 3072\-bit RSASSA\-PSS key will use RSASSA\-PSS as the +signature algorithm and SHA\-256 as the hash and MGF1 algorithms. .PP These default signature algorithms can be overridden by using the \f[CB]\-sigalg\f[R] option. @@ -393,12 +451,13 @@ A signature block file with a \f[CB]\&.DSA\f[R], \f[CB]\&.RSA\f[R], or The base file names for these two files come from the value of the \f[CB]\-sigfile\f[R] option. For example, when the option is \f[CB]\-sigfile\ MKSIGN\f[R], the files -are named \f[CB]MKSIGN.SF\f[R] and \f[CB]MKSIGN.DSA\f[R] +are named \f[CB]MKSIGN.SF\f[R] and \f[CB]MKSIGN.RSA\f[R]. +In this document, we assume the signer always uses an RSA key. .PP If no \f[CB]\-sigfile\f[R] option appears on the command line, then the -base file name for the \f[CB]\&.SF\f[R] and \f[CB]\&.DSA\f[R] files is the -first 8 characters of the alias name specified on the command line, all -converted to uppercase. +base file name for the \f[CB]\&.SF\f[R] and the signature block files is +the first 8 characters of the alias name specified on the command line, +all converted to uppercase. If the alias name has fewer than 8 characters, then the full alias name is used. If the alias name contains any characters that aren\[aq]t allowed in a @@ -442,7 +501,8 @@ This file also contains, encoded inside it, the certificate or certificate chain from the keystore that authenticates the public key corresponding to the private key used for signing. The file has the extension \f[CB]\&.DSA\f[R], \f[CB]\&.RSA\f[R], or -\f[CB]\&.EC\f[R], depending on the digest algorithm used. +\f[CB]\&.EC\f[R], depending on the key algorithm used. +See the table in \f[B]Supported Algorithms\f[R]. .SH SIGNATURE TIME STAMP .PP The \f[CB]jarsigner\f[R] command used with the following options generates @@ -468,9 +528,9 @@ Verify the signature of the \f[CB]\&.SF\f[R] file. .RS 4 .PP The verification ensures that the signature stored in each signature -block (\f[CB]\&.DSA\f[R]) file was generated using the private key -corresponding to the public key whose certificate (or certificate chain) -also appears in the \f[CB]\&.DSA\f[R] file. +block file was generated using the private key corresponding to the +public key whose certificate (or certificate chain) also appears in the +signature block file. It also ensures that the signature is a valid signature of the corresponding signature (\f[CB]\&.SF\f[R]) file, and thus the \f[CB]\&.SF\f[R] file wasn\[aq]t tampered with. @@ -543,7 +603,7 @@ jarsigner\ myBundle.jar\ kevin .fi .PP When a JAR file is signed multiple times, there are multiple -\f[CB]\&.SF\f[R] and \f[CB]\&.DSA\f[R] files in the resulting JAR file, one +\f[CB]\&.SF\f[R] and signature block files in the resulting JAR file, one pair for each signature. In the previous example, the output JAR file includes files with the following names: @@ -551,9 +611,9 @@ following names: .nf \f[CB] SUSAN.SF -SUSAN.DSA +SUSAN.RSA KEVIN.SF -KEVIN.DSA +KEVIN.RSA \f[R] .fi .SH OPTIONS FOR JARSIGNER @@ -701,10 +761,10 @@ by \f[B]Internet RFC 1421 Certificate Encoding Standard\f[R] .TP .B \f[CB]\-sigfile\f[R] \f[I]file\f[R] Specifies the base file name to be used for the generated \f[CB]\&.SF\f[R] -and \f[CB]\&.DSA\f[R] files. +and signature block files. For example, if file is \f[CB]DUKESIGN\f[R], then the generated -\f[CB]\&.SF\f[R] and \f[CB]\&.DSA\f[R] files are named \f[CB]DUKESIGN.SF\f[R] -and \f[CB]DUKESIGN.DSA\f[R], and placed in the \f[CB]META\-INF\f[R] +\f[CB]\&.SF\f[R] and signature block files are named \f[CB]DUKESIGN.SF\f[R] +and \f[CB]DUKESIGN.RSA\f[R], and placed in the \f[CB]META\-INF\f[R] directory of the signed JAR file. .RS .PP @@ -712,10 +772,10 @@ The characters in the file must come from the set \f[CB]a\-zA\-Z0\-9_\-\f[R]. Only letters, numbers, underscore, and hyphen characters are allowed. All lowercase characters are converted to uppercase for the -\f[CB]\&.SF\f[R] and \f[CB]\&.DSA\f[R] file names. +\f[CB]\&.SF\f[R] and signature block file names. .PP If no \f[CB]\-sigfile\f[R] option appears on the command line, then the -base file name for the \f[CB]\&.SF\f[R] and \f[CB]\&.DSA\f[R] files is the +base file name for the \f[CB]\&.SF\f[R] and signature block files is the first 8 characters of the alias name specified on the command line, all converted to upper case. If the alias name has fewer than 8 characters, then the full alias name @@ -804,7 +864,7 @@ If the \f[CB]\-certs\f[R] option appears on the command line with the \f[CB]\-verify\f[R] and \f[CB]\-verbose\f[R] options, then the output includes certificate information for each signer of the JAR file. This information includes the name of the type of certificate (stored in -the \f[CB]\&.DSA\f[R] file) that certifies the signer\[aq]s public key, +the signature block file) that certifies the signer\[aq]s public key, and if the certificate is an X.509 certificate (an instance of the \f[CB]java.security.cert.X509Certificate\f[R]), then the distinguished name of the signer. @@ -885,11 +945,11 @@ Standard Algorithm Names. .RE .TP .B \f[CB]\-internalsf\f[R] -In the past, the \f[CB]\&.DSA\f[R] (signature block) file generated when a -JAR file was signed included a complete encoded copy of the -\f[CB]\&.SF\f[R] file (signature file) also generated. +In the past, the signature block file generated when a JAR file was +signed included a complete encoded copy of the \f[CB]\&.SF\f[R] file +(signature file) also generated. This behavior has been changed. -To reduce the overall size of the output JAR file, the \f[CB]\&.DSA\f[R] +To reduce the overall size of the output JAR file, the signature block file by default doesn\[aq]t contain a copy of the \f[CB]\&.SF\f[R] file anymore. If \f[CB]\-internalsf\f[R] appears on the command line, then the old @@ -900,6 +960,15 @@ incurs higher overhead. .RS .RE .TP +.B \f[CB]\-directsign\f[R] +By default, jarsigner stores the hash of the \f[CB]\&.SF\f[R] file and +possibly other information in a SignerInfo signedAttributes field, and +then calculates the signature on this field. +If this option is set, no SignerInfo signedAttributes field is generated +and the signature is calculated on the \f[CB]\&.SF\f[R] file directly. +.RS +.RE +.TP .B \f[CB]\-sectionsonly\f[R] If the \f[CB]\-sectionsonly\f[R] option appears on the command line, then the \f[CB]\&.SF\f[R] file (signature file) generated when a JAR file is @@ -1213,6 +1282,15 @@ Informational warnings include those that aren\[aq]t errors but regarded as bad practice. They don\[aq]t have a code. .TP +.B extraAttributesDetected +The POSIX file permissions and/or symlink attributes are detected during +signing or verifying a JAR file. +The \f[CB]jarsigner\f[R] tool preserves these attributes in the newly +signed file but warns that these attributes are unsigned and not +protected by the signature. +.RS +.RE +.TP .B hasExpiringCert This JAR contains entries whose signer certificate expires within six months. @@ -1251,9 +1329,9 @@ JAR file \f[CB]sbundle.jar\f[R]: .RE .PP There is no \f[CB]\-sigfile\f[R] specified in the previous command so the -generated \f[CB]\&.SF\f[R] and \f[CB]\&.DSA\f[R] files to be placed in the +generated \f[CB]\&.SF\f[R] and signature block files to be placed in the signed JAR file have default names based on the alias name. -They are named \f[CB]JANE.SF\f[R] and \f[CB]JANE.DSA\f[R]. +They are named \f[CB]JANE.SF\f[R] and \f[CB]JANE.RSA\f[R]. .PP If you want to be prompted for the store password and the private key password, then you could shorten the previous command to the following: diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractOverviewIndexWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractOverviewIndexWriter.java index 9c90da89e3d..c042fa71429 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractOverviewIndexWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractOverviewIndexWriter.java @@ -46,8 +46,6 @@ */ public abstract class AbstractOverviewIndexWriter extends HtmlDocletWriter { - protected Navigation navBar; - /** * Constructs the AbstractOverviewIndexWriter. * @@ -57,32 +55,6 @@ public abstract class AbstractOverviewIndexWriter extends HtmlDocletWriter { public AbstractOverviewIndexWriter(HtmlConfiguration configuration, DocPath filename) { super(configuration, filename); - this.navBar = new Navigation(null, configuration, PageMode.OVERVIEW, path); - } - - /** - * Adds the top text (from the -top option), the upper - * navigation bar, and then the title (from the"-header" - * option), at the top of page. - * - * @param header the documentation tree to which the navigation bar header will be added - */ - protected void addNavigationBarHeader(Content header) { - addTop(header); - navBar.setUserHeader(getUserHeaderFooter(true)); - header.add(navBar.getContent(Navigation.Position.TOP)); - } - - /** - * Adds the lower navigation bar and the bottom text - * (from the -bottom option) at the bottom of page. - * - * @param footer the documentation tree to which the navigation bar footer will be added - */ - protected void addNavigationBarFooter(Content footer) { - navBar.setUserFooter(getUserHeaderFooter(false)); - footer.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(footer); } /** @@ -123,17 +95,13 @@ protected void buildOverviewIndexFile(String title, String description) throws DocFileIOException { String windowOverview = resources.getText(title); Content body = getBody(getWindowTitle(windowOverview)); - Content header = new ContentBuilder(); - addNavigationBarHeader(header); Content main = new ContentBuilder(); addOverviewHeader(main); addIndex(main); - Content footer = HtmlTree.FOOTER(); - addNavigationBarFooter(footer); body.add(new BodyContents() - .setHeader(header) + .setHeader(getHeader(PageMode.OVERVIEW)) .addMainContent(main) - .setFooter(footer)); + .setFooter(getFooter())); printHtmlDocument( configuration.metakeywords.getOverviewMetaKeywords(title, configuration.getOptions().docTitle()), description, body); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java index f1ad9e1febb..4aa82534667 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java @@ -30,7 +30,7 @@ import javax.lang.model.element.TypeElement; -import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.DeprecatedTree; import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; @@ -93,24 +93,15 @@ private static void generate(HtmlConfiguration configuration, IndexBuilder index */ protected void buildAllClassesFile() throws DocFileIOException { String label = resources.getText("doclet.All_Classes"); - Content header = new ContentBuilder(); - addTop(header); - Navigation navBar = new Navigation(null, configuration, PageMode.ALL_CLASSES, path); - navBar.setUserHeader(getUserHeaderFooter(true)); - header.add(navBar.getContent(Navigation.Position.TOP)); Content allClassesContent = new ContentBuilder(); addContents(allClassesContent); Content mainContent = new ContentBuilder(); mainContent.add(allClassesContent); - Content footer = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - footer.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(footer); HtmlTree bodyTree = getBody(getWindowTitle(label)); bodyTree.add(new BodyContents() - .setHeader(header) + .setHeader(getHeader(PageMode.ALL_CLASSES)) .addMainContent(mainContent) - .setFooter(footer)); + .setFooter(getFooter())); printHtmlDocument(null, "class index", bodyTree); } @@ -165,7 +156,7 @@ protected void addTableRow(Table table, TypeElement klass) { ContentBuilder description = new ContentBuilder(); if (utils.isDeprecated(klass)) { description.add(getDeprecatedPhrase(klass)); - List tags = utils.getDeprecatedTrees(klass); + List tags = utils.getDeprecatedTrees(klass); if (!tags.isEmpty()) { addSummaryDeprecatedComment(klass, tags.get(0), description); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllPackagesIndexWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllPackagesIndexWriter.java index 5201002b573..4b8a0da9a97 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllPackagesIndexWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllPackagesIndexWriter.java @@ -74,27 +74,18 @@ private static void generate(HtmlConfiguration configuration, DocPath fileName) */ protected void buildAllPackagesFile() throws DocFileIOException { String label = resources.getText("doclet.All_Packages"); - Content headerContent = new ContentBuilder(); - Navigation navBar = new Navigation(null, configuration, PageMode.ALL_PACKAGES, path); - addTop(headerContent); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); Content mainContent = new ContentBuilder(); addPackages(mainContent); Content titleContent = contents.allPackagesLabel; Content pHeading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING, HtmlStyle.title, titleContent); Content headerDiv = HtmlTree.DIV(HtmlStyle.header, pHeading); - Content footer = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - footer.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(footer); HtmlTree bodyTree = getBody(getWindowTitle(label)); bodyTree.add(new BodyContents() - .setHeader(headerContent) + .setHeader(getHeader(PageMode.ALL_PACKAGES)) .addMainContent(headerDiv) .addMainContent(mainContent) - .setFooter(footer)); + .setFooter(getFooter())); printHtmlDocument(null, "package index", bodyTree); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java index b83b9d54b7f..d87b8fab3ec 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java @@ -94,7 +94,6 @@ public class ClassUseWriter extends SubWriterHolderWriter { final ConstructorWriterImpl constrSubWriter; final FieldWriterImpl fieldSubWriter; final NestedClassWriterImpl classSubWriter; - private final Navigation navBar; /** * Constructor. @@ -147,7 +146,6 @@ public ClassUseWriter(HtmlConfiguration configuration, constrSubWriter.setFoundNonPubConstructor(true); fieldSubWriter = new FieldWriterImpl(this); classSubWriter = new NestedClassWriterImpl(this); - this.navBar = new Navigation(typeElement, configuration, PageMode.USE, path); } /** @@ -227,11 +225,7 @@ protected void generateClassUseFile() throws DocFileIOException { utils.getFullyQualifiedName(typeElement))); } bodyContents.addMainContent(mainContent); - HtmlTree footer = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - footer.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(footer); - bodyContents.setFooter(footer); + bodyContents.setFooter(getFooter()); body.add(bodyContents); String description = getDescription("use", typeElement); printHtmlDocument(null, description, body); @@ -425,17 +419,6 @@ protected HtmlTree getClassUseHeader() { String title = resources.getText("doclet.Window_ClassUse_Header", cltype, clname); HtmlTree bodyTree = getBody(getWindowTitle(title)); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - Content mdleLinkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement), - contents.moduleLabel); - navBar.setNavLinkModule(mdleLinkContent); - Content classLinkContent = getLink(new LinkInfoImpl( - configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement) - .label(resources.getText("doclet.Class"))); - navBar.setNavLinkClass(classLinkContent); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); ContentBuilder headingContent = new ContentBuilder(); headingContent.add(contents.getContent("doclet.ClassUse_Title", cltype)); headingContent.add(new HtmlTree(TagName.BR)); @@ -443,7 +426,19 @@ protected HtmlTree getClassUseHeader() { Content heading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING, HtmlStyle.title, headingContent); Content div = HtmlTree.DIV(HtmlStyle.header, heading); - bodyContents.setHeader(headerContent).addMainContent(div); + bodyContents.setHeader(getHeader(PageMode.USE, typeElement)).addMainContent(div); return bodyTree; } + + @Override + protected Navigation getNavBar(PageMode pageMode, Element element) { + Content mdleLinkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement), + contents.moduleLabel); + Content classLinkContent = getLink(new LinkInfoImpl( + configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement) + .label(resources.getText("doclet.Class"))); + return super.getNavBar(pageMode, element) + .setNavLinkModule(mdleLinkContent) + .setNavLinkClass(classLinkContent); + } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java index cb8acb741ff..adf1c3554f4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java @@ -41,6 +41,7 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.SimpleElementVisitor8; +import com.sun.source.doctree.DeprecatedTree; import com.sun.source.doctree.DocTree; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.Entity; @@ -89,8 +90,6 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite protected final ClassTree classtree; - private final Navigation navBar; - /** * @param configuration the configuration data for the doclet * @param typeElement the class being documented. @@ -102,20 +101,11 @@ public ClassWriterImpl(HtmlConfiguration configuration, TypeElement typeElement, this.typeElement = typeElement; configuration.currentTypeElement = typeElement; this.classtree = classTree; - this.navBar = new Navigation(typeElement, configuration, PageMode.CLASS, path); } @Override public Content getHeader(String header) { HtmlTree bodyTree = getBody(getWindowTitle(utils.getSimpleName(typeElement))); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement), - contents.moduleLabel); - navBar.setNavLinkModule(linkContent); - navBar.setMemberSummaryBuilder(configuration.getBuilderFactory().getMemberSummaryBuilder(this)); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); HtmlTree div = new HtmlTree(TagName.DIV); div.setStyle(HtmlStyle.header); if (configuration.showModules) { @@ -145,7 +135,7 @@ public Content getHeader(String header) { HtmlStyle.title, new StringContent(header)); heading.add(getTypeParameterLinks(linkInfo)); div.add(heading); - bodyContents.setHeader(headerContent) + bodyContents.setHeader(getHeader(PageMode.CLASS, typeElement)) .addMainContent(MarkerComments.START_OF_CLASS_DATA) .addMainContent(div); return bodyTree; @@ -156,14 +146,19 @@ public Content getClassContentHeader() { return getContentHeader(); } + @Override + protected Navigation getNavBar(PageMode pageMode, Element element) { + Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(element), + contents.moduleLabel); + return super.getNavBar(pageMode, element) + .setNavLinkModule(linkContent) + .setMemberSummaryBuilder(configuration.getBuilderFactory().getMemberSummaryBuilder(this)); + } + @Override public void addFooter() { bodyContents.addMainContent(MarkerComments.END_OF_CLASS_DATA); - Content htmlTree = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - htmlTree.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(htmlTree); - bodyContents.setFooter(htmlTree); + bodyContents.setFooter(getFooter()); } @Override @@ -507,7 +502,7 @@ public boolean isFunctionalInterface() { @Override public void addClassDeprecationInfo(Content classInfoTree) { - List deprs = utils.getBlockTags(typeElement, DocTree.Kind.DEPRECATED); + List deprs = utils.getDeprecatedTrees(typeElement); if (utils.isDeprecated(typeElement)) { Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(typeElement)); Content div = HtmlTree.DIV(HtmlStyle.deprecationBlock, deprLabel); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java index f146cc55066..6c7d62f70f4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java @@ -73,8 +73,6 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons */ private HtmlTree summaryTree; - private final Navigation navBar; - private final BodyContents bodyContents = new BodyContents(); private boolean hasConstants = false; @@ -88,7 +86,6 @@ public ConstantsSummaryWriterImpl(HtmlConfiguration configuration) { super(configuration, DocPaths.CONSTANT_VALUES); constantsTableHeader = new TableHeader( contents.modifierAndTypeLabel, contents.constantFieldLabel, contents.valueLabel); - this.navBar = new Navigation(null, configuration, PageMode.CONSTANT_VALUES, path); configuration.conditionalPages.add(HtmlConfiguration.ConditionalPage.CONSTANT_VALUES); } @@ -96,11 +93,7 @@ public ConstantsSummaryWriterImpl(HtmlConfiguration configuration) { public Content getHeader() { String label = resources.getText("doclet.Constants_Summary"); HtmlTree bodyTree = getBody(getWindowTitle(label)); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); - bodyContents.setHeader(headerContent); + bodyContents.setHeader(getHeader(PageMode.CONSTANT_VALUES)); return bodyTree; } @@ -271,11 +264,7 @@ public void addConstantSummaries(Content summariesTree) { @Override public void addFooter() { - Content htmlTree = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - htmlTree.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(htmlTree); - bodyContents.setFooter(htmlTree); + bodyContents.setFooter(getFooter()); } @Override diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java index 14bc4a6387c..78bc189d29b 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DeprecatedListWriter.java @@ -25,6 +25,7 @@ package jdk.javadoc.internal.doclets.formats.html; +import com.sun.source.doctree.DeprecatedTree; import jdk.javadoc.internal.doclets.formats.html.markup.Table; import jdk.javadoc.internal.doclets.formats.html.markup.TableHeader; @@ -206,8 +207,6 @@ private String getHeaderKey(DeprElementKind kind) { private EnumMap writerMap; - private final Navigation navBar; - /** * Constructor. * @@ -217,7 +216,6 @@ private String getHeaderKey(DeprElementKind kind) { public DeprecatedListWriter(HtmlConfiguration configuration, DocPath filename) { super(configuration, filename); - this.navBar = new Navigation(null, configuration, PageMode.DEPRECATED, path); NestedClassWriterImpl classW = new NestedClassWriterImpl(this); writerMap = new EnumMap<>(DeprElementKind.class); for (DeprElementKind kind : DeprElementKind.values()) { @@ -294,11 +292,7 @@ protected void generateDeprecatedListFile(DeprecatedAPIListBuilder deprAPI) } } bodyContents.addMainContent(content); - HtmlTree htmlTree = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - htmlTree.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(htmlTree); - bodyContents.setFooter(htmlTree); + bodyContents.setFooter(getFooter()); String description = "deprecated elements"; body.add(bodyContents); printHtmlDocument(null, description, body); @@ -355,11 +349,7 @@ public Content getContentsList(DeprecatedAPIListBuilder deprapi) { public HtmlTree getHeader() { String title = resources.getText("doclet.Window_Deprecated_List"); HtmlTree bodyTree = getBody(getWindowTitle(title)); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); - bodyContents.setHeader(headerContent); + bodyContents.setHeader(getHeader(PageMode.DEPRECATED)); return bodyTree; } @@ -397,7 +387,7 @@ protected void addDeprecatedAPI(SortedSet deprList, String id, String h link = getDeprecatedLink(e); } Content desc = new ContentBuilder(); - List tags = utils.getDeprecatedTrees(e); + List tags = utils.getDeprecatedTrees(e); if (!tags.isEmpty()) { addInlineDeprecatedComment(e, tags.get(0), desc); } else { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java index 162b35a4dcf..93c18d341e3 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/DocFilesHandlerImpl.java @@ -64,7 +64,6 @@ public class DocFilesHandlerImpl implements DocFilesHandler { public final DocPath source; public final HtmlConfiguration configuration; private final HtmlOptions options; - private Navigation navBar; /** * Constructor to construct the DocFilesWriter object. @@ -196,7 +195,9 @@ private void handleHtmlFile(DocFile srcfile, DocPath dstPath) throws DocFileIOEx DocFileElement dfElement = new DocFileElement(utils, element, fileObject); DocPath dfilePath = dstPath.resolve(srcfile.getName()); - HtmlDocletWriter docletWriter = new DocFileWriter(configuration, dfilePath, element); + PackageElement pkg = dfElement.getPackageElement(); + + HtmlDocletWriter docletWriter = new DocFileWriter(configuration, dfilePath, element, pkg); configuration.messages.notice("doclet.Generating_0", docletWriter.filename.getPath()); List localTags = getLocalHeaderTags(utils.getPreamble(dfElement)); @@ -204,30 +205,15 @@ private void handleHtmlFile(DocFile srcfile, DocPath dstPath) throws DocFileIOEx String title = getWindowTitle(docletWriter, dfElement).trim(); HtmlTree htmlContent = docletWriter.getBody(title); - PackageElement pkg = dfElement.getPackageElement(); - this.navBar = new Navigation(element, configuration, PageMode.DOC_FILE, docletWriter.path); - Content headerContent = new ContentBuilder(); - docletWriter.addTop(headerContent); - Content mdleLinkContent = docletWriter.getModuleLink(utils.elementUtils.getModuleOf(pkg), - docletWriter.contents.moduleLabel); - navBar.setNavLinkModule(mdleLinkContent); - Content pkgLinkContent = docletWriter.getPackageLink(pkg, docletWriter.contents.packageLabel); - navBar.setNavLinkPackage(pkgLinkContent); - navBar.setUserHeader(docletWriter.getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); List fullBody = utils.getFullBody(dfElement); Content pageContent = docletWriter.commentTagsToContent(null, dfElement, fullBody, false); docletWriter.addTagsInfo(dfElement, pageContent); - navBar.setUserFooter(docletWriter.getUserHeaderFooter(false)); - Content footer = HtmlTree.FOOTER(); - footer.add(navBar.getContent(Navigation.Position.BOTTOM)); - docletWriter.addBottom(footer); htmlContent.add(new BodyContents() - .setHeader(headerContent) + .setHeader(docletWriter.getHeader(PageMode.DOC_FILE, element)) .addMainContent(pageContent) - .setFooter(footer)); + .setFooter(docletWriter.getFooter())); docletWriter.printHtmlDocument(Collections.emptyList(), null, localTagsContent, Collections.emptyList(), htmlContent); } @@ -291,15 +277,17 @@ private String getWindowTitle(HtmlDocletWriter docletWriter, Element element) { } private static class DocFileWriter extends HtmlDocletWriter { + private final PackageElement pkg; /** * Constructor to construct the HtmlDocletWriter object. * - * @param configuration the configuration of this doclet. - * @param path the file to be generated. - * @param e the anchoring element. + * @param configuration the configuration of this doclet + * @param path the file to be generated + * @param e the anchoring element + * @param pkg the package containing the doc file */ - public DocFileWriter(HtmlConfiguration configuration, DocPath path, Element e) { + public DocFileWriter(HtmlConfiguration configuration, DocPath path, Element e, PackageElement pkg) { super(configuration, path); switch (e.getKind()) { case PACKAGE: @@ -308,6 +296,17 @@ public DocFileWriter(HtmlConfiguration configuration, DocPath path, Element e) { default: throw new AssertionError("unsupported element: " + e.getKind()); } + this.pkg = pkg; + } + + @Override + protected Navigation getNavBar(PageMode pageMode, Element element) { + Content mdleLinkContent = getModuleLink(utils.elementUtils.getModuleOf(element), + contents.moduleLabel); + Content pkgLinkContent = getPackageLink(pkg, contents.packageLabel); + return super.getNavBar(pageMode, element) + .setNavLinkModule(mdleLinkContent) + .setNavLinkPackage(pkgLinkContent); } } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java index 4f9124fdbb9..6e8400e24f6 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HelpWriter.java @@ -51,8 +51,6 @@ */ public class HelpWriter extends HtmlDocletWriter { - private final Navigation navBar; - private final String[][] SEARCH_EXAMPLES = { {"j.l.obj", "\"java.lang.Object\""}, {"InpStr", "\"java.io.InputStream\""}, @@ -67,7 +65,6 @@ public class HelpWriter extends HtmlDocletWriter { public HelpWriter(HtmlConfiguration configuration, DocPath filename) { super(configuration, filename); - this.navBar = new Navigation(null, configuration, PageMode.HELP, path); } /** @@ -93,20 +90,12 @@ public static void generate(HtmlConfiguration configuration) throws DocFileIOExc protected void generateHelpFile() throws DocFileIOException { String title = resources.getText("doclet.Window_Help_title"); HtmlTree body = getBody(getWindowTitle(title)); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); ContentBuilder helpFileContent = new ContentBuilder(); addHelpFileContents(helpFileContent); - HtmlTree footer = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - footer.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(footer); body.add(new BodyContents() - .setHeader(headerContent) + .setHeader(getHeader(PageMode.HELP)) .addMainContent(helpFileContent) - .setFooter(footer)); + .setFooter(getFooter())); printHtmlDocument(null, "help", body); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java index 2cc37855bb3..4b3d2f9defd 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java @@ -57,6 +57,7 @@ import com.sun.source.doctree.AttributeTree; import com.sun.source.doctree.AttributeTree.ValueKind; import com.sun.source.doctree.CommentTree; +import com.sun.source.doctree.DeprecatedTree; import com.sun.source.doctree.DocRootTree; import com.sun.source.doctree.DocTree; import com.sun.source.doctree.DocTree.Kind; @@ -486,46 +487,61 @@ public String getWindowTitle(String title) { } /** - * Get user specified header and the footer. + * Returns a {@code
    } element, containing the user "top" text, if any, + * amd the main navigation bar. * - * @param header if true print the user provided header else print the - * user provided footer. + * @param pageMode the pageMode used to configure the navigation bar + * + * @return the {@code
    } element */ - public Content getUserHeaderFooter(boolean header) { - String content; - if (header) { - content = replaceDocRootDir(options.header()); - } else { - if (options.footer().length() != 0) { - content = replaceDocRootDir(options.footer()); - } else { - content = replaceDocRootDir(options.header()); - } - } - Content rawContent = new RawHtml(content); - return rawContent; + protected HtmlTree getHeader(Navigation.PageMode pageMode) { + return getHeader(pageMode, null); + } + + /** + * Returns a {@code
    } element, containing the user "top" text, if any, + * amd the main navigation bar. + * + * @param pageMode the page mode used to configure the navigation bar + * @param element the element used to configure the navigation bar + * + * @return the {@code
    } element + */ + protected HtmlTree getHeader(Navigation.PageMode pageMode, Element element) { + return HtmlTree.HEADER() + .add(new RawHtml(replaceDocRootDir(options.top()))) + .add(getNavBar(pageMode, element).getContent()); } /** - * Adds the user specified top. + * Returns a basic navigation bar for a kind of page and element. + * + * @apiNote the result may be further configured by overriding this method * - * @param htmlTree the content tree to which user specified top will be added + * @param pageMode the page mode + * @param element the defining element for the navigation bar, or {@code null} if none + * @return the basic navigation bar */ - public void addTop(Content htmlTree) { - Content top = new RawHtml(replaceDocRootDir(options.top())); - htmlTree.add(top); + protected Navigation getNavBar(Navigation.PageMode pageMode, Element element) { + return new Navigation(element, configuration, pageMode, path) + .setUserHeader(new RawHtml(replaceDocRootDir(options.header()))); } /** - * Adds the user specified bottom. + * Returns a {@code
    } element containing the user's "bottom" text, + * or {@code null} if there is no such text. * - * @param htmlTree the content tree to which user specified bottom will be added + * @return the {@code
    } element or {@code null}. */ - public void addBottom(Content htmlTree) { - Content bottom = new RawHtml(replaceDocRootDir(options.bottom())); - Content small = HtmlTree.SMALL(bottom); - Content p = HtmlTree.P(HtmlStyle.legalCopy, small); - htmlTree.add(p); + public HtmlTree getFooter() { + String bottom = options.bottom(); + return (bottom == null || bottom.isEmpty()) + ? null + : HtmlTree.FOOTER() + .add(new HtmlTree(TagName.HR)) + .add(HtmlTree.P(HtmlStyle.legalCopy, + HtmlTree.SMALL( + new RawHtml(replaceDocRootDir(bottom))))); } /** @@ -1167,7 +1183,7 @@ public Content getDeprecatedPhrase(Element e) { * @param tag the inline tag to be added * @param htmltree the content tree to which the comment will be added */ - public void addInlineDeprecatedComment(Element e, DocTree tag, Content htmltree) { + public void addInlineDeprecatedComment(Element e, DeprecatedTree tag, Content htmltree) { CommentHelper ch = utils.getCommentHelper(e); addCommentTags(e, ch.getBody(tag), true, false, false, htmltree); } @@ -1193,7 +1209,7 @@ public void addSummaryComment(Element element, List firstSent addCommentTags(element, firstSentenceTags, false, true, true, htmltree); } - public void addSummaryDeprecatedComment(Element element, DocTree tag, Content htmltree) { + public void addSummaryDeprecatedComment(Element element, DeprecatedTree tag, Content htmltree) { CommentHelper ch = utils.getCommentHelper(element); List body = ch.getBody(tag); addCommentTags(element, ch.getFirstSentenceTrees(body), true, true, true, htmltree); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlOptions.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlOptions.java index 88fd3d6f003..f7b19aed7e0 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlOptions.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlOptions.java @@ -111,12 +111,6 @@ public class HtmlOptions extends BaseOptions { */ private String docTitle = ""; - - /** - * Argument for command-line option {@code -footer}. - */ - private String footer = ""; - /** * Argument for command-line option {@code -header}. */ @@ -235,7 +229,7 @@ public boolean process(String opt, List args) { new Option(resources, "-footer", 1) { @Override public boolean process(String opt, List args) { - footer = args.get(0); + messages.warning("doclet.footer_specified"); return true; } }, @@ -499,7 +493,6 @@ protected boolean validateOptions() { // to be handled here. Utils utils = config.utils; utils.checkJavaScriptInOption("-header", header); - utils.checkJavaScriptInOption("-footer", footer); utils.checkJavaScriptInOption("-top", top); utils.checkJavaScriptInOption("-bottom", bottom); utils.checkJavaScriptInOption("-doctitle", docTitle); @@ -593,13 +586,6 @@ String docTitle() { return docTitle; } - /** - * Argument for command-line option {@code -footer}. - */ - String footer() { - return footer; - } - /** * Argument for command-line option {@code -header}. */ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java index 013028288bd..039b3d45550 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java @@ -33,6 +33,7 @@ import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.SerialTree; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.TagName; @@ -165,7 +166,7 @@ public void addMemberDescription(VariableElement field, Content contentTree) { if (!utils.getFullBody(field).isEmpty()) { writer.addInlineComment(field, contentTree); } - List tags = utils.getBlockTags(field, DocTree.Kind.SERIAL); + List tags = utils.getSerialTrees(field); if (!tags.isEmpty()) { writer.addInlineComment(field, tags.get(0), contentTree); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java index 76e5174265e..1cc95cd1870 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java @@ -37,7 +37,7 @@ import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; -import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.DeprecatedTree; import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; @@ -123,28 +123,19 @@ protected void generateIndexFile(List allFirstCharacters, ? resources.getText("doclet.Window_Split_Index", displayFirstCharacters.get(0)) : resources.getText("doclet.Window_Single_Index"); HtmlTree body = getBody(getWindowTitle(title)); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - Navigation navBar = new Navigation(null, configuration, PageMode.INDEX, path); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); Content mainContent = new ContentBuilder(); addLinksForIndexes(allFirstCharacters, mainContent); for (Character ch : displayFirstCharacters) { addContents(ch, mainIndex.getItems(ch), mainContent); } addLinksForIndexes(allFirstCharacters, mainContent); - HtmlTree footer = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - footer.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(footer); body.add(new BodyContents() - .setHeader(headerContent) + .setHeader(getHeader(PageMode.INDEX)) .addMainContent(HtmlTree.DIV(HtmlStyle.header, HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, contents.getContent("doclet.Index")))) .addMainContent(mainContent) - .setFooter(footer)); + .setFooter(getFooter())); String description = splitIndex ? "index: " + displayFirstCharacters.get(0) : "index"; printHtmlDocument(null, description, body); @@ -300,13 +291,12 @@ protected void addTagDescription(IndexItem item, Content dlTree) { * @param contentTree the content tree to which the comment will be added */ protected void addComment(Element element, Content contentTree) { - List tags; Content span = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(element)); HtmlTree div = new HtmlTree(TagName.DIV); div.setStyle(HtmlStyle.deprecationBlock); if (utils.isDeprecated(element)) { div.add(span); - tags = utils.getBlockTags(element, DocTree.Kind.DEPRECATED); + List tags = utils.getDeprecatedTrees(element); if (!tags.isEmpty()) addInlineDeprecatedComment(element, tags.get(0), div); contentTree.add(div); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MarkerComments.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MarkerComments.java index 9a7826d77a0..a23cd867976 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MarkerComments.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MarkerComments.java @@ -43,24 +43,12 @@ public class MarkerComments { public static final Comment START_OF_TOP_NAVBAR = new Comment("========= START OF TOP NAVBAR ======="); - /** - * Marker to identify start of bottom navigation bar. - */ - public static final Comment START_OF_BOTTOM_NAVBAR = - new Comment("======= START OF BOTTOM NAVBAR ======"); - /** * Marker to identify end of top navigation bar. */ public static final Comment END_OF_TOP_NAVBAR = new Comment("========= END OF TOP NAVBAR ========="); - /** - * Marker to identify end of bottom navigation bar. - */ - public static final Comment END_OF_BOTTOM_NAVBAR = - new Comment("======== END OF BOTTOM NAVBAR ======="); - /** * Marker to identify start of module description. */ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java index 44ab67c3079..6c1b645bc28 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java @@ -40,6 +40,7 @@ import javax.lang.model.element.TypeElement; import javax.lang.model.util.ElementFilter; +import com.sun.source.doctree.DeprecatedTree; import com.sun.source.doctree.DocTree; import jdk.javadoc.doclet.DocletEnvironment.ModuleMode; import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; @@ -159,8 +160,6 @@ class PackageEntry { private final Map providesTrees = new TreeMap<>(comparators.makeAllClassesComparator()); - private final Navigation navBar; - private final BodyContents bodyContents = new BodyContents(); /** @@ -173,7 +172,6 @@ public ModuleWriterImpl(HtmlConfiguration configuration, ModuleElement mdle) { super(configuration, configuration.docPaths.moduleSummary(mdle)); this.mdle = mdle; this.moduleMode = configuration.docEnv.getModuleMode(); - this.navBar = new Navigation(mdle, configuration, PageMode.MODULE, path); computeModulesData(); } @@ -185,15 +183,6 @@ public ModuleWriterImpl(HtmlConfiguration configuration, ModuleElement mdle) { @Override public Content getModuleHeader(String heading) { HtmlTree bodyTree = getBody(getWindowTitle(mdle.getQualifiedName().toString())); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - navBar.setDisplaySummaryModuleDescLink(!utils.getFullBody(mdle).isEmpty() && !options.noComment()); - navBar.setDisplaySummaryModulesLink(display(requires) || display(indirectModules)); - navBar.setDisplaySummaryPackagesLink(display(packages) || display(indirectPackages) - || display(indirectOpenPackages)); - navBar.setDisplaySummaryServicesLink(displayServices(uses, usesTrees) || displayServices(provides.keySet(), providesTrees)); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); HtmlTree div = new HtmlTree(TagName.DIV); div.setStyle(HtmlStyle.header); Content annotationContent = new HtmlTree(TagName.P); @@ -207,11 +196,21 @@ public Content getModuleHeader(String heading) { Content moduleHead = new RawHtml(heading); tHeading.add(moduleHead); div.add(tHeading); - bodyContents.setHeader(headerContent) + bodyContents.setHeader(getHeader(PageMode.MODULE, mdle)) .addMainContent(div); return bodyTree; } + @Override + protected Navigation getNavBar(PageMode pageMode, Element element) { + return super.getNavBar(pageMode, element) + .setDisplaySummaryModuleDescLink(!utils.getFullBody(mdle).isEmpty() && !options.noComment()) + .setDisplaySummaryModulesLink(display(requires) || display(indirectModules)) + .setDisplaySummaryPackagesLink(display(packages) || display(indirectPackages) + || display(indirectOpenPackages)) + .setDisplaySummaryServicesLink(displayServices(uses, usesTrees) || displayServices(provides.keySet(), providesTrees)); + } + /** * Get the content header. */ @@ -369,14 +368,14 @@ public void computeModulesData() { } }); // Generate the map of all services listed using @provides, and the description. - utils.getBlockTags(mdle, DocTree.Kind.PROVIDES).forEach(tree -> { + utils.getProvidesTrees(mdle).forEach(tree -> { TypeElement t = ch.getServiceType(tree); if (t != null) { providesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(tree), false, true)); } }); // Generate the map of all services listed using @uses, and the description. - utils.getBlockTags(mdle, DocTree.Kind.USES).forEach(tree -> { + utils.getUsesTrees(mdle).forEach(tree -> { TypeElement t = ch.getServiceType(tree); if (t != null) { usesTrees.put(t, commentTagsToContent(tree, mdle, ch.getDescription(tree), false, true)); @@ -802,7 +801,7 @@ public void addProvidesList(Table table) { * @param div the content tree to which the deprecation information will be added */ public void addDeprecationInfo(Content div) { - List deprs = utils.getBlockTags(mdle, DocTree.Kind.DEPRECATED); + List deprs = utils.getDeprecatedTrees(mdle); if (utils.isDeprecated(mdle)) { CommentHelper ch = utils.getCommentHelper(mdle); HtmlTree deprDiv = new HtmlTree(TagName.DIV); @@ -839,11 +838,7 @@ public void addModuleContent(Content moduleContentTree) { @Override public void addModuleFooter() { - Content htmlTree = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - htmlTree.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(htmlTree); - bodyContents.setFooter(htmlTree); + bodyContents.setFooter(getFooter()); } @Override @@ -860,9 +855,8 @@ public void printDocument(Content contentTree) throws DocFileIOException { * @param pkg the PackageDoc that is added */ public void addPackageDeprecationInfo(Content li, PackageElement pkg) { - List deprs; if (utils.isDeprecated(pkg)) { - deprs = utils.getDeprecatedTrees(pkg); + List deprs = utils.getDeprecatedTrees(pkg); HtmlTree deprDiv = new HtmlTree(TagName.DIV); deprDiv.setStyle(HtmlStyle.deprecationBlock); Content deprPhrase = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(pkg)); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java index 3ce649ead92..31a40324d64 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Navigation.java @@ -80,7 +80,6 @@ public class Navigation { private boolean displaySummaryPackagesLink; private boolean displaySummaryServicesLink; private Content userHeader; - private Content userFooter; private final String rowListTitle; private final Content searchLabel; @@ -104,27 +103,6 @@ public enum PageMode { USE; } - enum Position { - BOTTOM(MarkerComments.START_OF_BOTTOM_NAVBAR, MarkerComments.END_OF_BOTTOM_NAVBAR), - TOP(MarkerComments.START_OF_TOP_NAVBAR, MarkerComments.END_OF_TOP_NAVBAR); - - final Content startOfNav; - final Content endOfNav; - - Position(Content startOfNav, Content endOfNav) { - this.startOfNav = startOfNav; - this.endOfNav = endOfNav; - } - - Content startOfNav() { - return startOfNav; - } - - Content endOfNav() { - return endOfNav; - } - } - /** * Creates a {@code Navigation} object for a specific file, to be written in a specific HTML * version. @@ -192,13 +170,8 @@ public Navigation setUserHeader(Content userHeader) { return this; } - public Navigation setUserFooter(Content userFooter) { - this.userFooter = userFooter; - return this; - } - /** - * Add the links for the main navigation. + * Adds the links for the main navigation. * * @param tree the content tree to which the main navigation will added */ @@ -356,7 +329,7 @@ private void addMainNavLinks(Content tree) { } /** - * Add the summary links to the sub-navigation. + * Adds the summary links to the sub-navigation. * * @param tree the content tree to which the sub-navigation will added */ @@ -436,7 +409,7 @@ private void addSummaryLinks(Content tree) { } /** - * Add the navigation summary link. + * Adds the navigation summary link. * * @param members members to be linked * @param vmt the visible member table @@ -461,7 +434,7 @@ private void addTypeSummaryLink(SortedSet members, } /** - * Add the navigation Type summary link. + * Adds the navigation Type summary link. * * @param typeElement the Type being documented * @param kind the kind of member being documented @@ -551,7 +524,7 @@ private void addTypeSummaryLink(TypeElement typeElement, VisibleMemberTable.Kind } /** - * Add the navigation Type summary link. + * Adds the navigation Type summary link. * * @param label the label to be added * @param kind the kind of member being documented @@ -598,7 +571,7 @@ private void addAnnotationTypeSummaryLink(String label, VisibleMemberTable.Kind } /** - * Add the detail links to sub-navigation. + * Adds the detail links to sub-navigation. * * @param tree the content tree to which the links will be added */ @@ -640,7 +613,7 @@ private void addDetailLinks(Content tree) { } /** - * Add the navigation Type detail link. + * Adds the navigation Type detail link. * * @param kind the kind of member being documented * @param link true if the members are listed and need to be linked @@ -689,7 +662,7 @@ protected void addTypeDetailLink(VisibleMemberTable.Kind kind, boolean link, Lis } /** - * Add the navigation Annotation Type detail link. + * Adds the navigation Annotation Type detail link. * * @param listContents the list of contents to which the annotation detail will be added. */ @@ -723,7 +696,7 @@ protected void addAnnotationTypeDetailLink(List listContents) { } /** - * Add the navigation Annotation Type detail link. + * Adds the navigation Annotation Type detail link. * * @param type the kind of member being documented * @param link true if the member details need to be linked @@ -906,12 +879,11 @@ private void addSearch(Content tree) { } /** - * Get the navigation content. + * Returns the navigation content. * - * @param posn the position for the navigation bar - * @return the navigation contents + * @return the navigation content */ - public Content getContent(Position posn) { + public Content getContent() { if (options.noNavbar()) { return new ContentBuilder(); } @@ -919,37 +891,15 @@ public Content getContent(Position posn) { HtmlTree navDiv = new HtmlTree(TagName.DIV); Content skipNavLinks = contents.getContent("doclet.Skip_navigation_links"); - SectionName navListSection; - Content aboutContent; - boolean addSearch; - switch (posn) { - case TOP: - tree.add(Position.TOP.startOfNav()); - navDiv.setStyle(HtmlStyle.topNav) - .setId(SectionName.NAVBAR_TOP.getName()) - .add(HtmlTree.DIV(HtmlStyle.skipNav, - links.createLink(SectionName.SKIP_NAVBAR_TOP, skipNavLinks, - skipNavLinks.toString(), ""))); - navListSection = SectionName.NAVBAR_TOP_FIRSTROW; - aboutContent = userHeader; - addSearch = options.createIndex(); - break; - - case BOTTOM: - tree.add(Position.BOTTOM.startOfNav()); - navDiv.setStyle(HtmlStyle.bottomNav) - .setId(SectionName.NAVBAR_BOTTOM.getName()) - .add(HtmlTree.DIV(HtmlStyle.skipNav, - links.createLink(SectionName.SKIP_NAVBAR_BOTTOM, skipNavLinks, - skipNavLinks.toString(), ""))); - navListSection = SectionName.NAVBAR_BOTTOM_FIRSTROW; - aboutContent = userFooter; - addSearch = false; - break; - - default: - throw new Error(); - } + tree.add(MarkerComments.START_OF_TOP_NAVBAR); + navDiv.setStyle(HtmlStyle.topNav) + .setId(SectionName.NAVBAR_TOP.getName()) + .add(HtmlTree.DIV(HtmlStyle.skipNav, + links.createLink(SectionName.SKIP_NAVBAR_TOP, skipNavLinks, + skipNavLinks.toString(), ""))); + SectionName navListSection = SectionName.NAVBAR_TOP_FIRSTROW; + Content aboutContent = userHeader; + boolean addSearch = options.createIndex(); HtmlTree navList = new HtmlTree(TagName.UL) .setId(navListSection.getName()) @@ -979,18 +929,10 @@ public Content getContent(Position posn) { } tree.add(subDiv); - switch (posn) { - case TOP: - tree.add(Position.TOP.endOfNav()); - tree.add(HtmlTree.SPAN(HtmlStyle.skipNav, EMPTY_COMMENT) - .setId(SectionName.SKIP_NAVBAR_TOP.getName())); - break; + tree.add(MarkerComments.END_OF_TOP_NAVBAR); + tree.add(HtmlTree.SPAN(HtmlStyle.skipNav, EMPTY_COMMENT) + .setId(SectionName.SKIP_NAVBAR_TOP.getName())); - case BOTTOM: - tree.add(Position.BOTTOM.endOfNav()); - tree.add(HtmlTree.SPAN(HtmlStyle.skipNav, EMPTY_COMMENT) - .setId(SectionName.SKIP_NAVBAR_BOTTOM.getName())); - } return tree; } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java index 6120e08b4ae..95d2f207af9 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java @@ -25,6 +25,7 @@ package jdk.javadoc.internal.doclets.formats.html; +import javax.lang.model.element.Element; import javax.lang.model.element.PackageElement; import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; @@ -56,8 +57,6 @@ public class PackageTreeWriter extends AbstractTreeWriter { */ protected PackageElement packageElement; - private final Navigation navBar; - private final BodyContents bodyContents = new BodyContents(); /** @@ -70,7 +69,6 @@ public PackageTreeWriter(HtmlConfiguration configuration, DocPath path, PackageE super(configuration, path, new ClassTree(configuration.typeElementCatalog.allClasses(packageElement), configuration)); this.packageElement = packageElement; - this.navBar = new Navigation(packageElement, configuration, PageMode.TREE, path); } /** @@ -112,11 +110,7 @@ protected void generatePackageTreeFile() throws DocFileIOException { addTree(classtree.baseAnnotationTypes(), "doclet.Annotation_Type_Hierarchy", mainContent); addTree(classtree.baseEnums(), "doclet.Enum_Hierarchy", mainContent, true); bodyContents.addMainContent(mainContent); - HtmlTree footer = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - footer.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(footer); - bodyContents.setFooter(footer); + bodyContents.setFooter(getFooter()); body.add(bodyContents); printHtmlDocument(null, getDescription("tree", packageElement), body); } @@ -130,15 +124,16 @@ protected HtmlTree getPackageTreeHeader() { String packageName = packageElement.isUnnamed() ? "" : utils.getPackageName(packageElement); String title = packageName + " " + resources.getText("doclet.Window_Class_Hierarchy"); HtmlTree bodyTree = getBody(getWindowTitle(title)); - Content headerContent = new ContentBuilder(); - addTop(headerContent); + bodyContents.setHeader(getHeader(PageMode.TREE, packageElement)); + return bodyTree; + } + + @Override + protected Navigation getNavBar(PageMode pageMode, Element element) { Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement), contents.moduleLabel); - navBar.setNavLinkModule(linkContent); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); - bodyContents.setHeader(headerContent); - return bodyTree; + return super.getNavBar(pageMode, element) + .setNavLinkModule(linkContent); } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java index 9e219b72c25..365ff890e6e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java @@ -30,6 +30,7 @@ import java.util.TreeMap; import java.util.TreeSet; +import javax.lang.model.element.Element; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; @@ -61,7 +62,6 @@ public class PackageUseWriter extends SubWriterHolderWriter { final PackageElement packageElement; final SortedMap> usingPackageToUsedClasses = new TreeMap<>(); final String packageUseTableSummary; - private final Navigation navBar; /** * Constructor. @@ -99,7 +99,6 @@ public PackageUseWriter(HtmlConfiguration configuration, packageUseTableSummary = resources.getText("doclet.Use_Table_Summary", resources.getText("doclet.packages")); - this.navBar = new Navigation(packageElement, configuration, PageMode.USE, path); } /** @@ -131,11 +130,7 @@ protected void generatePackageUseFile() throws DocFileIOException { addPackageUse(mainContent); } bodyContents.addMainContent(mainContent); - HtmlTree footer = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - footer.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(footer); - bodyContents.setFooter(footer); + bodyContents.setFooter(getFooter()); body.add(bodyContents); printHtmlDocument(null, getDescription("use", packageElement), @@ -236,13 +231,6 @@ private HtmlTree getPackageUseHeader() { String name = packageElement.isUnnamed() ? "" : utils.getPackageName(packageElement); String title = resources.getText("doclet.Window_ClassUse_Header", packageText, name); HtmlTree bodyTree = getBody(getWindowTitle(title)); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement), - contents.moduleLabel); - navBar.setNavLinkModule(linkContent); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); ContentBuilder headingContent = new ContentBuilder(); headingContent.add(contents.getContent("doclet.ClassUse_Title", packageText)); headingContent.add(new HtmlTree(TagName.BR)); @@ -250,8 +238,16 @@ private HtmlTree getPackageUseHeader() { Content heading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING, HtmlStyle.title, headingContent); Content div = HtmlTree.DIV(HtmlStyle.header, heading); - bodyContents.setHeader(headerContent) + bodyContents.setHeader(getHeader(PageMode.USE, packageElement)) .addMainContent(div); return bodyTree; } + + @Override + protected Navigation getNavBar(PageMode pageMode, Element element) { + Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(element), + contents.moduleLabel); + return super.getNavBar(pageMode, element) + .setNavLinkModule(linkContent); + } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java index 005097639ca..89170e24da9 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java @@ -28,10 +28,12 @@ import java.util.List; import java.util.SortedSet; +import javax.lang.model.element.Element; import javax.lang.model.element.ModuleElement; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; +import com.sun.source.doctree.DeprecatedTree; import com.sun.source.doctree.DocTree; import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; @@ -73,8 +75,6 @@ public class PackageWriterImpl extends HtmlDocletWriter */ protected HtmlTree sectionTree = HtmlTree.SECTION(HtmlStyle.packageDescription, new ContentBuilder()); - private final Navigation navBar; - private final BodyContents bodyContents = new BodyContents(); /** @@ -93,19 +93,11 @@ public PackageWriterImpl(HtmlConfiguration configuration, PackageElement package configuration.docPaths.forPackage(packageElement) .resolve(DocPaths.PACKAGE_SUMMARY)); this.packageElement = packageElement; - this.navBar = new Navigation(packageElement, configuration, PageMode.PACKAGE, path); } @Override public Content getPackageHeader(String heading) { HtmlTree bodyTree = getBody(getWindowTitle(utils.getPackageName(packageElement))); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement), - contents.moduleLabel); - navBar.setNavLinkModule(linkContent); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); HtmlTree div = new HtmlTree(TagName.DIV); div.setStyle(HtmlStyle.header); if (configuration.showModules) { @@ -126,7 +118,7 @@ public Content getPackageHeader(String heading) { Content packageHead = new StringContent(heading); tHeading.add(packageHead); div.add(tHeading); - bodyContents.setHeader(headerContent) + bodyContents.setHeader(getHeader(PageMode.PACKAGE, packageElement)) .addMainContent(div); return bodyTree; } @@ -136,13 +128,21 @@ public Content getContentHeader() { return new ContentBuilder(); } + @Override + protected Navigation getNavBar(PageMode pageMode, Element element) { + Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement), + contents.moduleLabel); + return super.getNavBar(pageMode, element) + .setNavLinkModule(linkContent); + } + /** * Add the package deprecation information to the documentation tree. * * @param div the content tree to which the deprecation information will be added */ public void addDeprecationInfo(Content div) { - List deprs = utils.getBlockTags(packageElement, DocTree.Kind.DEPRECATED); + List deprs = utils.getDeprecatedTrees(packageElement); if (utils.isDeprecated(packageElement)) { CommentHelper ch = utils.getCommentHelper(packageElement); HtmlTree deprDiv = new HtmlTree(TagName.DIV); @@ -223,7 +223,7 @@ public void addClassesSummary(SortedSet classes, String label, ContentBuilder description = new ContentBuilder(); if (utils.isDeprecated(klass)) { description.add(getDeprecatedPhrase(klass)); - List tags = utils.getDeprecatedTrees(klass); + List tags = utils.getDeprecatedTrees(klass); if (!tags.isEmpty()) { addSummaryDeprecatedComment(klass, tags.get(0), description); } @@ -260,11 +260,7 @@ public void addPackageContent(Content packageContentTree) { @Override public void addPackageFooter() { - Content htmlTree = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - htmlTree.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(htmlTree); - bodyContents.setFooter(htmlTree); + bodyContents.setFooter(getFooter()); } @Override diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java index 3aa0db00fbe..975d2aa8f39 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java @@ -55,15 +55,12 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter Set visibleClasses; - private final Navigation navBar; - /** * @param configuration the configuration data for the doclet */ public SerializedFormWriterImpl(HtmlConfiguration configuration) { super(configuration, DocPaths.SERIALIZED_FORM); visibleClasses = configuration.getIncludedTypeElements(); - this.navBar = new Navigation(null, configuration, PageMode.SERIALIZED_FORM, path); configuration.conditionalPages.add(HtmlConfiguration.ConditionalPage.SERIALIZED_FORM); } @@ -76,15 +73,11 @@ public SerializedFormWriterImpl(HtmlConfiguration configuration) { @Override public Content getHeader(String header) { HtmlTree bodyTree = getBody(getWindowTitle(header)); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); Content h1Content = new StringContent(header); Content heading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING, HtmlStyle.title, h1Content); Content div = HtmlTree.DIV(HtmlStyle.header, heading); - bodyContents.setHeader(headerContent) + bodyContents.setHeader(getHeader(PageMode.SERIALIZED_FORM)) .addMainContent(div); return bodyTree; } @@ -241,11 +234,7 @@ public void addPackageSerializedTree(Content serializedSummariesTree, */ @Override public void addFooter() { - Content htmlTree = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - htmlTree.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(htmlTree); - bodyContents.setFooter(htmlTree); + bodyContents.setFooter(getFooter()); } @Override diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java index c6f0463b645..593005a09a0 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SubWriterHolderWriter.java @@ -30,6 +30,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; +import com.sun.source.doctree.DeprecatedTree; import com.sun.source.doctree.DocTree; import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; @@ -108,7 +109,7 @@ protected void addIndexComment(Element member, Content contentTree) { */ protected void addIndexComment(Element member, List firstSentenceTags, Content tdSummary) { - List deprs = utils.getBlockTags(member, DocTree.Kind.DEPRECATED); + List deprs = utils.getDeprecatedTrees(member); Content div; if (utils.isDeprecated(member)) { Content deprLabel = HtmlTree.SPAN(HtmlStyle.deprecatedLabel, getDeprecatedPhrase(member)); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SystemPropertiesWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SystemPropertiesWriter.java index 503eeb10b6e..c17997c6510 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SystemPropertiesWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SystemPropertiesWriter.java @@ -63,8 +63,6 @@ */ public class SystemPropertiesWriter extends HtmlDocletWriter { - private final Navigation navBar; - /** * Cached contents of {@code ...} tags of the HTML pages. */ @@ -78,7 +76,6 @@ public class SystemPropertiesWriter extends HtmlDocletWriter { */ public SystemPropertiesWriter(HtmlConfiguration configuration, DocPath filename) { super(configuration, filename); - this.navBar = new Navigation(null, configuration, PageMode.SYSTEM_PROPERTIES, path); } public static void generate(HtmlConfiguration configuration) throws DocFileIOException { @@ -108,23 +105,15 @@ private static void generate(HtmlConfiguration configuration, DocPath fileName) protected void buildSystemPropertiesPage() throws DocFileIOException { String title = resources.getText("doclet.systemProperties"); HtmlTree body = getBody(getWindowTitle(title)); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); Content mainContent = new ContentBuilder(); addSystemProperties(mainContent); - Content footer = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - footer.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(footer); body.add(new BodyContents() - .setHeader(headerContent) + .setHeader(getHeader(PageMode.SYSTEM_PROPERTIES)) .addMainContent(HtmlTree.DIV(HtmlStyle.header, HtmlTree.HEADING(Headings.PAGE_TITLE_HEADING, contents.getContent("doclet.systemProperties")))) .addMainContent(mainContent) - .setFooter(footer)); + .setFooter(getFooter())); printHtmlDocument(null, "system properties", body); if (configuration.mainIndex != null) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java index 7fcf7006bb2..dc90bf4bf94 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java @@ -37,10 +37,15 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.SimpleElementVisitor14; +import com.sun.source.doctree.DeprecatedTree; import com.sun.source.doctree.DocTree; import com.sun.source.doctree.IndexTree; +import com.sun.source.doctree.LiteralTree; import com.sun.source.doctree.ParamTree; +import com.sun.source.doctree.ReturnTree; +import com.sun.source.doctree.SeeTree; import com.sun.source.doctree.SystemPropertyTree; +import com.sun.source.doctree.ThrowsTree; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; @@ -109,16 +114,15 @@ protected Content codeTagOutput(Element element, DocTree tag) { } @Override - protected Content indexTagOutput(Element element, DocTree tag) { + protected Content indexTagOutput(Element element, IndexTree tag) { CommentHelper ch = utils.getCommentHelper(element); - IndexTree itt = (IndexTree) tag; - String tagText = ch.getText(itt.getSearchTerm()); + String tagText = ch.getText(tag.getSearchTerm()); if (tagText.charAt(0) == '"' && tagText.charAt(tagText.length() - 1) == '"') { tagText = tagText.substring(1, tagText.length() - 1) .replaceAll("\\s+", " "); } - String desc = ch.getText(itt.getDescription()); + String desc = ch.getText(tag.getDescription()); return createAnchorAndSearchIndex(element, tagText, desc, tag); } @@ -137,7 +141,7 @@ public Content getDocRootOutput() { public Content deprecatedTagOutput(Element element) { ContentBuilder result = new ContentBuilder(); CommentHelper ch = utils.getCommentHelper(element); - List deprs = utils.getBlockTags(element, DocTree.Kind.DEPRECATED); + List deprs = utils.getDeprecatedTrees(element); if (utils.isTypeElement(element)) { if (utils.isDeprecated(element)) { result.add(HtmlTree.SPAN(HtmlStyle.deprecatedLabel, @@ -171,7 +175,7 @@ public Content deprecatedTagOutput(Element element) { } @Override - protected Content literalTagOutput(Element element, DocTree tag) { + protected Content literalTagOutput(Element element, LiteralTree tag) { CommentHelper ch = utils.getCommentHelper(element); Content result = new StringContent(utils.normalizeNewlines(ch.getText(tag))); return result; @@ -191,12 +195,12 @@ public Content getParamHeader(ParamTaglet.ParamKind kind) { @Override @SuppressWarnings("preview") - public Content paramTagOutput(Element element, DocTree paramTag, String paramName) { + public Content paramTagOutput(Element element, ParamTree paramTag, String paramName) { ContentBuilder body = new ContentBuilder(); CommentHelper ch = utils.getCommentHelper(element); // define id attributes for state components so that generated descriptions may refer to them boolean defineID = (element.getKind() == ElementKind.RECORD) - && (paramTag instanceof ParamTree) && !((ParamTree) paramTag).isTypeParameter(); + && !paramTag.isTypeParameter(); Content nameTree = new StringContent(paramName); body.add(HtmlTree.CODE(defineID ? HtmlTree.SPAN_ID("param-" + paramName, nameTree) : nameTree)); body.add(" - "); @@ -206,7 +210,7 @@ public Content paramTagOutput(Element element, DocTree paramTag, String paramNam } @Override - public Content returnTagOutput(Element element, DocTree returnTag) { + public Content returnTagOutput(Element element, ReturnTree returnTag) { CommentHelper ch = utils.getCommentHelper(element); return new ContentBuilder( HtmlTree.DT(contents.returns), @@ -215,7 +219,7 @@ public Content returnTagOutput(Element element, DocTree returnTag) { } @Override - public Content seeTagOutput(Element holder, List seeTags) { + public Content seeTagOutput(Element holder, List seeTags) { ContentBuilder body = new ContentBuilder(); for (DocTree dt : seeTags) { appendSeparatorIfNotEmpty(body); @@ -279,9 +283,8 @@ public Content simpleBlockTagOutput(Element element, List sim } @Override - protected Content systemPropertyTagOutput(Element element, DocTree tag) { - SystemPropertyTree itt = (SystemPropertyTree) tag; - String tagText = itt.getPropertyName().toString(); + protected Content systemPropertyTagOutput(Element element, SystemPropertyTree tag) { + String tagText = tag.getPropertyName().toString(); return HtmlTree.CODE(createAnchorAndSearchIndex(element, tagText, resources.getText("doclet.System_Property"), tag)); } @@ -292,7 +295,7 @@ public Content getThrowsHeader() { } @Override - public Content throwsTagOutput(Element element, DocTree throwsTag, TypeMirror substituteType) { + public Content throwsTagOutput(Element element, ThrowsTree throwsTag, TypeMirror substituteType) { ContentBuilder body = new ContentBuilder(); CommentHelper ch = utils.getCommentHelper(element); Element exception = ch.getException(throwsTag); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java index 1fe0a5292e4..0dbe9c790b5 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TreeWriter.java @@ -66,8 +66,6 @@ public class TreeWriter extends AbstractTreeWriter { */ private final boolean classesOnly; - private final Navigation navBar; - protected BodyContents bodyContents; /** @@ -81,7 +79,6 @@ public TreeWriter(HtmlConfiguration configuration, DocPath filename, ClassTree c super(configuration, filename, classtree); packages = configuration.packages; classesOnly = packages.isEmpty(); - this.navBar = new Navigation(null, configuration, PageMode.TREE, path); this.bodyContents = new BodyContents(); } @@ -118,13 +115,9 @@ public void generateTreeFile() throws DocFileIOException { addTree(classtree.baseInterfaces(), "doclet.Interface_Hierarchy", mainContent); addTree(classtree.baseAnnotationTypes(), "doclet.Annotation_Type_Hierarchy", mainContent); addTree(classtree.baseEnums(), "doclet.Enum_Hierarchy", mainContent, true); - HtmlTree footerTree = HtmlTree.FOOTER(); - navBar.setUserFooter(getUserHeaderFooter(false)); - footerTree.add(navBar.getContent(Navigation.Position.BOTTOM)); - addBottom(footerTree); body.add(bodyContents .addMainContent(mainContent) - .setFooter(footerTree)); + .setFooter(getFooter())); printHtmlDocument(null, "class tree", body); } @@ -175,11 +168,7 @@ protected void addPackageTreeLinks(Content contentTree) { protected HtmlTree getTreeHeader() { String title = resources.getText("doclet.Window_Class_Hierarchy"); HtmlTree bodyTree = getBody(getWindowTitle(title)); - Content headerContent = new ContentBuilder(); - addTop(headerContent); - navBar.setUserHeader(getUserHeaderFooter(true)); - headerContent.add(navBar.getContent(Navigation.Position.TOP)); - bodyContents.setHeader(headerContent); + bodyContents.setHeader(getHeader(PageMode.TREE)); return bodyTree; } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/BodyContents.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/BodyContents.java index 63f2dfc1778..33ebbc43b2d 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/BodyContents.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/BodyContents.java @@ -31,6 +31,7 @@ import java.io.Writer; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * Content for the {@code } element. @@ -47,20 +48,20 @@ public class BodyContents extends Content { private List mainContents = new ArrayList<>(); - private Content header = HtmlTree.EMPTY; - private Content footer = HtmlTree.EMPTY; + private HtmlTree header = null; + private HtmlTree footer = null; public BodyContents addMainContent(Content content) { mainContents.add(content); return this; } - public BodyContents setHeader(Content header) { - this.header = header; + public BodyContents setHeader(HtmlTree header) { + this.header = Objects.requireNonNull(header); return this; } - public BodyContents setFooter(Content footer) { + public BodyContents setFooter(HtmlTree footer) { this.footer = footer; return this; } @@ -88,13 +89,14 @@ public boolean write(Writer out, boolean atNewline) throws IOException { * @return the HTML */ private Content toContent() { - HtmlTree flexHeader = HtmlTree.HEADER() - .setStyle(HtmlStyle.flexHeader) - .add(header); + if (header == null) + throw new NullPointerException(); + + HtmlTree flexHeader = header.addStyle(HtmlStyle.flexHeader); HtmlTree flexContent = HtmlTree.DIV(HtmlStyle.flexContent) .add(HtmlTree.MAIN().add(mainContents)) - .add(footer); + .add(footer == null ? HtmlTree.EMPTY : footer); return HtmlTree.DIV(HtmlStyle.flexBox) .add(flexHeader) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java index ace4257226f..28791eb7a02 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java @@ -97,11 +97,6 @@ public enum HtmlStyle { */ topNav, - /** - * The class for the overall {@code div} element containing the {@code footer} element for the page. - */ - bottomNav, - /** * The class for the element containing the information (such as the product name and version) * provided by the {@code -header} or {@code -footer} command line option. diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties index 3a8fcc0948f..0846a2ff64d 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties @@ -491,7 +491,12 @@ doclet.usage.xdoclint-package.description=\ of the given package. Prefix the package specifier with - to\n\ disable checks for the specified packages. -# L10N: do not localize the option names --no-frames +# L10N: do not localize the option name --no-frames doclet.NoFrames_specified=\ The --no-frames option is no longer required and may be removed\n\ in a future release. + +# L10N: do not localize the option name -footer +doclet.footer_specified=\ + The -footer option is no longer supported and will be ignored.\n\ + It may be removed in a future release. \ No newline at end of file diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java index a549baf5253..2e593830faf 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java @@ -38,6 +38,7 @@ import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.DocTree; import com.sun.source.doctree.DocTree.Kind; +import com.sun.source.doctree.SinceTree; import com.sun.source.doctree.UnknownBlockTagTree; import jdk.javadoc.internal.doclets.toolkit.ClassWriter; import jdk.javadoc.internal.doclets.toolkit.Content; @@ -335,7 +336,7 @@ private void processProperty(Element member, } // copy certain tags - List tags = utils.getBlockTags(property, Kind.SINCE); + List tags = utils.getBlockTags(property, Kind.SINCE, SinceTree.class); blockTags.addAll(tags); List bTags = utils.getBlockTags(property, diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java index 595810f74fd..2516073ee5b 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java @@ -36,8 +36,8 @@ import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; -import com.sun.source.doctree.DocTree; import com.sun.source.doctree.SerialFieldTree; +import com.sun.source.doctree.SerialTree; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.DocletException; import jdk.javadoc.internal.doclets.toolkit.SerializedFormWriter; @@ -472,10 +472,7 @@ protected void buildSerialFieldTagsInfo(Content serializableFieldsTree) { // element.) SortedSet tags = new TreeSet<>(utils.comparators.makeSerialFieldTreeComparator()); // sort the elements - for (DocTree dt : utils.getSerialFieldTrees(field)) { - SerialFieldTree st = (SerialFieldTree) dt; - tags.add(st); - } + tags.addAll(utils.getSerialFieldTrees(field)); CommentHelper ch = utils.getCommentHelper(field); for (SerialFieldTree tag : tags) { @@ -574,7 +571,7 @@ private static boolean serialDocInclude(Utils utils, Element element) { if (utils.isEnum(element)) { return false; } - List serial = utils.getSerialTrees(element); + List serial = utils.getSerialTrees(element); if (!serial.isEmpty()) { CommentHelper ch = utils.getCommentHelper(element); String serialtext = Utils.toLowerCase(ch.getText(serial.get(0))); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css index a4fd5d659f9..de894ea81e9 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/stylesheet.css @@ -152,19 +152,6 @@ button { overflow:hidden; font-size:12px; } -.bottom-nav { - margin-top:10px; - background-color:#4D7A97; - color:#FFFFFF; - float:left; - padding:0; - width:100%; - clear:right; - height:2.8em; - padding-top:10px; - overflow:hidden; - font-size:12px; -} .sub-nav { background-color:#dee3e9; float:left; @@ -207,12 +194,12 @@ ul.sub-nav-list li { float:left; padding-top:10px; } -.top-nav a:link, .top-nav a:active, .top-nav a:visited, .bottom-nav a:link, .bottom-nav a:active, .bottom-nav a:visited { +.top-nav a:link, .top-nav a:active, .top-nav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } -.top-nav a:hover, .bottom-nav a:hover { +.top-nav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/IndexTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/IndexTaglet.java index e2307aacfba..d67cb44f003 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/IndexTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/IndexTaglet.java @@ -29,6 +29,7 @@ import javax.lang.model.element.Element; import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.IndexTree; import jdk.javadoc.doclet.Taglet.Location; import jdk.javadoc.internal.doclets.toolkit.Content; @@ -46,6 +47,6 @@ public class IndexTaglet extends BaseTaglet { @Override public Content getInlineTagOutput(Element element, DocTree tag, TagletWriter writer) { - return writer.indexTagOutput(element, tag); + return writer.indexTagOutput(element, (IndexTree) tag); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/LiteralTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/LiteralTaglet.java index 3c1e9b6639b..50df1c8fdcc 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/LiteralTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/LiteralTaglet.java @@ -29,6 +29,7 @@ import javax.lang.model.element.Element; import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.LiteralTree; import jdk.javadoc.doclet.Taglet.Location; import jdk.javadoc.internal.doclets.toolkit.Content; /** @@ -52,6 +53,6 @@ public class LiteralTaglet extends BaseTaglet { @Override public Content getInlineTagOutput(Element e, DocTree tag, TagletWriter writer) { - return writer.literalTagOutput(e, tag); + return writer.literalTagOutput(e, (LiteralTree) tag); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ParamTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ParamTaglet.java index f1f617a154e..199d28b66c3 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ParamTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ParamTaglet.java @@ -165,7 +165,7 @@ public Content getAllBlockTagOutput(Element holder, TagletWriter writer) { * @return the content representation of these {@code @param DocTree}s. */ private Content getTagletOutput(ParamKind kind, Element holder, - TagletWriter writer, List formalParameters, List paramTags) { + TagletWriter writer, List formalParameters, List paramTags) { Content result = writer.getOutputInstance(); Set alreadyDocumented = new HashSet<>(); if (!paramTags.isEmpty()) { @@ -210,7 +210,7 @@ private Content getInheritedTagletOutput(ParamKind kind, Element holder, CommentHelper ch = utils.getCommentHelper(holder); ch.setOverrideElement(inheritedDoc.holder); Content content = processParamTag(holder, kind, writer, - inheritedDoc.holderTag, + (ParamTree) inheritedDoc.holderTag, lname, alreadyDocumented.isEmpty()); result.add(content); @@ -240,13 +240,13 @@ private Content getInheritedTagletOutput(ParamKind kind, Element holder, * @return the Content representation of this {@code @param DocTree}. */ private Content processParamTags(Element e, ParamKind kind, - List paramTags, Map rankMap, TagletWriter writer, + List paramTags, Map rankMap, TagletWriter writer, Set alreadyDocumented) { Messages messages = writer.configuration().getMessages(); Content result = writer.getOutputInstance(); if (!paramTags.isEmpty()) { CommentHelper ch = writer.configuration().utils.getCommentHelper(e); - for (DocTree dt : paramTags) { + for (ParamTree dt : paramTags) { String name = ch.getParameterName(dt); String paramName = kind != ParamKind.TYPE_PARAMETER ? name.toString() @@ -294,7 +294,7 @@ private Content processParamTags(Element e, ParamKind kind, * */ private Content processParamTag(Element e, ParamKind kind, - TagletWriter writer, DocTree paramTag, String name, + TagletWriter writer, ParamTree paramTag, String name, boolean isFirstParam) { Content result = writer.getOutputInstance(); if (isFirstParam) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ReturnTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ReturnTaglet.java index 3aebf49fe71..15983f90403 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ReturnTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ReturnTaglet.java @@ -34,6 +34,7 @@ import javax.lang.model.type.TypeMirror; import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.ReturnTree; import jdk.javadoc.doclet.Taglet.Location; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.Messages; @@ -58,7 +59,7 @@ public ReturnTaglet() { @Override public void inherit(DocFinder.Input input, DocFinder.Output output) { - List tags = input.utils.getBlockTags(input.element, DocTree.Kind.RETURN); + List tags = input.utils.getReturnTrees(input.element); CommentHelper ch = input.utils.getCommentHelper(input.element); if (!tags.isEmpty()) { output.holder = input.element; @@ -74,7 +75,7 @@ public Content getAllBlockTagOutput(Element holder, TagletWriter writer) { Messages messages = writer.configuration().getMessages(); Utils utils = writer.configuration().utils; TypeMirror returnType = utils.getReturnType(writer.getCurrentPageElement(), (ExecutableElement)holder); - List tags = utils.getBlockTags(holder, DocTree.Kind.RETURN); + List tags = utils.getReturnTrees(holder); //Make sure we are not using @return tag on method with void return type. if (returnType != null && utils.isVoid(returnType)) { @@ -94,6 +95,6 @@ public Content getAllBlockTagOutput(Element holder, TagletWriter writer) { ch.setOverrideElement(inheritedDoc.holder); ntags.add(inheritedDoc.holderTag); } - return !ntags.isEmpty() ? writer.returnTagOutput(holder, ntags.get(0)) : null; + return !ntags.isEmpty() ? writer.returnTagOutput(holder, (ReturnTree) ntags.get(0)) : null; } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SeeTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SeeTaglet.java index 24222758ee7..60863371ae8 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SeeTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SeeTaglet.java @@ -31,6 +31,7 @@ import javax.lang.model.element.Element; import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.SeeTree; import jdk.javadoc.doclet.Taglet.Location; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper; @@ -54,7 +55,7 @@ public SeeTaglet() { @Override public void inherit(DocFinder.Input input, DocFinder.Output output) { - List tags = input.utils.getSeeTrees(input.element); + List tags = input.utils.getSeeTrees(input.element); if (!tags.isEmpty()) { CommentHelper ch = input.utils.getCommentHelper(input.element); output.holder = input.element; @@ -68,7 +69,7 @@ public void inherit(DocFinder.Input input, DocFinder.Output output) { @Override public Content getAllBlockTagOutput(Element holder, TagletWriter writer) { Utils utils = writer.configuration().utils; - List tags = utils.getSeeTrees(holder); + List tags = utils.getSeeTrees(holder); Element e = holder; if (tags.isEmpty() && utils.isExecutableElement(holder)) { Input input = new DocFinder.Input(utils, holder, this); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SystemPropertyTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SystemPropertyTaglet.java index c94c7172b65..84bfe329343 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SystemPropertyTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/SystemPropertyTaglet.java @@ -26,6 +26,7 @@ package jdk.javadoc.internal.doclets.toolkit.taglets; import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.SystemPropertyTree; import jdk.javadoc.doclet.Taglet.Location; import jdk.javadoc.internal.doclets.toolkit.Content; @@ -50,6 +51,6 @@ public class SystemPropertyTaglet extends BaseTaglet { @Override public Content getInlineTagOutput(Element element, DocTree tag, TagletWriter writer) { - return writer.systemPropertyTagOutput(element, tag); + return writer.systemPropertyTagOutput(element, (SystemPropertyTree) tag); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java index d0defd1c2ff..692022aed9a 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java @@ -34,6 +34,13 @@ import javax.lang.model.type.TypeMirror; import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.IndexTree; +import com.sun.source.doctree.LiteralTree; +import com.sun.source.doctree.ParamTree; +import com.sun.source.doctree.ReturnTree; +import com.sun.source.doctree.SeeTree; +import com.sun.source.doctree.SystemPropertyTree; +import com.sun.source.doctree.ThrowsTree; import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.taglets.Taglet.UnsupportedTagletOperationException; @@ -85,7 +92,7 @@ protected TagletWriter(boolean isFirstSentence) { * * @return the output */ - protected abstract Content indexTagOutput(Element element, DocTree tag); + protected abstract Content indexTagOutput(Element element, IndexTree tag); /** * Returns the output for a {@code {@docRoot}} tag. @@ -111,7 +118,7 @@ protected TagletWriter(boolean isFirstSentence) { * * @return the output */ - protected abstract Content literalTagOutput(Element element, DocTree tag); + protected abstract Content literalTagOutput(Element element, LiteralTree tag); /** * Returns the header for the {@code @param} tags. @@ -133,7 +140,7 @@ protected TagletWriter(boolean isFirstSentence) { * * @return the output */ - protected abstract Content paramTagOutput(Element element, DocTree paramTag, String paramName); + protected abstract Content paramTagOutput(Element element, ParamTree paramTag, String paramName); /** * Returns the output for a {@code @return} tag. @@ -143,7 +150,7 @@ protected TagletWriter(boolean isFirstSentence) { * * @return the output */ - protected abstract Content returnTagOutput(Element element, DocTree returnTag); + protected abstract Content returnTagOutput(Element element, ReturnTree returnTag); /** * Returns the output for {@code @see} tags. @@ -153,7 +160,7 @@ protected TagletWriter(boolean isFirstSentence) { * * @return the output */ - protected abstract Content seeTagOutput(Element element, List seeTags); + protected abstract Content seeTagOutput(Element element, List seeTags); /** * Returns the output for a series of simple tags. @@ -174,7 +181,7 @@ protected TagletWriter(boolean isFirstSentence) { * * @return the output */ - protected abstract Content systemPropertyTagOutput(Element element, DocTree systemPropertyTag); + protected abstract Content systemPropertyTagOutput(Element element, SystemPropertyTree systemPropertyTag); /** * Returns the header for the {@code @throws} tag. @@ -192,7 +199,7 @@ protected TagletWriter(boolean isFirstSentence) { * * @return the output */ - protected abstract Content throwsTagOutput(Element element, DocTree throwsTag, TypeMirror substituteType); + protected abstract Content throwsTagOutput(Element element, ThrowsTree throwsTag, TypeMirror substituteType); /** * Returns the output for a default {@code @throws} tag. diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ThrowsTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ThrowsTaglet.java index bf2ab199e37..bea65063128 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ThrowsTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ThrowsTaglet.java @@ -35,6 +35,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.stream.Collectors; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; @@ -43,6 +44,7 @@ import javax.lang.model.type.TypeMirror; import com.sun.source.doctree.DocTree; +import com.sun.source.doctree.ThrowsTree; import jdk.javadoc.doclet.Taglet.Location; import jdk.javadoc.internal.doclets.toolkit.Content; @@ -72,7 +74,8 @@ public void inherit(DocFinder.Input input, DocFinder.Output output) { Element exception; CommentHelper ch = utils.getCommentHelper(input.element); if (input.tagId == null) { - exception = ch.getException(input.docTreeInfo.docTree); + exception = input.docTreeInfo.docTree instanceof ThrowsTree + ? ch.getException((ThrowsTree) input.docTreeInfo.docTree) : null; input.tagId = exception == null ? ch.getExceptionName(input.docTreeInfo.docTree).getSignature() : utils.getFullyQualifiedName(exception); @@ -80,18 +83,18 @@ public void inherit(DocFinder.Input input, DocFinder.Output output) { exception = input.utils.findClass(input.element, input.tagId); } - for (DocTree dt : input.utils.getThrowsTrees(input.element)) { - Element exc = ch.getException(dt); + for (ThrowsTree tt : input.utils.getThrowsTrees(input.element)) { + Element exc = ch.getException(tt); if (exc != null && (input.tagId.equals(utils.getSimpleName(exc)) || (input.tagId.equals(utils.getFullyQualifiedName(exc))))) { output.holder = input.element; - output.holderTag = dt; + output.holderTag = tt; output.inlineTags = ch.getBody(output.holderTag); - output.tagList.add(dt); + output.tagList.add(tt); } else if (exception != null && exc != null && utils.isTypeElement(exc) && utils.isTypeElement(exception) && utils.isSubclassOf((TypeElement)exc, (TypeElement)exception)) { - output.tagList.add(dt); + output.tagList.add(tt); } } } @@ -129,7 +132,7 @@ private Content inheritThrowsDocumentation(Element holder, Utils utils = writer.configuration().utils; Content result = writer.getOutputInstance(); if (utils.isExecutableElement(holder)) { - Map, ExecutableElement> declaredExceptionTags = new LinkedHashMap<>(); + Map, ExecutableElement> declaredExceptionTags = new LinkedHashMap<>(); for (TypeMirror declaredExceptionType : declaredExceptionTypes) { Input input = new DocFinder.Input(utils, holder, this, utils.getTypeName(declaredExceptionType, false)); @@ -143,7 +146,10 @@ private Content inheritThrowsDocumentation(Element holder, if (inheritedDoc.holder == null) { inheritedDoc.holder = holder; } - declaredExceptionTags.put(inheritedDoc.tagList, (ExecutableElement)inheritedDoc.holder); + List inheritedTags = inheritedDoc.tagList.stream() + .map(t -> (ThrowsTree) t) + .collect(Collectors.toList()); + declaredExceptionTags.put(inheritedTags, (ExecutableElement) inheritedDoc.holder); } } result.add(throwsTagsOutput(declaredExceptionTags, writer, alreadyDocumented, @@ -161,7 +167,7 @@ public Content getAllBlockTagOutput(Element holder, TagletWriter writer) { List thrownTypes = instantiatedType.getThrownTypes(); Map typeSubstitutions = getSubstitutedThrownTypes( ((ExecutableElement) holder).getThrownTypes(), thrownTypes); - Map, ExecutableElement> tagsMap = new LinkedHashMap<>(); + Map, ExecutableElement> tagsMap = new LinkedHashMap<>(); tagsMap.put(utils.getThrowsTrees(execHolder), execHolder); Content result = writer.getOutputInstance(); HashSet alreadyDocumented = new HashSet<>(); @@ -183,16 +189,16 @@ public Content getAllBlockTagOutput(Element holder, TagletWriter writer) { * @param allowDuplicates {@code true} if we allow duplicate tags to be documented * @return the generated content for the tags */ - protected Content throwsTagsOutput(Map, ExecutableElement> throwTags, + protected Content throwsTagsOutput(Map, ExecutableElement> throwTags, TagletWriter writer, Set alreadyDocumented, Map typeSubstitutions, boolean allowDuplicates) { Utils utils = writer.configuration().utils; Content result = writer.getOutputInstance(); if (!throwTags.isEmpty()) { - for (Entry, ExecutableElement> entry : throwTags.entrySet()) { + for (Entry, ExecutableElement> entry : throwTags.entrySet()) { CommentHelper ch = utils.getCommentHelper(entry.getValue()); Element e = entry.getValue(); - for (DocTree dt : entry.getKey()) { + for (ThrowsTree dt : entry.getKey()) { Element te = ch.getException(dt); String excName = ch.getExceptionName(dt).toString(); TypeMirror substituteType = typeSubstitutions.get(excName); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/CommentHelper.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/CommentHelper.java index a77b2912157..6d2d955917e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/CommentHelper.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/CommentHelper.java @@ -200,13 +200,8 @@ public TypeMirror getType(ReferenceTree rtree) { return null; } - public Element getException(DocTree dtree) { - if (dtree.getKind() == THROWS || dtree.getKind() == EXCEPTION) { - ThrowsTree tt = (ThrowsTree)dtree; - ReferenceTree exceptionName = tt.getExceptionName(); - return getElement(exceptionName); - } - return null; + public Element getException(ThrowsTree tt) { + return getElement(tt.getExceptionName()); } public List getDescription(DocTree dtree) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java index ddd91d7ab13..d73b1355ce4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java @@ -91,14 +91,23 @@ import javax.tools.JavaFileManager.Location; import javax.tools.StandardLocation; +import com.sun.source.doctree.DeprecatedTree; import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.DocTree; import com.sun.source.doctree.DocTree.Kind; import com.sun.source.doctree.EndElementTree; import com.sun.source.doctree.ParamTree; +import com.sun.source.doctree.ProvidesTree; +import com.sun.source.doctree.ReturnTree; +import com.sun.source.doctree.SeeTree; +import com.sun.source.doctree.SerialDataTree; +import com.sun.source.doctree.SerialFieldTree; +import com.sun.source.doctree.SerialTree; import com.sun.source.doctree.StartElementTree; import com.sun.source.doctree.TextTree; +import com.sun.source.doctree.ThrowsTree; import com.sun.source.doctree.UnknownBlockTagTree; +import com.sun.source.doctree.UsesTree; import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.LineMap; import com.sun.source.util.DocSourcePositions; @@ -945,8 +954,8 @@ public SortedSet getTypeElementsAsSortedSet(Iterable t return set; } - public List getSerialDataTrees(ExecutableElement member) { - return getBlockTags(member, SERIAL_DATA); + public List getSerialDataTrees(ExecutableElement member) { + return getBlockTags(member, SERIAL_DATA, SerialDataTree.class); } public FileObject getFileObject(TypeElement te) { @@ -2591,10 +2600,22 @@ public List getBlockTags(Element element, Predicate .collect(Collectors.toList()); } + public List getBlockTags(Element element, Predicate filter, Class tClass) { + return getBlockTags(element).stream() + .filter(t -> t.getKind() != ERRONEOUS) + .filter(filter) + .map(t -> tClass.cast(t)) + .collect(Collectors.toList()); + } + public List getBlockTags(Element element, DocTree.Kind kind) { return getBlockTags(element, t -> t.getKind() == kind); } + public List getBlockTags(Element element, DocTree.Kind kind, Class tClass) { + return getBlockTags(element, t -> t.getKind() == kind, tClass); + } + public List getBlockTags(Element element, DocTree.Kind kind, DocTree.Kind altKind) { return getBlockTags(element, t -> t.getKind() == kind || t.getKind() == altKind); } @@ -2780,28 +2801,30 @@ public List getBody(Element element) { : docCommentTree.getFullBody(); } - public List getDeprecatedTrees(Element element) { - return getBlockTags(element, DEPRECATED); + public List getDeprecatedTrees(Element element) { + return getBlockTags(element, DEPRECATED, DeprecatedTree.class); } - public List getProvidesTrees(Element element) { - return getBlockTags(element, PROVIDES); + public List getProvidesTrees(Element element) { + return getBlockTags(element, PROVIDES, ProvidesTree.class); } - public List getSeeTrees(Element element) { - return getBlockTags(element, SEE); + public List getSeeTrees(Element element) { + return getBlockTags(element, SEE, SeeTree.class); } - public List getSerialTrees(Element element) { - return getBlockTags(element, SERIAL); + public List getSerialTrees(Element element) { + return getBlockTags(element, SERIAL, SerialTree.class); } - public List getSerialFieldTrees(VariableElement field) { - return getBlockTags(field, DocTree.Kind.SERIAL_FIELD); + public List getSerialFieldTrees(VariableElement field) { + return getBlockTags(field, DocTree.Kind.SERIAL_FIELD, SerialFieldTree.class); } - public List getThrowsTrees(Element element) { - return getBlockTags(element, DocTree.Kind.EXCEPTION, DocTree.Kind.THROWS); + public List getThrowsTrees(Element element) { + return getBlockTags(element, + t -> switch (t.getKind()) { case EXCEPTION, THROWS -> true; default -> false; }, + ThrowsTree.class); } public List getTypeParamTrees(Element element) { @@ -2813,22 +2836,17 @@ public List getParamTrees(Element element) { } private List getParamTrees(Element element, boolean isTypeParameters) { - List out = new ArrayList<>(); - for (DocTree dt : getBlockTags(element, PARAM)) { - ParamTree pt = (ParamTree) dt; - if (pt.isTypeParameter() == isTypeParameters) { - out.add(pt); - } - } - return out; + return getBlockTags(element, + t -> t.getKind() == PARAM && ((ParamTree) t).isTypeParameter() == isTypeParameters, + ParamTree.class); } - public List getReturnTrees(Element element) { - return new ArrayList<>(getBlockTags(element, RETURN)); + public List getReturnTrees(Element element) { + return new ArrayList<>(getBlockTags(element, RETURN, ReturnTree.class)); } - public List getUsesTrees(Element element) { - return getBlockTags(element, USES); + public List getUsesTrees(Element element) { + return getBlockTags(element, USES, UsesTree.class); } public List getFirstSentenceTrees(Element element) { diff --git a/src/jdk.javadoc/share/man/javadoc.1 b/src/jdk.javadoc/share/man/javadoc.1 index a0fc1354141..14139d20ef2 100644 --- a/src/jdk.javadoc/share/man/javadoc.1 +++ b/src/jdk.javadoc/share/man/javadoc.1 @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAVADOC" "1" "2020" "JDK 15" "JDK Commands" +.TH "JAVADOC" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jcmd/share/man/jcmd.1 b/src/jdk.jcmd/share/man/jcmd.1 index 9e6a99bd253..5ab057c1453 100644 --- a/src/jdk.jcmd/share/man/jcmd.1 +++ b/src/jdk.jcmd/share/man/jcmd.1 @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JCMD" "1" "2020" "JDK 15" "JDK Commands" +.TH "JCMD" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jcmd/share/man/jinfo.1 b/src/jdk.jcmd/share/man/jinfo.1 index a78f5b2e172..f7f79ab296e 100644 --- a/src/jdk.jcmd/share/man/jinfo.1 +++ b/src/jdk.jcmd/share/man/jinfo.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JINFO" "1" "2020" "JDK 15" "JDK Commands" +.TH "JINFO" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jcmd/share/man/jmap.1 b/src/jdk.jcmd/share/man/jmap.1 index eb0c92b0775..b5284e0f9e0 100644 --- a/src/jdk.jcmd/share/man/jmap.1 +++ b/src/jdk.jcmd/share/man/jmap.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JMAP" "1" "2020" "JDK 15" "JDK Commands" +.TH "JMAP" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jcmd/share/man/jps.1 b/src/jdk.jcmd/share/man/jps.1 index b754ce042a9..75acc38ced0 100644 --- a/src/jdk.jcmd/share/man/jps.1 +++ b/src/jdk.jcmd/share/man/jps.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JPS" "1" "2020" "JDK 15" "JDK Commands" +.TH "JPS" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jcmd/share/man/jstack.1 b/src/jdk.jcmd/share/man/jstack.1 index ebc294928a2..98269bcaf8c 100644 --- a/src/jdk.jcmd/share/man/jstack.1 +++ b/src/jdk.jcmd/share/man/jstack.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JSTACK" "1" "2020" "JDK 15" "JDK Commands" +.TH "JSTACK" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jcmd/share/man/jstat.1 b/src/jdk.jcmd/share/man/jstat.1 index 7623a3769a5..143d3ce8d4f 100644 --- a/src/jdk.jcmd/share/man/jstat.1 +++ b/src/jdk.jcmd/share/man/jstat.1 @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JSTAT" "1" "2020" "JDK 15" "JDK Commands" +.TH "JSTAT" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP @@ -224,7 +224,7 @@ Class loader statistics. .PP \f[CB]Unloaded\f[R]: Number of classes unloaded. .PP -\f[CB]Bytes\f[R]: Number of KB loaded. +\f[CB]Bytes\f[R]: Number of KB unloaded. .PP \f[CB]Time\f[R]: Time spent performing class loading and unloading operations. diff --git a/src/jdk.jconsole/share/man/jconsole.1 b/src/jdk.jconsole/share/man/jconsole.1 index da8196d9e05..277cf034433 100644 --- a/src/jdk.jconsole/share/man/jconsole.1 +++ b/src/jdk.jconsole/share/man/jconsole.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JCONSOLE" "1" "2020" "JDK 15" "JDK Commands" +.TH "JCONSOLE" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdeps/share/man/javap.1 b/src/jdk.jdeps/share/man/javap.1 index d19f23559c6..3bef06a924e 100644 --- a/src/jdk.jdeps/share/man/javap.1 +++ b/src/jdk.jdeps/share/man/javap.1 @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JAVAP" "1" "2020" "JDK 15" "JDK Commands" +.TH "JAVAP" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdeps/share/man/jdeprscan.1 b/src/jdk.jdeps/share/man/jdeprscan.1 index c4ca77319a5..3dd4cd9097e 100644 --- a/src/jdk.jdeps/share/man/jdeprscan.1 +++ b/src/jdk.jdeps/share/man/jdeprscan.1 @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JDEPRSCAN" "1" "2020" "JDK 15" "JDK Commands" +.TH "JDEPRSCAN" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdeps/share/man/jdeps.1 b/src/jdk.jdeps/share/man/jdeps.1 index 3a08fe64406..3dd37bd7150 100644 --- a/src/jdk.jdeps/share/man/jdeps.1 +++ b/src/jdk.jdeps/share/man/jdeps.1 @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JDEPS" "1" "2020" "JDK 15" "JDK Commands" +.TH "JDEPS" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdi/share/man/jdb.1 b/src/jdk.jdi/share/man/jdb.1 index 6f6d6c4e95d..00969b55e45 100644 --- a/src/jdk.jdi/share/man/jdb.1 +++ b/src/jdk.jdi/share/man/jdb.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JDB" "1" "2020" "JDK 15" "JDK Commands" +.TH "JDB" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c b/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c index 78ca29796aa..96773392fc3 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c +++ b/src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -836,6 +836,7 @@ threadControl_onHook(void) */ node->isStarted = JNI_TRUE; } + jvmtiDeallocate(threads); } } END_WITH_LOCAL_REFS(env) @@ -1515,22 +1516,9 @@ threadControl_suspendAll(void) error = AGENT_ERROR_OUT_OF_MEMORY; goto err; } - if (canSuspendResumeThreadLists()) { - error = commonSuspendList(env, count, threads); - if (error != JVMTI_ERROR_NONE) { - goto err; - } - } else { - - int i; - - for (i = 0; i < count; i++) { - error = commonSuspend(env, threads[i], JNI_FALSE); - - if (error != JVMTI_ERROR_NONE) { - goto err; - } - } + error = commonSuspendList(env, count, threads); + if (error != JVMTI_ERROR_NONE) { + goto err; } /* @@ -1549,7 +1537,8 @@ threadControl_suspendAll(void) suspendAllCount++; } - err: ; + err: + jvmtiDeallocate(threads); } END_WITH_LOCAL_REFS(env) @@ -1588,12 +1577,7 @@ threadControl_resumeAll(void) * no need to get the whole thread list from JVMTI (unlike * suspendAll). */ - if (canSuspendResumeThreadLists()) { - error = commonResumeList(env); - } else { - error = enumerateOverThreadList(env, &runningThreads, - resumeHelper, NULL); - } + error = commonResumeList(env); if ((error == JVMTI_ERROR_NONE) && (otherThreads.first != NULL)) { error = enumerateOverThreadList(env, &otherThreads, resumeHelper, NULL); diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/util.c b/src/jdk.jdwp.agent/share/native/libjdwp/util.c index d05f5075a66..f81bfcfb4b8 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/util.c +++ b/src/jdk.jdwp.agent/share/native/libjdwp/util.c @@ -699,12 +699,12 @@ methodClass(jmethodID method, jclass *pclazz) jvmtiError error; *pclazz = NULL; - error = FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass) + error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass) (gdata->jvmti, method, pclazz); return error; } -/* Returns a local ref to the declaring class for a method, or NULL. */ +/* Returns the start and end locations of the specified method. */ jvmtiError methodLocation(jmethodID method, jlocation *ploc1, jlocation *ploc2) { @@ -727,7 +727,7 @@ methodSignature(jmethodID method, char *signature = NULL; char *generic_signature = NULL; - error = FUNC_PTR(gdata->jvmti,GetMethodName) + error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodName) (gdata->jvmti, method, &name, &signature, &generic_signature); if ( pname != NULL ) { @@ -962,16 +962,6 @@ jvmtiMicroVersion(void) >> JVMTI_VERSION_SHIFT_MICRO; } -jboolean -canSuspendResumeThreadLists(void) -{ - jvmtiError error; - jvmtiCapabilities cap; - - error = jvmtiGetCapabilities(&cap); - return (error == JVMTI_ERROR_NONE && cap.can_suspend); -} - jvmtiError getSourceDebugExtension(jclass clazz, char **extensionPtr) { @@ -1019,7 +1009,7 @@ debugMonitorEnter(jrawMonitorID monitor) { jvmtiError error; while (JNI_TRUE) { - error = FUNC_PTR(gdata->jvmti,RawMonitorEnter) + error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorEnter) (gdata->jvmti, monitor); error = ignore_vm_death(error); if (error == JVMTI_ERROR_INTERRUPT) { @@ -1038,7 +1028,7 @@ debugMonitorExit(jrawMonitorID monitor) { jvmtiError error; - error = FUNC_PTR(gdata->jvmti,RawMonitorExit) + error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorExit) (gdata->jvmti, monitor); error = ignore_vm_death(error); if (error != JVMTI_ERROR_NONE) { @@ -1050,7 +1040,7 @@ void debugMonitorWait(jrawMonitorID monitor) { jvmtiError error; - error = FUNC_PTR(gdata->jvmti,RawMonitorWait) + error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorWait) (gdata->jvmti, monitor, ((jlong)(-1))); /* @@ -1095,7 +1085,7 @@ void debugMonitorTimedWait(jrawMonitorID monitor, jlong millis) { jvmtiError error; - error = FUNC_PTR(gdata->jvmti,RawMonitorWait) + error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorWait) (gdata->jvmti, monitor, millis); if (error == JVMTI_ERROR_INTERRUPT) { /* See comment above */ @@ -1113,7 +1103,7 @@ debugMonitorNotify(jrawMonitorID monitor) { jvmtiError error; - error = FUNC_PTR(gdata->jvmti,RawMonitorNotify) + error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorNotify) (gdata->jvmti, monitor); error = ignore_vm_death(error); if (error != JVMTI_ERROR_NONE) { @@ -1126,7 +1116,7 @@ debugMonitorNotifyAll(jrawMonitorID monitor) { jvmtiError error; - error = FUNC_PTR(gdata->jvmti,RawMonitorNotifyAll) + error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorNotifyAll) (gdata->jvmti, monitor); error = ignore_vm_death(error); if (error != JVMTI_ERROR_NONE) { @@ -1140,7 +1130,7 @@ debugMonitorCreate(char *name) jrawMonitorID monitor; jvmtiError error; - error = FUNC_PTR(gdata->jvmti,CreateRawMonitor) + error = JVMTI_FUNC_PTR(gdata->jvmti,CreateRawMonitor) (gdata->jvmti, name, &monitor); if (error != JVMTI_ERROR_NONE) { EXIT_ERROR(error, "on creation of a raw monitor"); @@ -1153,7 +1143,7 @@ debugMonitorDestroy(jrawMonitorID monitor) { jvmtiError error; - error = FUNC_PTR(gdata->jvmti,DestroyRawMonitor) + error = JVMTI_FUNC_PTR(gdata->jvmti,DestroyRawMonitor) (gdata->jvmti, monitor); error = ignore_vm_death(error); if (error != JVMTI_ERROR_NONE) { @@ -1212,7 +1202,7 @@ classSignature(jclass clazz, char **psignature, char **pgeneric_signature) * pgeneric_signature can be NULL, and GetClassSignature * accepts NULL. */ - error = FUNC_PTR(gdata->jvmti,GetClassSignature) + error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassSignature) (gdata->jvmti, clazz, &signature, pgeneric_signature); if ( psignature != NULL ) { @@ -1784,7 +1774,7 @@ jvmtiAllocate(jint numBytes) if ( numBytes == 0 ) { return NULL; } - error = FUNC_PTR(gdata->jvmti,Allocate) + error = JVMTI_FUNC_PTR(gdata->jvmti,Allocate) (gdata->jvmti, numBytes, (unsigned char**)&ptr); if (error != JVMTI_ERROR_NONE ) { EXIT_ERROR(error, "Can't allocate jvmti memory"); @@ -1799,7 +1789,7 @@ jvmtiDeallocate(void *ptr) if ( ptr == NULL ) { return; } - error = FUNC_PTR(gdata->jvmti,Deallocate) + error = JVMTI_FUNC_PTR(gdata->jvmti,Deallocate) (gdata->jvmti, ptr); if (error != JVMTI_ERROR_NONE ) { EXIT_ERROR(error, "Can't deallocate jvmti memory"); diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/util.h b/src/jdk.jdwp.agent/share/native/libjdwp/util.h index c4d31774c64..43c4b143471 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/util.h +++ b/src/jdk.jdwp.agent/share/native/libjdwp/util.h @@ -337,7 +337,6 @@ jint jvmtiMajorVersion(void); jint jvmtiMinorVersion(void); jint jvmtiMicroVersion(void); jvmtiError getSourceDebugExtension(jclass clazz, char **extensionPtr); -jboolean canSuspendResumeThreadLists(void); jrawMonitorID debugMonitorCreate(char *name); void debugMonitorEnter(jrawMonitorID theLock); diff --git a/src/jdk.jfr/share/man/jfr.1 b/src/jdk.jfr/share/man/jfr.1 index ace59a45852..0fb8912b671 100644 --- a/src/jdk.jfr/share/man/jfr.1 +++ b/src/jdk.jfr/share/man/jfr.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JFR" "1" "2020" "JDK 15" "JDK Commands" +.TH "JFR" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jlink/share/man/jlink.1 b/src/jdk.jlink/share/man/jlink.1 index 631b1b0d147..a782d558b43 100644 --- a/src/jdk.jlink/share/man/jlink.1 +++ b/src/jdk.jlink/share/man/jlink.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JLINK" "1" "2020" "JDK 15" "JDK Commands" +.TH "JLINK" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jlink/share/man/jmod.1 b/src/jdk.jlink/share/man/jmod.1 index 5b089d8d357..d46f8708478 100644 --- a/src/jdk.jlink/share/man/jmod.1 +++ b/src/jdk.jlink/share/man/jmod.1 @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JMOD" "1" "2020" "JDK 15" "JDK Commands" +.TH "JMOD" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/DesktopIntegration.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/DesktopIntegration.java similarity index 96% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/DesktopIntegration.java rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/DesktopIntegration.java index 9396bfb93c3..9311d9dc282 100644 --- a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/DesktopIntegration.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/DesktopIntegration.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.awt.image.BufferedImage; import java.io.BufferedReader; @@ -46,16 +46,16 @@ import javax.imageio.ImageIO; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import jdk.incubator.jpackage.internal.Arguments.CLIOptions; -import static jdk.incubator.jpackage.internal.LinuxAppImageBuilder.DEFAULT_ICON; -import static jdk.incubator.jpackage.internal.LinuxAppImageBuilder.ICON_PNG; -import static jdk.incubator.jpackage.internal.OverridableResource.createResource; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.DESCRIPTION; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.FILE_ASSOCIATIONS; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.ICON; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE; +import jdk.jpackage.internal.Arguments.CLIOptions; +import static jdk.jpackage.internal.LinuxAppImageBuilder.DEFAULT_ICON; +import static jdk.jpackage.internal.LinuxAppImageBuilder.ICON_PNG; +import static jdk.jpackage.internal.OverridableResource.createResource; +import static jdk.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.DESCRIPTION; +import static jdk.jpackage.internal.StandardBundlerParam.FILE_ASSOCIATIONS; +import static jdk.jpackage.internal.StandardBundlerParam.ICON; +import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE; /** * Helper to create files for desktop integration. diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LibProvidersLookup.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LibProvidersLookup.java similarity index 91% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LibProvidersLookup.java rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LibProvidersLookup.java index aa0b3bbf852..10df465a0fb 100644 --- a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LibProvidersLookup.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LibProvidersLookup.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Files; @@ -153,17 +153,17 @@ public interface PackageLookup { // // Typical ldd output: // - // ldd: warning: you do not have execution permission for `/tmp/jdk.incubator.jpackage17911687595930080396/images/opt/simplepackagetest/lib/runtime/lib/libawt_headless.so' + // ldd: warning: you do not have execution permission for `/tmp/jdk.jpackage17911687595930080396/images/opt/simplepackagetest/lib/runtime/lib/libawt_headless.so' // linux-vdso.so.1 => (0x00007ffce6bfd000) - // libawt.so => /tmp/jdk.incubator.jpackage17911687595930080396/images/opt/simplepackagetest/lib/runtime/lib/libawt.so (0x00007f4e00c75000) + // libawt.so => /tmp/jdk.jpackage17911687595930080396/images/opt/simplepackagetest/lib/runtime/lib/libawt.so (0x00007f4e00c75000) // libjvm.so => not found - // libjava.so => /tmp/jdk.incubator.jpackage17911687595930080396/images/opt/simplepackagetest/lib/runtime/lib/libjava.so (0x00007f4e00c41000) + // libjava.so => /tmp/jdk.jpackage17911687595930080396/images/opt/simplepackagetest/lib/runtime/lib/libjava.so (0x00007f4e00c41000) // libm.so.6 => /lib64/libm.so.6 (0x00007f4e00834000) // libdl.so.2 => /lib64/libdl.so.2 (0x00007f4e00630000) // libc.so.6 => /lib64/libc.so.6 (0x00007f4e00262000) // libjvm.so => not found // libjvm.so => not found - // libverify.so => /tmp/jdk.incubator.jpackage17911687595930080396/images/opt/simplepackagetest/lib/runtime/lib/libverify.so (0x00007f4e00c2e000) + // libverify.so => /tmp/jdk.jpackage17911687595930080396/images/opt/simplepackagetest/lib/runtime/lib/libverify.so (0x00007f4e00c2e000) // /lib64/ld-linux-x86-64.so.2 (0x00007f4e00b36000) // libjvm.so => not found // diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxAppBundler.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppBundler.java similarity index 97% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxAppBundler.java rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppBundler.java index 1978db0fd6e..9a308155f78 100644 --- a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxAppBundler.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppBundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; public class LinuxAppBundler extends AppImageBundler { public LinuxAppBundler() { diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxAppImageBuilder.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java similarity index 94% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxAppImageBuilder.java rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java index 0afca510b09..b5d602afe65 100644 --- a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxAppImageBuilder.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.io.InputStream; @@ -32,9 +32,9 @@ import java.text.MessageFormat; import java.util.List; import java.util.Map; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.ICON; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.ICON; +import static jdk.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; public class LinuxAppImageBuilder extends AbstractAppImageBuilder { diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxDebBundler.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java similarity index 97% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxDebBundler.java rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java index e79de26b4e1..3732193a20b 100644 --- a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxDebBundler.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxDebBundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.FileVisitResult; @@ -45,13 +45,13 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import static jdk.incubator.jpackage.internal.OverridableResource.createResource; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.RELEASE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VENDOR; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.LICENSE_FILE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.COPYRIGHT; +import static jdk.jpackage.internal.OverridableResource.createResource; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.StandardBundlerParam.RELEASE; +import static jdk.jpackage.internal.StandardBundlerParam.VENDOR; +import static jdk.jpackage.internal.StandardBundlerParam.LICENSE_FILE; +import static jdk.jpackage.internal.StandardBundlerParam.COPYRIGHT; public class LinuxDebBundler extends LinuxPackageBundler { diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxPackageBundler.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java similarity index 95% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxPackageBundler.java rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java index 622d93dab35..e2e03087717 100644 --- a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxPackageBundler.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.InvalidPathException; @@ -40,13 +40,13 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; -import static jdk.incubator.jpackage.internal.DesktopIntegration.*; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.PREDEFINED_RUNTIME_IMAGE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.RELEASE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VENDOR; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.DESCRIPTION; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.INSTALL_DIR; +import static jdk.jpackage.internal.DesktopIntegration.*; +import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_RUNTIME_IMAGE; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.StandardBundlerParam.RELEASE; +import static jdk.jpackage.internal.StandardBundlerParam.VENDOR; +import static jdk.jpackage.internal.StandardBundlerParam.DESCRIPTION; +import static jdk.jpackage.internal.StandardBundlerParam.INSTALL_DIR; abstract class LinuxPackageBundler extends AbstractBundler { diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxRpmBundler.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java similarity index 96% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxRpmBundler.java rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java index 4ddddf0ae91..ac33836579e 100644 --- a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/LinuxRpmBundler.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxRpmBundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Path; @@ -37,12 +37,12 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.LICENSE_FILE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.RELEASE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.TEMP_ROOT; -import static jdk.incubator.jpackage.internal.OverridableResource.createResource; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.LICENSE_FILE; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.StandardBundlerParam.RELEASE; +import static jdk.jpackage.internal.StandardBundlerParam.TEMP_ROOT; +import static jdk.jpackage.internal.OverridableResource.createResource; /** * There are two command line options to configure license information for RPM diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/PackageProperty.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/PackageProperty.java similarity index 98% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/PackageProperty.java rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/PackageProperty.java index 8d2f2ffef88..b9f43b93742 100644 --- a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/PackageProperty.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/PackageProperty.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.text.MessageFormat; diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/LinuxResources.properties b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources.properties similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/LinuxResources.properties rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources.properties diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/LinuxResources_ja.properties b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_ja.properties similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/LinuxResources_ja.properties rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_ja.properties diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/LinuxResources_zh_CN.properties b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_zh_CN.properties similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/LinuxResources_zh_CN.properties rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_zh_CN.properties diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/java32.png b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/java32.png similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/java32.png rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/java32.png diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.control b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.control similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.control rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.control diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.copyright b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.copyright similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.copyright rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.copyright diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.desktop b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.desktop similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.desktop rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.desktop diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.postinst b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.postinst similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.postinst rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.postinst diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.postrm b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.postrm similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.postrm rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.postrm diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.preinst b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.preinst similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.preinst rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.preinst diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.prerm b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.prerm similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.prerm rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.prerm diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.spec b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.spec similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/template.spec rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/template.spec diff --git a/src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/utils.sh b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/utils.sh similarity index 100% rename from src/jdk.incubator.jpackage/linux/classes/jdk/incubator/jpackage/internal/resources/utils.sh rename to src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/utils.sh diff --git a/src/jdk.incubator.jpackage/windows/classes/module-info.java.extra b/src/jdk.jpackage/linux/classes/module-info.java.extra similarity index 85% rename from src/jdk.incubator.jpackage/windows/classes/module-info.java.extra rename to src/jdk.jpackage/linux/classes/module-info.java.extra index 6e34520b6d1..d32314b0429 100644 --- a/src/jdk.incubator.jpackage/windows/classes/module-info.java.extra +++ b/src/jdk.jpackage/linux/classes/module-info.java.extra @@ -23,8 +23,8 @@ * questions. */ -provides jdk.incubator.jpackage.internal.Bundler with - jdk.incubator.jpackage.internal.WinAppBundler, - jdk.incubator.jpackage.internal.WinExeBundler, - jdk.incubator.jpackage.internal.WinMsiBundler; +provides jdk.jpackage.internal.Bundler with + jdk.jpackage.internal.LinuxAppBundler, + jdk.jpackage.internal.LinuxDebBundler, + jdk.jpackage.internal.LinuxRpmBundler; diff --git a/src/jdk.incubator.jpackage/linux/native/applauncher/Executor.cpp b/src/jdk.jpackage/linux/native/applauncher/Executor.cpp similarity index 100% rename from src/jdk.incubator.jpackage/linux/native/applauncher/Executor.cpp rename to src/jdk.jpackage/linux/native/applauncher/Executor.cpp diff --git a/src/jdk.incubator.jpackage/linux/native/applauncher/Executor.h b/src/jdk.jpackage/linux/native/applauncher/Executor.h similarity index 100% rename from src/jdk.incubator.jpackage/linux/native/applauncher/Executor.h rename to src/jdk.jpackage/linux/native/applauncher/Executor.h diff --git a/src/jdk.incubator.jpackage/linux/native/applauncher/LinuxLauncher.cpp b/src/jdk.jpackage/linux/native/applauncher/LinuxLauncher.cpp similarity index 100% rename from src/jdk.incubator.jpackage/linux/native/applauncher/LinuxLauncher.cpp rename to src/jdk.jpackage/linux/native/applauncher/LinuxLauncher.cpp diff --git a/src/jdk.incubator.jpackage/linux/native/applauncher/Package.cpp b/src/jdk.jpackage/linux/native/applauncher/Package.cpp similarity index 100% rename from src/jdk.incubator.jpackage/linux/native/applauncher/Package.cpp rename to src/jdk.jpackage/linux/native/applauncher/Package.cpp diff --git a/src/jdk.incubator.jpackage/linux/native/applauncher/Package.h b/src/jdk.jpackage/linux/native/applauncher/Package.h similarity index 100% rename from src/jdk.incubator.jpackage/linux/native/applauncher/Package.h rename to src/jdk.jpackage/linux/native/applauncher/Package.h diff --git a/src/jdk.incubator.jpackage/linux/native/common/LinuxSysInfo.cpp b/src/jdk.jpackage/linux/native/common/LinuxSysInfo.cpp similarity index 100% rename from src/jdk.incubator.jpackage/linux/native/common/LinuxSysInfo.cpp rename to src/jdk.jpackage/linux/native/common/LinuxSysInfo.cpp diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/CFBundleVersion.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/CFBundleVersion.java similarity index 98% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/CFBundleVersion.java rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/CFBundleVersion.java index a144f0f29e3..61bedfb8e67 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/CFBundleVersion.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/CFBundleVersion.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.math.BigInteger; diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppBundler.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppBundler.java similarity index 92% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppBundler.java rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppBundler.java index aba31acbd71..e7054c4c122 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppBundler.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppBundler.java @@ -23,17 +23,17 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.text.MessageFormat; import java.util.Map; import java.util.Optional; -import static jdk.incubator.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEYCHAIN; -import static jdk.incubator.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEY_USER; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.MAIN_CLASS; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERBOSE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEYCHAIN; +import static jdk.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEY_USER; +import static jdk.jpackage.internal.StandardBundlerParam.MAIN_CLASS; +import static jdk.jpackage.internal.StandardBundlerParam.VERBOSE; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; public class MacAppBundler extends AppImageBundler { public MacAppBundler() { diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppImageBuilder.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java similarity index 95% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppImageBuilder.java rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java index 3f51bc824ce..82ba22ac344 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppImageBuilder.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppImageBuilder.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.io.InputStream; @@ -49,28 +49,28 @@ import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; -import static jdk.incubator.jpackage.internal.MacAppBundler.BUNDLE_ID_SIGNING_PREFIX; -import static jdk.incubator.jpackage.internal.MacAppBundler.DEVELOPER_ID_APP_SIGNING_KEY; -import static jdk.incubator.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEYCHAIN; -import static jdk.incubator.jpackage.internal.OverridableResource.createResource; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.COPYRIGHT; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.FA_CONTENT_TYPE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.FA_DESCRIPTION; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.FA_EXTENSIONS; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.FA_ICON; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.FILE_ASSOCIATIONS; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.ICON; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.MAIN_CLASS; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; +import static jdk.jpackage.internal.MacAppBundler.BUNDLE_ID_SIGNING_PREFIX; +import static jdk.jpackage.internal.MacAppBundler.DEVELOPER_ID_APP_SIGNING_KEY; +import static jdk.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEYCHAIN; +import static jdk.jpackage.internal.OverridableResource.createResource; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; +import static jdk.jpackage.internal.StandardBundlerParam.COPYRIGHT; +import static jdk.jpackage.internal.StandardBundlerParam.FA_CONTENT_TYPE; +import static jdk.jpackage.internal.StandardBundlerParam.FA_DESCRIPTION; +import static jdk.jpackage.internal.StandardBundlerParam.FA_EXTENSIONS; +import static jdk.jpackage.internal.StandardBundlerParam.FA_ICON; +import static jdk.jpackage.internal.StandardBundlerParam.FILE_ASSOCIATIONS; +import static jdk.jpackage.internal.StandardBundlerParam.ICON; +import static jdk.jpackage.internal.StandardBundlerParam.MAIN_CLASS; +import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; public class MacAppImageBuilder extends AbstractAppImageBuilder { private static final ResourceBundle I18N = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.MacResources"); + "jdk.jpackage.internal.resources.MacResources"); private static final String TEMPLATE_BUNDLE_ICON = "java.icns"; private static final String OS_TYPE_CODE = "APPL"; diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppStoreBundler.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppStoreBundler.java similarity index 94% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppStoreBundler.java rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppStoreBundler.java index 44e7ecf0581..8dcbdd8b765 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacAppStoreBundler.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacAppStoreBundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.nio.file.Files; import java.nio.file.Path; @@ -35,16 +35,16 @@ import java.util.Optional; import java.util.ResourceBundle; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERBOSE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.MacAppBundler.DEVELOPER_ID_APP_SIGNING_KEY; -import static jdk.incubator.jpackage.internal.MacAppBundler.DEFAULT_ICNS_ICON; -import static jdk.incubator.jpackage.internal.MacAppBundler.BUNDLE_ID_SIGNING_PREFIX; +import static jdk.jpackage.internal.StandardBundlerParam.VERBOSE; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.MacAppBundler.DEVELOPER_ID_APP_SIGNING_KEY; +import static jdk.jpackage.internal.MacAppBundler.DEFAULT_ICNS_ICON; +import static jdk.jpackage.internal.MacAppBundler.BUNDLE_ID_SIGNING_PREFIX; public class MacAppStoreBundler extends MacBaseInstallerBundler { private static final ResourceBundle I18N = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.MacResources"); + "jdk.jpackage.internal.resources.MacResources"); private static final String TEMPLATE_BUNDLE_ICON_HIDPI = "java.icns"; diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacBaseInstallerBundler.java similarity index 95% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacBaseInstallerBundler.java index 1d7c999ba2d..4d38cd3e167 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacBaseInstallerBundler.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacBaseInstallerBundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -36,10 +36,10 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.INSTALL_DIR; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.INSTALL_DIR; +import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; public abstract class MacBaseInstallerBundler extends AbstractBundler { diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacCertificate.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacCertificate.java similarity index 99% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacCertificate.java rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacCertificate.java index b1c0ec78bca..75dd82c8ff0 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacCertificate.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacCertificate.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java similarity index 96% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java index 2973731010f..32b5c261097 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacDmgBundler.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.BufferedReader; import java.io.File; @@ -37,20 +37,20 @@ import java.util.Map; import java.util.Objects; import java.util.ResourceBundle; -import static jdk.incubator.jpackage.internal.MacAppImageBuilder.ICON_ICNS; -import static jdk.incubator.jpackage.internal.MacAppImageBuilder.MAC_CF_BUNDLE_IDENTIFIER; -import static jdk.incubator.jpackage.internal.OverridableResource.createResource; +import static jdk.jpackage.internal.MacAppImageBuilder.ICON_ICNS; +import static jdk.jpackage.internal.MacAppImageBuilder.MAC_CF_BUNDLE_IDENTIFIER; +import static jdk.jpackage.internal.OverridableResource.createResource; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.LICENSE_FILE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.TEMP_ROOT; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERBOSE; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; +import static jdk.jpackage.internal.StandardBundlerParam.LICENSE_FILE; +import static jdk.jpackage.internal.StandardBundlerParam.TEMP_ROOT; +import static jdk.jpackage.internal.StandardBundlerParam.VERBOSE; public class MacDmgBundler extends MacBaseInstallerBundler { private static final ResourceBundle I18N = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.MacResources"); + "jdk.jpackage.internal.resources.MacResources"); // Background image name in resources static final String DEFAULT_BACKGROUND_IMAGE = "background_dmg.tiff"; diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java similarity index 96% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java index 5b5b8189234..27b74a10641 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.io.PrintWriter; @@ -40,21 +40,21 @@ import java.util.Optional; import java.util.ResourceBundle; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.TEMP_ROOT; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERBOSE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.LICENSE_FILE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; -import static jdk.incubator.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEYCHAIN; -import static jdk.incubator.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEY_USER; -import static jdk.incubator.jpackage.internal.MacAppImageBuilder.MAC_CF_BUNDLE_IDENTIFIER; -import static jdk.incubator.jpackage.internal.OverridableResource.createResource; +import static jdk.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; +import static jdk.jpackage.internal.StandardBundlerParam.TEMP_ROOT; +import static jdk.jpackage.internal.StandardBundlerParam.VERBOSE; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.LICENSE_FILE; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEYCHAIN; +import static jdk.jpackage.internal.MacBaseInstallerBundler.SIGNING_KEY_USER; +import static jdk.jpackage.internal.MacAppImageBuilder.MAC_CF_BUNDLE_IDENTIFIER; +import static jdk.jpackage.internal.OverridableResource.createResource; public class MacPkgBundler extends MacBaseInstallerBundler { private static final ResourceBundle I18N = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.MacResources"); + "jdk.jpackage.internal.resources.MacResources"); private static final String DEFAULT_BACKGROUND_IMAGE = "background_pkg.png"; diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/DMGsetup.scpt b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/DMGsetup.scpt similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/DMGsetup.scpt rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/DMGsetup.scpt diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/Info-lite.plist.template b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/Info-lite.plist.template similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/Info-lite.plist.template rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/Info-lite.plist.template diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources.properties b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources.properties rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources.properties diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_ja.properties b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_ja.properties similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_ja.properties rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_ja.properties diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_zh_CN.properties b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_zh_CN.properties similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/MacResources_zh_CN.properties rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_zh_CN.properties diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/Runtime-Info.plist.template b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/Runtime-Info.plist.template similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/Runtime-Info.plist.template rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/Runtime-Info.plist.template diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/background_dmg.tiff b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/background_dmg.tiff similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/background_dmg.tiff rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/background_dmg.tiff diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/background_pkg.png b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/background_pkg.png similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/background_pkg.png rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/background_pkg.png diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/java.icns b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/java.icns similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/java.icns rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/java.icns diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/lic_template.plist b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/lic_template.plist similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/lic_template.plist rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/lic_template.plist diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/postinstall.template b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/postinstall.template similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/postinstall.template rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/postinstall.template diff --git a/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/preinstall.template b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/preinstall.template similarity index 100% rename from src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/resources/preinstall.template rename to src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/preinstall.template diff --git a/src/jdk.incubator.jpackage/linux/classes/module-info.java.extra b/src/jdk.jpackage/macosx/classes/module-info.java.extra similarity index 85% rename from src/jdk.incubator.jpackage/linux/classes/module-info.java.extra rename to src/jdk.jpackage/macosx/classes/module-info.java.extra index 0c2987a8bf4..158209e9796 100644 --- a/src/jdk.incubator.jpackage/linux/classes/module-info.java.extra +++ b/src/jdk.jpackage/macosx/classes/module-info.java.extra @@ -23,8 +23,9 @@ * questions. */ -provides jdk.incubator.jpackage.internal.Bundler with - jdk.incubator.jpackage.internal.LinuxAppBundler, - jdk.incubator.jpackage.internal.LinuxDebBundler, - jdk.incubator.jpackage.internal.LinuxRpmBundler; +provides jdk.jpackage.internal.Bundler with + jdk.jpackage.internal.MacAppBundler, + jdk.jpackage.internal.MacAppStoreBundler, + jdk.jpackage.internal.MacDmgBundler, + jdk.jpackage.internal.MacPkgBundler; diff --git a/src/jdk.incubator.jpackage/macosx/native/applauncher/MacLauncher.cpp b/src/jdk.jpackage/macosx/native/applauncher/MacLauncher.cpp similarity index 100% rename from src/jdk.incubator.jpackage/macosx/native/applauncher/MacLauncher.cpp rename to src/jdk.jpackage/macosx/native/applauncher/MacLauncher.cpp diff --git a/src/jdk.incubator.jpackage/macosx/native/common/MacSysInfo.cpp b/src/jdk.jpackage/macosx/native/common/MacSysInfo.cpp similarity index 100% rename from src/jdk.incubator.jpackage/macosx/native/common/MacSysInfo.cpp rename to src/jdk.jpackage/macosx/native/common/MacSysInfo.cpp diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AbstractAppImageBuilder.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java similarity index 91% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AbstractAppImageBuilder.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java index a941c66d721..da73b9a6419 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AbstractAppImageBuilder.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java @@ -23,17 +23,17 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.util.Map; -import static jdk.incubator.jpackage.internal.OverridableResource.createResource; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.ICON; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.SOURCE_DIR; -import jdk.incubator.jpackage.internal.resources.ResourceLocator; +import static jdk.jpackage.internal.OverridableResource.createResource; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.ICON; +import static jdk.jpackage.internal.StandardBundlerParam.SOURCE_DIR; +import jdk.jpackage.internal.resources.ResourceLocator; /* * AbstractAppImageBuilder diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AbstractBundler.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java similarity index 98% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AbstractBundler.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java index ef2ed7433ba..b615176fd15 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AbstractBundler.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Path; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AddLauncherArguments.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AddLauncherArguments.java similarity index 97% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AddLauncherArguments.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/AddLauncherArguments.java index ade19cd2c3a..bf2107f6210 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AddLauncherArguments.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AddLauncherArguments.java @@ -23,14 +23,14 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.nio.file.Path; import java.util.HashMap; import java.util.Map; import java.util.List; -import jdk.incubator.jpackage.internal.Arguments.CLIOptions; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.LAUNCHER_DATA; +import jdk.jpackage.internal.Arguments.CLIOptions; +import static jdk.jpackage.internal.StandardBundlerParam.LAUNCHER_DATA; /* * AddLauncherArguments diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AppImageBundler.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageBundler.java similarity index 93% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AppImageBundler.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageBundler.java index 56c0633bb07..5ee569c94e4 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AppImageBundler.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageBundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Files; @@ -32,10 +32,10 @@ import java.util.Map; import java.util.Objects; import java.util.function.Function; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.PREDEFINED_RUNTIME_IMAGE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.LAUNCHER_DATA; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE; +import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_RUNTIME_IMAGE; +import static jdk.jpackage.internal.StandardBundlerParam.LAUNCHER_DATA; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; class AppImageBundler extends AbstractBundler { diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AppImageFile.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java similarity index 97% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AppImageFile.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java index d51f40fa825..a2b4278e47c 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/AppImageFile.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Files; @@ -43,9 +43,9 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; public class AppImageFile { diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ApplicationLayout.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ApplicationLayout.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ApplicationLayout.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/ApplicationLayout.java index ef2e1eef136..c725afed3a1 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ApplicationLayout.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ApplicationLayout.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.nio.file.Path; import java.util.Map; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Arguments.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java similarity index 98% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Arguments.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java index 9efcbe8cc8f..ae44d28b8f7 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Arguments.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.io.Reader; @@ -57,7 +57,7 @@ */ public class Arguments { private static final ResourceBundle I18N = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.MainResources"); + "jdk.jpackage.internal.resources.MainResources"); private static final String FA_EXTENSIONS = "extension"; private static final String FA_CONTENT_TYPE = "mime-type"; @@ -615,12 +615,12 @@ private void validateArguments() throws PackagerException { } } - private jdk.incubator.jpackage.internal.Bundler getPlatformBundler() { + private jdk.jpackage.internal.Bundler getPlatformBundler() { boolean appImage = deployParams.isTargetAppImage(); String type = deployParams.getTargetFormat(); String bundleType = (appImage ? "IMAGE" : "INSTALLER"); - for (jdk.incubator.jpackage.internal.Bundler bundler : + for (jdk.jpackage.internal.Bundler bundler : Bundlers.createBundlersInstance().getBundlers(bundleType)) { if (type == null) { if (bundler.isDefault() @@ -651,7 +651,7 @@ private void generateBundle(Map params) StandardBundlerParam.TEMP_ROOT.fetchFrom(params); // determine what bundler to run - jdk.incubator.jpackage.internal.Bundler bundler = getPlatformBundler(); + jdk.jpackage.internal.Bundler bundler = getPlatformBundler(); if (bundler == null) { throw new PackagerException("ERR_InvalidInstallerType", diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/BasicBundlers.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BasicBundlers.java similarity index 98% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/BasicBundlers.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/BasicBundlers.java index f6ad3cbe17a..7f444fe7337 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/BasicBundlers.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BasicBundlers.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.Arrays; import java.util.Collection; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/BundleParams.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java similarity index 95% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/BundleParams.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java index de56acc110b..453d6963be2 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/BundleParams.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java @@ -23,11 +23,11 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.HashMap; import java.util.Map; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; public class BundleParams { diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Bundler.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Bundler.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Bundler.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/Bundler.java index be702f711ea..59916fc3ca1 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Bundler.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Bundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.nio.file.Path; import java.util.Map; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/BundlerParamInfo.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundlerParamInfo.java similarity index 98% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/BundlerParamInfo.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundlerParamInfo.java index 0db8c8cc95b..4173980002b 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/BundlerParamInfo.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundlerParamInfo.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.Map; import java.util.function.BiFunction; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Bundlers.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Bundlers.java similarity index 98% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Bundlers.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/Bundlers.java index 88150ce4f0e..955952d563d 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Bundlers.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Bundlers.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.Collection; import java.util.Iterator; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/CLIHelp.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/CLIHelp.java similarity index 97% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/CLIHelp.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/CLIHelp.java index 6f803d549b8..d9ee8d81bfd 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/CLIHelp.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/CLIHelp.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.ResourceBundle; import java.io.File; @@ -38,7 +38,7 @@ public class CLIHelp { private static final ResourceBundle I18N = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.HelpResources"); + "jdk.jpackage.internal.resources.HelpResources"); // generates --help for jpackage's CLI public static void showHelp(boolean noArgs) { diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/CfgFile.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/CfgFile.java similarity index 92% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/CfgFile.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/CfgFile.java index 99d3f77bbfa..0826e3970a4 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/CfgFile.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/CfgFile.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.io.File; @@ -32,11 +32,11 @@ import java.util.List; import java.util.Map; import java.util.stream.Stream; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.LAUNCHER_DATA; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.JAVA_OPTIONS; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.ARGUMENTS; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.StandardBundlerParam.LAUNCHER_DATA; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.JAVA_OPTIONS; +import static jdk.jpackage.internal.StandardBundlerParam.ARGUMENTS; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; /** * App launcher's config file. diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ConfigException.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ConfigException.java similarity index 97% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ConfigException.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/ConfigException.java index 8dba7bd383c..5a43fbe93fe 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ConfigException.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ConfigException.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; public class ConfigException extends Exception { private static final long serialVersionUID = 1L; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/DeployParams.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/DeployParams.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java index 2c54a089ce5..0783c327e11 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/DeployParams.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.File; import java.io.IOException; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/DottedVersion.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DottedVersion.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/DottedVersion.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/DottedVersion.java index 8ade9a28ace..652c90ae1e6 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/DottedVersion.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DottedVersion.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.math.BigInteger; import java.text.MessageFormat; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Executor.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Executor.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Executor.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/Executor.java index 0ada00dec68..320a63190b5 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Executor.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Executor.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.BufferedReader; import java.io.IOException; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/FileAssociation.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/FileAssociation.java similarity index 88% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/FileAssociation.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/FileAssociation.java index b4b9be9f150..7f8ff7fa168 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/FileAssociation.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/FileAssociation.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.nio.file.Path; import java.text.MessageFormat; @@ -33,12 +33,12 @@ import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.FILE_ASSOCIATIONS; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.FA_EXTENSIONS; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.FA_CONTENT_TYPE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.FA_ICON; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.FA_DESCRIPTION; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.FILE_ASSOCIATIONS; +import static jdk.jpackage.internal.StandardBundlerParam.FA_EXTENSIONS; +import static jdk.jpackage.internal.StandardBundlerParam.FA_CONTENT_TYPE; +import static jdk.jpackage.internal.StandardBundlerParam.FA_ICON; +import static jdk.jpackage.internal.StandardBundlerParam.FA_DESCRIPTION; final class FileAssociation { void verify() { diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/I18N.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/I18N.java similarity index 84% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/I18N.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/I18N.java index dac2e930c85..f349b71126e 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/I18N.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/I18N.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.ResourceBundle; @@ -36,20 +36,20 @@ static String getString(String key) { } private static final ResourceBundle SHARED = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.MainResources"); + "jdk.jpackage.internal.resources.MainResources"); private static final ResourceBundle PLATFORM; static { if (Platform.isLinux()) { PLATFORM = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.LinuxResources"); + "jdk.jpackage.internal.resources.LinuxResources"); } else if (Platform.isWindows()) { PLATFORM = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.WinResources"); + "jdk.jpackage.internal.resources.WinResources"); } else if (Platform.isMac()) { PLATFORM = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.MacResources"); + "jdk.jpackage.internal.resources.MacResources"); } else { throw new IllegalStateException("Unknwon platform"); } diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/IOUtils.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/IOUtils.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java index 27ae1f175b9..414ae2275ee 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/IOUtils.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.BufferedReader; import java.io.InputStreamReader; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/JLinkBundlerHelper.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/JLinkBundlerHelper.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java index cbd9eda8d43..343c469f931 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/JLinkBundlerHelper.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.File; import java.io.IOException; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/JPackageToolProvider.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/JPackageToolProvider.java similarity index 93% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/JPackageToolProvider.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/JPackageToolProvider.java index e4d18a4656f..18f7f5df21a 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/JPackageToolProvider.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/JPackageToolProvider.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.PrintWriter; import java.util.spi.ToolProvider; @@ -43,7 +43,7 @@ public String name() { public synchronized int run( PrintWriter out, PrintWriter err, String... args) { try { - return new jdk.incubator.jpackage.main.Main().execute(out, err, args); + return new jdk.jpackage.main.Main().execute(out, err, args); } catch (RuntimeException re) { Log.fatalError(re.getMessage()); Log.verbose(re); diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/LauncherData.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/LauncherData.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/LauncherData.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/LauncherData.java index ef9d36854f3..2541ffdc20a 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/LauncherData.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/LauncherData.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.File; import java.io.IOException; @@ -46,7 +46,7 @@ import java.util.jar.Manifest; import java.util.stream.Collectors; import java.util.stream.Stream; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.PREDEFINED_RUNTIME_IMAGE; +import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_RUNTIME_IMAGE; /** * Extracts data needed to run application from parameters. diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Log.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Log.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Log.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/Log.java index e1e6b1bff05..c20066075d2 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Log.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Log.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.PrintWriter; import java.text.SimpleDateFormat; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/OverridableResource.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/OverridableResource.java similarity index 97% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/OverridableResource.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/OverridableResource.java index c29a8b63840..23ed0ee7477 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/OverridableResource.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/OverridableResource.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.BufferedReader; import java.io.ByteArrayInputStream; @@ -42,8 +42,8 @@ import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.RESOURCE_DIR; -import jdk.incubator.jpackage.internal.resources.ResourceLocator; +import static jdk.jpackage.internal.StandardBundlerParam.RESOURCE_DIR; +import jdk.jpackage.internal.resources.ResourceLocator; /** @@ -52,7 +52,7 @@ * jpackage parameter. * * Resource has default name and public name. Default name is the name of a file - * in {@code jdk.incubator.jpackage.internal.resources} package that provides the default + * in {@code jdk.jpackage.internal.resources} package that provides the default * value of the resource. * * Public name is a path relative to resource directory to a file with custom diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/PackagerException.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PackagerException.java similarity index 94% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/PackagerException.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/PackagerException.java index e5414b23188..b5f514ae1ab 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/PackagerException.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PackagerException.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.text.MessageFormat; import java.util.ResourceBundle; @@ -31,7 +31,7 @@ public class PackagerException extends Exception { private static final long serialVersionUID = 1L; private static final ResourceBundle bundle = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.MainResources"); + "jdk.jpackage.internal.resources.MainResources"); public PackagerException(Throwable cause) { super(cause); diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/PathGroup.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PathGroup.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/PathGroup.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/PathGroup.java index d7e332f3fbf..2cb44db59f9 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/PathGroup.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PathGroup.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Files; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Platform.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Platform.java similarity index 98% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Platform.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/Platform.java index 7b03b36fe4d..5849c1777ac 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/Platform.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Platform.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.regex.Pattern; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/PlatformPackage.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PlatformPackage.java similarity index 97% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/PlatformPackage.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/PlatformPackage.java index 54aa2333df4..6102e24c015 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/PlatformPackage.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PlatformPackage.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.nio.file.Path; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/RetryExecutor.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/RetryExecutor.java similarity index 98% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/RetryExecutor.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/RetryExecutor.java index 2370389d52b..dfa75b217af 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/RetryExecutor.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/RetryExecutor.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.util.function.Consumer; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ScriptRunner.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ScriptRunner.java similarity index 92% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ScriptRunner.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/ScriptRunner.java index 9d6f037b400..47fe75da4bc 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ScriptRunner.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ScriptRunner.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Files; @@ -31,9 +31,9 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; -import static jdk.incubator.jpackage.internal.OverridableResource.createResource; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; +import static jdk.jpackage.internal.OverridableResource.createResource; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; /** * Runs custom script from resource directory. diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/StandardBundlerParam.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/StandardBundlerParam.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java index 173e5183f94..ec8ede14dc4 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/StandardBundlerParam.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.File; import java.io.IOException; @@ -235,7 +235,7 @@ class StandardBundlerParam extends BundlerParamInfo { Path.class, params -> { try { - return Files.createTempDirectory("jdk.incubator.jpackage"); + return Files.createTempDirectory("jdk.jpackage"); } catch (IOException ioe) { return null; } diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ToolValidator.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ToolValidator.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ToolValidator.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/ToolValidator.java index 497d46e19be..04519ca710a 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ToolValidator.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ToolValidator.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Path; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ValidOptions.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ValidOptions.java similarity index 98% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ValidOptions.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/ValidOptions.java index de56d448473..5fb8a68fbe2 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/ValidOptions.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ValidOptions.java @@ -23,10 +23,10 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.HashMap; -import jdk.incubator.jpackage.internal.Arguments.CLIOptions; +import jdk.jpackage.internal.Arguments.CLIOptions; /** * ValidOptions diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/HelpResources.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties similarity index 100% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/HelpResources.properties rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/HelpResources_ja.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties similarity index 100% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/HelpResources_ja.properties rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/HelpResources_zh_CN.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties similarity index 100% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/HelpResources_zh_CN.properties rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties similarity index 100% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources.properties rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources_ja.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties similarity index 100% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources_ja.properties rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources_zh_CN.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties similarity index 100% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/MainResources_zh_CN.properties rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/ResourceLocator.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/ResourceLocator.java similarity index 96% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/ResourceLocator.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/ResourceLocator.java index c51d1daf425..dfb5da7f829 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/internal/resources/ResourceLocator.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/ResourceLocator.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal.resources; +package jdk.jpackage.internal.resources; /* * ResourceLocator diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/main/CommandLine.java b/src/jdk.jpackage/share/classes/jdk/jpackage/main/CommandLine.java similarity index 99% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/main/CommandLine.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/main/CommandLine.java index 08ebc23f8fa..e9ab994624b 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/main/CommandLine.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/main/CommandLine.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.main; +package jdk.jpackage.main; import java.io.FileNotFoundException; import java.io.IOException; diff --git a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/main/Main.java b/src/jdk.jpackage/share/classes/jdk/jpackage/main/Main.java similarity index 92% rename from src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/main/Main.java rename to src/jdk.jpackage/share/classes/jdk/jpackage/main/Main.java index 7cf25e872c6..1381902f52a 100644 --- a/src/jdk.incubator.jpackage/share/classes/jdk/incubator/jpackage/main/Main.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/main/Main.java @@ -23,11 +23,11 @@ * questions. */ -package jdk.incubator.jpackage.main; +package jdk.jpackage.main; -import jdk.incubator.jpackage.internal.Arguments; -import jdk.incubator.jpackage.internal.Log; -import jdk.incubator.jpackage.internal.CLIHelp; +import jdk.jpackage.internal.Arguments; +import jdk.jpackage.internal.Log; +import jdk.jpackage.internal.CLIHelp; import java.io.PrintWriter; import java.util.ResourceBundle; import java.io.FileNotFoundException; @@ -37,7 +37,7 @@ public class Main { private static final ResourceBundle I18N = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.MainResources"); + "jdk.jpackage.internal.resources.MainResources"); /** * main(String... args) @@ -49,7 +49,7 @@ public static void main(String... args) throws Exception { // Create logger with default system.out and system.err Log.setLogger(null); - int status = new jdk.incubator.jpackage.main.Main().execute(args); + int status = new jdk.jpackage.main.Main().execute(args); System.exit(status); } diff --git a/src/jdk.incubator.jpackage/share/classes/module-info.java b/src/jdk.jpackage/share/classes/module-info.java similarity index 86% rename from src/jdk.incubator.jpackage/share/classes/module-info.java rename to src/jdk.jpackage/share/classes/module-info.java index 1b516403a71..475daa0bd56 100644 --- a/src/jdk.incubator.jpackage/share/classes/module-info.java +++ b/src/jdk.jpackage/share/classes/module-info.java @@ -43,20 +43,20 @@ * * * @moduleGraph - * @since 14 + * @since 16 */ -module jdk.incubator.jpackage { +module jdk.jpackage { requires jdk.jlink; requires java.desktop; - uses jdk.incubator.jpackage.internal.Bundler; - uses jdk.incubator.jpackage.internal.Bundlers; + uses jdk.jpackage.internal.Bundler; + uses jdk.jpackage.internal.Bundlers; - provides jdk.incubator.jpackage.internal.Bundlers with - jdk.incubator.jpackage.internal.BasicBundlers; + provides jdk.jpackage.internal.Bundlers with + jdk.jpackage.internal.BasicBundlers; provides java.util.spi.ToolProvider - with jdk.incubator.jpackage.internal.JPackageToolProvider; + with jdk.jpackage.internal.JPackageToolProvider; } diff --git a/src/jdk.incubator.jpackage/share/man/jpackage.1 b/src/jdk.jpackage/share/man/jpackage.1 similarity index 96% rename from src/jdk.incubator.jpackage/share/man/jpackage.1 rename to src/jdk.jpackage/share/man/jpackage.1 index 2311b233853..8fa4a24005b 100644 --- a/src/jdk.incubator.jpackage/share/man/jpackage.1 +++ b/src/jdk.jpackage/share/man/jpackage.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" .\" This code is free software; you can redistribute it and/or modify it @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JPACKAGE" "1" "2019" "JDK 15" "JDK Commands" +.TH "JPACKAGE" "1" "2019" "JDK 16" "JDK Commands" .hy .SH NAME .PP @@ -152,10 +152,14 @@ and is absolute or relative to the current directory. This option can be used multiple times. .RE .TP -.B \f[CB]\-\-bind\-services\f[R] -Pass on \-\-bind\-services option to jlink (which will link in service -provider modules and their dependences). +.B \f[CB]\-\-jlink\-options\f[R] +A space separated list of options to pass to jlink .RS +.PP +If not specified, defaults to "\-\-strip\-native\-commands +\-\-strip\-debug \-\-no\-man\-pages \-\-no\-header\-files" +.PP +This option can be used multiple times. .RE .TP .B \f[CB]\-\-runtime\-image\f[R] diff --git a/src/jdk.incubator.jpackage/share/native/applauncher/AppLauncher.cpp b/src/jdk.jpackage/share/native/applauncher/AppLauncher.cpp similarity index 100% rename from src/jdk.incubator.jpackage/share/native/applauncher/AppLauncher.cpp rename to src/jdk.jpackage/share/native/applauncher/AppLauncher.cpp diff --git a/src/jdk.incubator.jpackage/share/native/applauncher/AppLauncher.h b/src/jdk.jpackage/share/native/applauncher/AppLauncher.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/applauncher/AppLauncher.h rename to src/jdk.jpackage/share/native/applauncher/AppLauncher.h diff --git a/src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.cpp b/src/jdk.jpackage/share/native/applauncher/CfgFile.cpp similarity index 100% rename from src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.cpp rename to src/jdk.jpackage/share/native/applauncher/CfgFile.cpp diff --git a/src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.h b/src/jdk.jpackage/share/native/applauncher/CfgFile.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/applauncher/CfgFile.h rename to src/jdk.jpackage/share/native/applauncher/CfgFile.h diff --git a/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.cpp b/src/jdk.jpackage/share/native/applauncher/JvmLauncher.cpp similarity index 100% rename from src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.cpp rename to src/jdk.jpackage/share/native/applauncher/JvmLauncher.cpp diff --git a/src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h b/src/jdk.jpackage/share/native/applauncher/JvmLauncher.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/applauncher/JvmLauncher.h rename to src/jdk.jpackage/share/native/applauncher/JvmLauncher.h diff --git a/src/jdk.incubator.jpackage/share/native/common/Dll.h b/src/jdk.jpackage/share/native/common/Dll.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/Dll.h rename to src/jdk.jpackage/share/native/common/Dll.h diff --git a/src/jdk.incubator.jpackage/share/native/common/ErrorHandling.cpp b/src/jdk.jpackage/share/native/common/ErrorHandling.cpp similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/ErrorHandling.cpp rename to src/jdk.jpackage/share/native/common/ErrorHandling.cpp diff --git a/src/jdk.incubator.jpackage/share/native/common/ErrorHandling.h b/src/jdk.jpackage/share/native/common/ErrorHandling.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/ErrorHandling.h rename to src/jdk.jpackage/share/native/common/ErrorHandling.h diff --git a/src/jdk.incubator.jpackage/share/native/common/FileUtils.cpp b/src/jdk.jpackage/share/native/common/FileUtils.cpp similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/FileUtils.cpp rename to src/jdk.jpackage/share/native/common/FileUtils.cpp diff --git a/src/jdk.incubator.jpackage/share/native/common/FileUtils.h b/src/jdk.jpackage/share/native/common/FileUtils.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/FileUtils.h rename to src/jdk.jpackage/share/native/common/FileUtils.h diff --git a/src/jdk.incubator.jpackage/share/native/common/Log.cpp b/src/jdk.jpackage/share/native/common/Log.cpp similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/Log.cpp rename to src/jdk.jpackage/share/native/common/Log.cpp diff --git a/src/jdk.incubator.jpackage/share/native/common/Log.h b/src/jdk.jpackage/share/native/common/Log.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/Log.h rename to src/jdk.jpackage/share/native/common/Log.h diff --git a/src/jdk.incubator.jpackage/share/native/common/SourceCodePos.h b/src/jdk.jpackage/share/native/common/SourceCodePos.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/SourceCodePos.h rename to src/jdk.jpackage/share/native/common/SourceCodePos.h diff --git a/src/jdk.incubator.jpackage/share/native/common/SysInfo.h b/src/jdk.jpackage/share/native/common/SysInfo.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/SysInfo.h rename to src/jdk.jpackage/share/native/common/SysInfo.h diff --git a/src/jdk.incubator.jpackage/share/native/common/Toolbox.h b/src/jdk.jpackage/share/native/common/Toolbox.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/Toolbox.h rename to src/jdk.jpackage/share/native/common/Toolbox.h diff --git a/src/jdk.incubator.jpackage/share/native/common/kludge_c++11.h b/src/jdk.jpackage/share/native/common/kludge_c++11.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/kludge_c++11.h rename to src/jdk.jpackage/share/native/common/kludge_c++11.h diff --git a/src/jdk.incubator.jpackage/share/native/common/tstrings.cpp b/src/jdk.jpackage/share/native/common/tstrings.cpp similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/tstrings.cpp rename to src/jdk.jpackage/share/native/common/tstrings.cpp diff --git a/src/jdk.incubator.jpackage/share/native/common/tstrings.h b/src/jdk.jpackage/share/native/common/tstrings.h similarity index 100% rename from src/jdk.incubator.jpackage/share/native/common/tstrings.h rename to src/jdk.jpackage/share/native/common/tstrings.h diff --git a/src/jdk.incubator.jpackage/unix/native/common/PlatformLogEvent.cpp b/src/jdk.jpackage/unix/native/common/PlatformLogEvent.cpp similarity index 100% rename from src/jdk.incubator.jpackage/unix/native/common/PlatformLogEvent.cpp rename to src/jdk.jpackage/unix/native/common/PlatformLogEvent.cpp diff --git a/src/jdk.incubator.jpackage/unix/native/common/PlatformLogEvent.h b/src/jdk.jpackage/unix/native/common/PlatformLogEvent.h similarity index 100% rename from src/jdk.incubator.jpackage/unix/native/common/PlatformLogEvent.h rename to src/jdk.jpackage/unix/native/common/PlatformLogEvent.h diff --git a/src/jdk.incubator.jpackage/unix/native/common/UnixDll.cpp b/src/jdk.jpackage/unix/native/common/UnixDll.cpp similarity index 100% rename from src/jdk.incubator.jpackage/unix/native/common/UnixDll.cpp rename to src/jdk.jpackage/unix/native/common/UnixDll.cpp diff --git a/src/jdk.incubator.jpackage/unix/native/common/UnixFileUtils.cpp b/src/jdk.jpackage/unix/native/common/UnixFileUtils.cpp similarity index 100% rename from src/jdk.incubator.jpackage/unix/native/common/UnixFileUtils.cpp rename to src/jdk.jpackage/unix/native/common/UnixFileUtils.cpp diff --git a/src/jdk.incubator.jpackage/unix/native/common/UnixSysInfo.cpp b/src/jdk.jpackage/unix/native/common/UnixSysInfo.cpp similarity index 100% rename from src/jdk.incubator.jpackage/unix/native/common/UnixSysInfo.cpp rename to src/jdk.jpackage/unix/native/common/UnixSysInfo.cpp diff --git a/src/jdk.incubator.jpackage/unix/native/common/UnixSysInfo.h b/src/jdk.jpackage/unix/native/common/UnixSysInfo.h similarity index 100% rename from src/jdk.incubator.jpackage/unix/native/common/UnixSysInfo.h rename to src/jdk.jpackage/unix/native/common/UnixSysInfo.h diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/ExecutableRebrander.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ExecutableRebrander.java similarity index 92% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/ExecutableRebrander.java rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ExecutableRebrander.java index 53af7209d4d..cec106cdd24 100644 --- a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/ExecutableRebrander.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ExecutableRebrander.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -38,18 +38,18 @@ import java.util.Map; import java.util.Properties; import java.util.ResourceBundle; -import static jdk.incubator.jpackage.internal.OverridableResource.createResource; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.COPYRIGHT; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.DESCRIPTION; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.TEMP_ROOT; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VENDOR; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.OverridableResource.createResource; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.COPYRIGHT; +import static jdk.jpackage.internal.StandardBundlerParam.DESCRIPTION; +import static jdk.jpackage.internal.StandardBundlerParam.TEMP_ROOT; +import static jdk.jpackage.internal.StandardBundlerParam.VENDOR; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; final class ExecutableRebrander { private static final ResourceBundle I18N = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.WinResources"); + "jdk.jpackage.internal.resources.WinResources"); private static final String LAUNCHER_PROPERTIES_TEMPLATE = "WinLauncher.template"; diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/MsiVersion.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/MsiVersion.java similarity index 98% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/MsiVersion.java rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/MsiVersion.java index 6d8bba3aa30..90a56f38066 100644 --- a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/MsiVersion.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/MsiVersion.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.math.BigInteger; diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WinAppBundler.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java similarity index 97% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WinAppBundler.java rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java index 58a9dddceb6..16ae11e1f4a 100644 --- a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WinAppBundler.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinAppBundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; public class WinAppBundler extends AppImageBundler { public WinAppBundler() { diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WinExeBundler.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java similarity index 99% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WinExeBundler.java rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java index b72cf6d1164..96971193957 100644 --- a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WinExeBundler.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.io.InputStream; diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WinMsiBundler.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java similarity index 96% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WinMsiBundler.java rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java index b01455e5acb..8ff2df9998c 100644 --- a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WinMsiBundler.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.io.InputStream; @@ -54,15 +54,15 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; -import static jdk.incubator.jpackage.internal.OverridableResource.createResource; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.DESCRIPTION; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.LICENSE_FILE; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.RESOURCE_DIR; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.TEMP_ROOT; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VENDOR; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.OverridableResource.createResource; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; +import static jdk.jpackage.internal.StandardBundlerParam.DESCRIPTION; +import static jdk.jpackage.internal.StandardBundlerParam.LICENSE_FILE; +import static jdk.jpackage.internal.StandardBundlerParam.RESOURCE_DIR; +import static jdk.jpackage.internal.StandardBundlerParam.TEMP_ROOT; +import static jdk.jpackage.internal.StandardBundlerParam.VENDOR; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; @@ -84,7 +84,7 @@ *
*

* main.wxs file is a copy of main.wxs resource from - * jdk.incubator.jpackage.internal.resources package. It is parametrized with the + * jdk.jpackage.internal.resources package. It is parametrized with the * following WiX variables: *

    *
  • JpAppName. Name of the application. Set to the value of --name command diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WindowsAppImageBuilder.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java similarity index 93% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WindowsAppImageBuilder.java rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java index cb34707d345..79db04d5b5b 100644 --- a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WindowsAppImageBuilder.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsAppImageBuilder.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.io.InputStream; @@ -34,13 +34,13 @@ import java.util.Map; import java.util.ResourceBundle; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.ICON; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.ICON; +import static jdk.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; public class WindowsAppImageBuilder extends AbstractAppImageBuilder { private static final ResourceBundle I18N = ResourceBundle.getBundle( - "jdk.incubator.jpackage.internal.resources.WinResources"); + "jdk.jpackage.internal.resources.WinResources"); private static final String TEMPLATE_APP_ICON ="java48.ico"; diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WindowsDefender.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsDefender.java similarity index 98% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WindowsDefender.java rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsDefender.java index 8cc8ad45d77..9dc0e710b29 100644 --- a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WindowsDefender.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsDefender.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.List; diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WindowsRegistry.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsRegistry.java similarity index 99% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WindowsRegistry.java rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsRegistry.java index f502dc03a2f..a62d9c3b687 100644 --- a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WindowsRegistry.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsRegistry.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.ArrayList; import java.util.List; diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WixPipeline.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixPipeline.java similarity index 99% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WixPipeline.java rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixPipeline.java index 1cc88c63efb..eebfe052505 100644 --- a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WixPipeline.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixPipeline.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Files; diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WixSourcesBuilder.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixSourcesBuilder.java similarity index 98% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WixSourcesBuilder.java rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixSourcesBuilder.java index 2193ef74054..e478cfa9c38 100644 --- a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WixSourcesBuilder.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixSourcesBuilder.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -48,12 +48,12 @@ import java.util.stream.Stream; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import jdk.incubator.jpackage.internal.IOUtils.XmlConsumer; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.APP_NAME; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.INSTALL_DIR; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VENDOR; -import static jdk.incubator.jpackage.internal.StandardBundlerParam.VERSION; -import static jdk.incubator.jpackage.internal.WinMsiBundler.MSI_SYSTEM_WIDE; +import jdk.jpackage.internal.IOUtils.XmlConsumer; +import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import static jdk.jpackage.internal.StandardBundlerParam.INSTALL_DIR; +import static jdk.jpackage.internal.StandardBundlerParam.VENDOR; +import static jdk.jpackage.internal.StandardBundlerParam.VERSION; +import static jdk.jpackage.internal.WinMsiBundler.MSI_SYSTEM_WIDE; /** * Creates application WiX source files. diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WixTool.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixTool.java similarity index 99% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WixTool.java rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixTool.java index cebe3936f8b..47edbd16c99 100644 --- a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/WixTool.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixTool.java @@ -23,7 +23,7 @@ * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.FileSystems; diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/MsiInstallerStrings_en.wxl b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_en.wxl similarity index 100% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/MsiInstallerStrings_en.wxl rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_en.wxl diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/MsiInstallerStrings_ja.wxl b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_ja.wxl similarity index 100% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/MsiInstallerStrings_ja.wxl rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_ja.wxl diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/MsiInstallerStrings_zh_CN.wxl b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_zh_CN.wxl similarity index 100% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/MsiInstallerStrings_zh_CN.wxl rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/MsiInstallerStrings_zh_CN.wxl diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/WinInstaller.template b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinInstaller.template similarity index 100% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/WinInstaller.template rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinInstaller.template diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/WinLauncher.template b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinLauncher.template similarity index 100% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/WinLauncher.template rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinLauncher.template diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/WinResources.properties b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties similarity index 100% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/WinResources.properties rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/WinResources_ja.properties b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties similarity index 100% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/WinResources_ja.properties rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/WinResources_zh_CN.properties b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties similarity index 100% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/WinResources_zh_CN.properties rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/java48.ico b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/java48.ico similarity index 100% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/java48.ico rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/java48.ico diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/main.wxs b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/main.wxs similarity index 100% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/main.wxs rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/main.wxs diff --git a/src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/overrides.wxi b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/overrides.wxi similarity index 100% rename from src/jdk.incubator.jpackage/windows/classes/jdk/incubator/jpackage/internal/resources/overrides.wxi rename to src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/overrides.wxi diff --git a/src/jdk.incubator.jpackage/macosx/classes/module-info.java.extra b/src/jdk.jpackage/windows/classes/module-info.java.extra similarity index 82% rename from src/jdk.incubator.jpackage/macosx/classes/module-info.java.extra rename to src/jdk.jpackage/windows/classes/module-info.java.extra index ea6da5da5a4..d9d3bde1e4d 100644 --- a/src/jdk.incubator.jpackage/macosx/classes/module-info.java.extra +++ b/src/jdk.jpackage/windows/classes/module-info.java.extra @@ -23,9 +23,8 @@ * questions. */ -provides jdk.incubator.jpackage.internal.Bundler with - jdk.incubator.jpackage.internal.MacAppBundler, - jdk.incubator.jpackage.internal.MacAppStoreBundler, - jdk.incubator.jpackage.internal.MacDmgBundler, - jdk.incubator.jpackage.internal.MacPkgBundler; +provides jdk.jpackage.internal.Bundler with + jdk.jpackage.internal.WinAppBundler, + jdk.jpackage.internal.WinExeBundler, + jdk.jpackage.internal.WinMsiBundler; diff --git a/src/jdk.incubator.jpackage/windows/native/applauncher/WinLauncher.cpp b/src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/applauncher/WinLauncher.cpp rename to src/jdk.jpackage/windows/native/applauncher/WinLauncher.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/common/PlatformLogEvent.cpp b/src/jdk.jpackage/windows/native/common/PlatformLogEvent.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/common/PlatformLogEvent.cpp rename to src/jdk.jpackage/windows/native/common/PlatformLogEvent.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/common/PlatformLogEvent.h b/src/jdk.jpackage/windows/native/common/PlatformLogEvent.h similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/common/PlatformLogEvent.h rename to src/jdk.jpackage/windows/native/common/PlatformLogEvent.h diff --git a/src/jdk.incubator.jpackage/windows/native/common/UniqueHandle.h b/src/jdk.jpackage/windows/native/common/UniqueHandle.h similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/common/UniqueHandle.h rename to src/jdk.jpackage/windows/native/common/UniqueHandle.h diff --git a/src/jdk.incubator.jpackage/windows/native/common/WinDll.cpp b/src/jdk.jpackage/windows/native/common/WinDll.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/common/WinDll.cpp rename to src/jdk.jpackage/windows/native/common/WinDll.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/common/WinErrorHandling.cpp b/src/jdk.jpackage/windows/native/common/WinErrorHandling.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/common/WinErrorHandling.cpp rename to src/jdk.jpackage/windows/native/common/WinErrorHandling.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/common/WinErrorHandling.h b/src/jdk.jpackage/windows/native/common/WinErrorHandling.h similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/common/WinErrorHandling.h rename to src/jdk.jpackage/windows/native/common/WinErrorHandling.h diff --git a/src/jdk.incubator.jpackage/windows/native/common/WinFileUtils.cpp b/src/jdk.jpackage/windows/native/common/WinFileUtils.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/common/WinFileUtils.cpp rename to src/jdk.jpackage/windows/native/common/WinFileUtils.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/common/WinFileUtils.h b/src/jdk.jpackage/windows/native/common/WinFileUtils.h similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/common/WinFileUtils.h rename to src/jdk.jpackage/windows/native/common/WinFileUtils.h diff --git a/src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.cpp b/src/jdk.jpackage/windows/native/common/WinSysInfo.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.cpp rename to src/jdk.jpackage/windows/native/common/WinSysInfo.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.h b/src/jdk.jpackage/windows/native/common/WinSysInfo.h similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/common/WinSysInfo.h rename to src/jdk.jpackage/windows/native/common/WinSysInfo.h diff --git a/src/jdk.incubator.jpackage/windows/native/libjpackage/IconSwap.cpp b/src/jdk.jpackage/windows/native/libjpackage/IconSwap.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/libjpackage/IconSwap.cpp rename to src/jdk.jpackage/windows/native/libjpackage/IconSwap.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/libjpackage/IconSwap.h b/src/jdk.jpackage/windows/native/libjpackage/IconSwap.h similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/libjpackage/IconSwap.h rename to src/jdk.jpackage/windows/native/libjpackage/IconSwap.h diff --git a/src/jdk.incubator.jpackage/windows/native/libjpackage/JniUtils.cpp b/src/jdk.jpackage/windows/native/libjpackage/JniUtils.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/libjpackage/JniUtils.cpp rename to src/jdk.jpackage/windows/native/libjpackage/JniUtils.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/libjpackage/JniUtils.h b/src/jdk.jpackage/windows/native/libjpackage/JniUtils.h similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/libjpackage/JniUtils.h rename to src/jdk.jpackage/windows/native/libjpackage/JniUtils.h diff --git a/src/jdk.incubator.jpackage/windows/native/libjpackage/ResourceEditor.cpp b/src/jdk.jpackage/windows/native/libjpackage/ResourceEditor.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/libjpackage/ResourceEditor.cpp rename to src/jdk.jpackage/windows/native/libjpackage/ResourceEditor.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/libjpackage/ResourceEditor.h b/src/jdk.jpackage/windows/native/libjpackage/ResourceEditor.h similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/libjpackage/ResourceEditor.h rename to src/jdk.jpackage/windows/native/libjpackage/ResourceEditor.h diff --git a/src/jdk.incubator.jpackage/windows/native/libjpackage/VersionInfo.cpp b/src/jdk.jpackage/windows/native/libjpackage/VersionInfo.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/libjpackage/VersionInfo.cpp rename to src/jdk.jpackage/windows/native/libjpackage/VersionInfo.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/libjpackage/VersionInfo.h b/src/jdk.jpackage/windows/native/libjpackage/VersionInfo.h similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/libjpackage/VersionInfo.h rename to src/jdk.jpackage/windows/native/libjpackage/VersionInfo.h diff --git a/src/jdk.incubator.jpackage/windows/native/libjpackage/WindowsRegistry.cpp b/src/jdk.jpackage/windows/native/libjpackage/WindowsRegistry.cpp similarity index 84% rename from src/jdk.incubator.jpackage/windows/native/libjpackage/WindowsRegistry.cpp rename to src/jdk.jpackage/windows/native/libjpackage/WindowsRegistry.cpp index 80ba6ce0964..3ecefb1adca 100644 --- a/src/jdk.incubator.jpackage/windows/native/libjpackage/WindowsRegistry.cpp +++ b/src/jdk.jpackage/windows/native/libjpackage/WindowsRegistry.cpp @@ -71,23 +71,23 @@ std::wstring GetLongPath(const std::wstring& path) { #ifdef __cplusplus extern "C" { #endif -#undef jdk_incubator_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE -#define jdk_incubator_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE 1L +#undef jdk_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE +#define jdk_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE 1L /* - * Class: jdk_incubator_jpackage_internal_WindowsRegistry + * Class: jdk_jpackage_internal_WindowsRegistry * Method: readDwordValue * Signature: (ILjava/lang/String;Ljava/lang/String;I)I */ JNIEXPORT jint JNICALL - Java_jdk_incubator_jpackage_internal_WindowsRegistry_readDwordValue( + Java_jdk_jpackage_internal_WindowsRegistry_readDwordValue( JNIEnv *pEnv, jclass c, jint key, jstring jSubKey, jstring jValue, jint defaultValue) { jint jResult = defaultValue; JP_TRY; - if (key != jdk_incubator_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE) { + if (key != jdk_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE) { JP_THROW("Inavlid Windows registry key id"); } @@ -115,17 +115,17 @@ extern "C" { } /* - * Class: jdk_incubator_jpackage_internal_WindowsRegistry + * Class: jdk_jpackage_internal_WindowsRegistry * Method: openRegistryKey * Signature: (ILjava/lang/String;)J */ JNIEXPORT jlong JNICALL - Java_jdk_incubator_jpackage_internal_WindowsRegistry_openRegistryKey( + Java_jdk_jpackage_internal_WindowsRegistry_openRegistryKey( JNIEnv *pEnv, jclass c, jint key, jstring jSubKey) { JP_TRY; - if (key != jdk_incubator_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE) { + if (key != jdk_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE) { JP_THROW("Inavlid Windows registry key id"); } @@ -143,12 +143,12 @@ extern "C" { } /* - * Class: jdk_incubator_jpackage_internal_WindowsRegistry + * Class: jdk_jpackage_internal_WindowsRegistry * Method: enumRegistryValue * Signature: (JI)Ljava/lang/String; */ JNIEXPORT jstring JNICALL - Java_jdk_incubator_jpackage_internal_WindowsRegistry_enumRegistryValue( + Java_jdk_jpackage_internal_WindowsRegistry_enumRegistryValue( JNIEnv *pEnv, jclass c, jlong lKey, jint jIndex) { JP_TRY; @@ -175,24 +175,24 @@ extern "C" { } /* - * Class: jdk_incubator_jpackage_internal_WindowsRegistry + * Class: jdk_jpackage_internal_WindowsRegistry * Method: closeRegistryKey * Signature: (J)V */ JNIEXPORT void JNICALL - Java_jdk_incubator_jpackage_internal_WindowsRegistry_closeRegistryKey( + Java_jdk_jpackage_internal_WindowsRegistry_closeRegistryKey( JNIEnv *pEnc, jclass c, jlong lKey) { HKEY hKey = (HKEY)lKey; RegCloseKey(hKey); } /* - * Class: jdk_incubator_jpackage_internal_WindowsRegistry + * Class: jdk_jpackage_internal_WindowsRegistry * Method: comparePaths * Signature: (Ljava/lang/String;Ljava/lang/String;)Z */ JNIEXPORT jboolean JNICALL - Java_jdk_incubator_jpackage_internal_WindowsRegistry_comparePaths( + Java_jdk_jpackage_internal_WindowsRegistry_comparePaths( JNIEnv *pEnv, jclass c, jstring jPath1, jstring jPath2) { JP_TRY; diff --git a/src/jdk.incubator.jpackage/windows/native/libjpackage/jpackage.cpp b/src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp similarity index 84% rename from src/jdk.incubator.jpackage/windows/native/libjpackage/jpackage.cpp rename to src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp index 4e1a574d963..66e20b18aef 100644 --- a/src/jdk.incubator.jpackage/windows/native/libjpackage/jpackage.cpp +++ b/src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp @@ -34,12 +34,12 @@ extern "C" { #endif /* - * Class: jdk_incubator_jpackage_internal_ExecutableRebrander + * Class: jdk_jpackage_internal_ExecutableRebrander * Method: lockResource * Signature: (Ljava/lang/String;)J */ JNIEXPORT jlong JNICALL - Java_jdk_incubator_jpackage_internal_ExecutableRebrander_lockResource( + Java_jdk_jpackage_internal_ExecutableRebrander_lockResource( JNIEnv *pEnv, jclass c, jstring jExecutable) { JP_TRY; @@ -55,12 +55,12 @@ extern "C" { } /* - * Class: jdk_incubator_jpackage_internal_ExecutableRebrander + * Class: jdk_jpackage_internal_ExecutableRebrander * Method: unlockResource * Signature: (J;)V */ JNIEXPORT void JNICALL - Java_jdk_incubator_jpackage_internal_ExecutableRebrander_unlockResource( + Java_jdk_jpackage_internal_ExecutableRebrander_unlockResource( JNIEnv *pEnv, jclass c, jlong jResourceLock) { JP_TRY; @@ -70,12 +70,12 @@ extern "C" { } /* - * Class: jdk_incubator_jpackage_internal_ExecutableRebrander + * Class: jdk_jpackage_internal_ExecutableRebrander * Method: iconSwap * Signature: (J;Ljava/lang/String;)I */ JNIEXPORT jint JNICALL - Java_jdk_incubator_jpackage_internal_ExecutableRebrander_iconSwap( + Java_jdk_jpackage_internal_ExecutableRebrander_iconSwap( JNIEnv *pEnv, jclass c, jlong jResourceLock, jstring jIconTarget) { JP_TRY; @@ -94,12 +94,12 @@ extern "C" { } /* - * Class: jdk_incubator_jpackage_internal_ExecutableRebrander + * Class: jdk_jpackage_internal_ExecutableRebrander * Method: versionSwap * Signature: (J;[Ljava/lang/String;)I */ JNIEXPORT jint JNICALL - Java_jdk_incubator_jpackage_internal_ExecutableRebrander_versionSwap( + Java_jdk_jpackage_internal_ExecutableRebrander_versionSwap( JNIEnv *pEnv, jclass c, jlong jResourceLock, jobjectArray jExecutableProperties) { @@ -129,11 +129,11 @@ extern "C" { } /* - * Class: jdk_incubator_jpackage_internal_WinExeBundler + * Class: jdk_jpackage_internal_WinExeBundler * Method: embedMSI * Signature: (J;Ljava/lang/String;)I */ - JNIEXPORT jint JNICALL Java_jdk_incubator_jpackage_internal_WinExeBundler_embedMSI( + JNIEXPORT jint JNICALL Java_jdk_jpackage_internal_WinExeBundler_embedMSI( JNIEnv *pEnv, jclass c, jlong jResourceLock, jstring jmsiPath) { JP_TRY; diff --git a/src/jdk.incubator.jpackage/windows/native/libwixhelper/libwixhelper.cpp b/src/jdk.jpackage/windows/native/libwixhelper/libwixhelper.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/libwixhelper/libwixhelper.cpp rename to src/jdk.jpackage/windows/native/libwixhelper/libwixhelper.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/msiwrapper/Executor.cpp b/src/jdk.jpackage/windows/native/msiwrapper/Executor.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/msiwrapper/Executor.cpp rename to src/jdk.jpackage/windows/native/msiwrapper/Executor.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/msiwrapper/Executor.h b/src/jdk.jpackage/windows/native/msiwrapper/Executor.h similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/msiwrapper/Executor.h rename to src/jdk.jpackage/windows/native/msiwrapper/Executor.h diff --git a/src/jdk.incubator.jpackage/windows/native/msiwrapper/MsiWrapper.cpp b/src/jdk.jpackage/windows/native/msiwrapper/MsiWrapper.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/msiwrapper/MsiWrapper.cpp rename to src/jdk.jpackage/windows/native/msiwrapper/MsiWrapper.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/msiwrapper/Resources.cpp b/src/jdk.jpackage/windows/native/msiwrapper/Resources.cpp similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/msiwrapper/Resources.cpp rename to src/jdk.jpackage/windows/native/msiwrapper/Resources.cpp diff --git a/src/jdk.incubator.jpackage/windows/native/msiwrapper/Resources.h b/src/jdk.jpackage/windows/native/msiwrapper/Resources.h similarity index 100% rename from src/jdk.incubator.jpackage/windows/native/msiwrapper/Resources.h rename to src/jdk.jpackage/windows/native/msiwrapper/Resources.h diff --git a/src/jdk.jshell/share/man/jshell.1 b/src/jdk.jshell/share/man/jshell.1 index 5fb056b0e31..01d6a24b30a 100644 --- a/src/jdk.jshell/share/man/jshell.1 +++ b/src/jdk.jshell/share/man/jshell.1 @@ -1,4 +1,3 @@ -.\"t .\" Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. .\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. .\" @@ -8,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -20,9 +19,10 @@ .\" or visit www.oracle.com if you need additional information or have any .\" questions. .\" +.\"t .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JSHELL" "1" "2020" "JDK 15" "JDK Commands" +.TH "JSHELL" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.jstatd/share/man/jstatd.1 b/src/jdk.jstatd/share/man/jstatd.1 index 9e4a849eca7..88d3222c364 100644 --- a/src/jdk.jstatd/share/man/jstatd.1 +++ b/src/jdk.jstatd/share/man/jstatd.1 @@ -7,7 +7,7 @@ .\" .\" This code is distributed in the hope that it will be useful, but WITHOUT .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License .\" version 2 for more details (a copy is included in the LICENSE file that .\" accompanied this code). .\" @@ -21,7 +21,7 @@ .\" .\" Automatically generated by Pandoc 2.3.1 .\" -.TH "JSTATD" "1" "2020" "JDK 15" "JDK Commands" +.TH "JSTATD" "1" "2020" "JDK 16" "JDK Commands" .hy .SH NAME .PP diff --git a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java index d924e27dfed..107586fe2d5 100644 --- a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java +++ b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java @@ -636,7 +636,6 @@ public void freeMemory(long address) { * @see #getInt(Object, long) */ @ForceInline - @SuppressWarnings("preview") public long objectFieldOffset(Field f) { if (f == null) { throw new NullPointerException(); @@ -649,7 +648,7 @@ public long objectFieldOffset(Field f) { throw new UnsupportedOperationException("can't get field offset on an inline class: " + f); } if (declaringClass.isRecord()) { - throw new UnsupportedOperationException("can't get field offset on a record (preview): " + f); + throw new UnsupportedOperationException("can't get field offset on a record class: " + f); } return theInternalUnsafe.objectFieldOffset(f); } @@ -672,7 +671,6 @@ public long objectFieldOffset(Field f) { * @see #getInt(Object, long) */ @ForceInline - @SuppressWarnings("preview") public long staticFieldOffset(Field f) { if (f == null) { throw new NullPointerException(); @@ -685,7 +683,7 @@ public long staticFieldOffset(Field f) { throw new UnsupportedOperationException("can't get static field offset on an inline class: " + f); } if (declaringClass.isRecord()) { - throw new UnsupportedOperationException("can't get field offset on a record (preview): " + f); + throw new UnsupportedOperationException("can't get field offset on a record class: " + f); } return theInternalUnsafe.staticFieldOffset(f); } @@ -701,7 +699,6 @@ public long staticFieldOffset(Field f) { * this class. */ @ForceInline - @SuppressWarnings("preview") public Object staticFieldBase(Field f) { if (f == null) { throw new NullPointerException(); @@ -714,7 +711,7 @@ public Object staticFieldBase(Field f) { throw new UnsupportedOperationException("can't get base address on an inline class: " + f); } if (declaringClass.isRecord()) { - throw new UnsupportedOperationException("can't get base address on a record (preview): " + f); + throw new UnsupportedOperationException("can't get base address on a record class: " + f); } return theInternalUnsafe.staticFieldBase(f); } diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java index 59fcd62d172..273fff49eee 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java @@ -2907,11 +2907,16 @@ private int writeEXT(OutputStream os) throws IOException { // read NTFS, UNIX and ZIP64 data from cen.extra private void readExtra(ZipFileSystem zipfs) throws IOException { + // Note that Section 4.5, Extensible data fields, of the PKWARE ZIP File + // Format Specification does not mandate a specific order for the + // data in the extra field, therefore Zip FS cannot assume the data + // is written in the same order by Zip libraries as Zip FS. if (extra == null) return; int elen = extra.length; int off = 0; int newOff = 0; + boolean hasZip64LocOffset = false; while (off + 4 < elen) { // extra spec: HeaderID+DataSize+Data int pos = off; @@ -2955,7 +2960,7 @@ private void readExtra(ZipFileSystem zipfs) throws IOException { ctime = winToJavaTime(LL(extra, pos + 20)); break; case EXTID_EXTT: - // spec says the Extened timestamp in cen only has mtime + // spec says the Extended timestamp in cen only has mtime // need to read the loc to get the extra a/ctime, if flag // "zipinfo-time" is not specified to false; // there is performance cost (move up to loc and read) to @@ -2965,44 +2970,15 @@ private void readExtra(ZipFileSystem zipfs) throws IOException { mtime = unixToJavaTime(LG(extra, pos + 1)); break; } - byte[] buf = new byte[LOCHDR]; - if (zipfs.readFullyAt(buf, 0, buf.length , locoff) - != buf.length) - throw new ZipException("loc: reading failed"); - if (!locSigAt(buf, 0)) - throw new ZipException("loc: wrong sig ->" - + Long.toString(getSig(buf, 0), 16)); - int locElen = LOCEXT(buf); - if (locElen < 9) // EXTT is at least 9 bytes - break; - int locNlen = LOCNAM(buf); - buf = new byte[locElen]; - if (zipfs.readFullyAt(buf, 0, buf.length , locoff + LOCHDR + locNlen) - != buf.length) - throw new ZipException("loc extra: reading failed"); - int locPos = 0; - while (locPos + 4 < buf.length) { - int locTag = SH(buf, locPos); - int locSZ = SH(buf, locPos + 2); - locPos += 4; - if (locTag != EXTID_EXTT) { - locPos += locSZ; - continue; - } - int end = locPos + locSZ - 4; - int flag = CH(buf, locPos++); - if ((flag & 0x1) != 0 && locPos <= end) { - mtime = unixToJavaTime(LG(buf, locPos)); - locPos += 4; - } - if ((flag & 0x2) != 0 && locPos <= end) { - atime = unixToJavaTime(LG(buf, locPos)); - locPos += 4; - } - if ((flag & 0x4) != 0 && locPos <= end) { - ctime = unixToJavaTime(LG(buf, locPos)); - } - break; + // If the LOC offset is 0xFFFFFFFF, then we need to read the + // LOC offset from the EXTID_ZIP64 extra data. Therefore + // wait until all of the CEN extra data fields have been processed + // prior to reading the LOC extra data field in order to obtain + // the Info-ZIP Extended Timestamp. + if (locoff != ZIP64_MINVAL) { + readLocEXTT(zipfs); + } else { + hasZip64LocOffset = true; } break; default: // unknown tag @@ -3011,12 +2987,66 @@ private void readExtra(ZipFileSystem zipfs) throws IOException { } off += (sz + 4); } + + // We need to read the LOC extra data and the LOC offset was obtained + // from the EXTID_ZIP64 field. + if (hasZip64LocOffset) { + readLocEXTT(zipfs); + } + if (newOff != 0 && newOff != extra.length) extra = Arrays.copyOf(extra, newOff); else extra = null; } + /** + * Read the LOC extra field to obtain the Info-ZIP Extended Timestamp fields + * @param zipfs The Zip FS to use + * @throws IOException If an error occurs + */ + private void readLocEXTT(ZipFileSystem zipfs) throws IOException { + byte[] buf = new byte[LOCHDR]; + if (zipfs.readFullyAt(buf, 0, buf.length , locoff) + != buf.length) + throw new ZipException("loc: reading failed"); + if (!locSigAt(buf, 0)) + throw new ZipException("R" + + Long.toString(getSig(buf, 0), 16)); + int locElen = LOCEXT(buf); + if (locElen < 9) // EXTT is at least 9 bytes + return; + int locNlen = LOCNAM(buf); + buf = new byte[locElen]; + if (zipfs.readFullyAt(buf, 0, buf.length , locoff + LOCHDR + locNlen) + != buf.length) + throw new ZipException("loc extra: reading failed"); + int locPos = 0; + while (locPos + 4 < buf.length) { + int locTag = SH(buf, locPos); + int locSZ = SH(buf, locPos + 2); + locPos += 4; + if (locTag != EXTID_EXTT) { + locPos += locSZ; + continue; + } + int end = locPos + locSZ - 4; + int flag = CH(buf, locPos++); + if ((flag & 0x1) != 0 && locPos <= end) { + mtime = unixToJavaTime(LG(buf, locPos)); + locPos += 4; + } + if ((flag & 0x2) != 0 && locPos <= end) { + atime = unixToJavaTime(LG(buf, locPos)); + locPos += 4; + } + if ((flag & 0x4) != 0 && locPos <= end) { + ctime = unixToJavaTime(LG(buf, locPos)); + } + break; + } + } + @Override public String toString() { StringBuilder sb = new StringBuilder(1024); diff --git a/test/hotspot/gtest/gc/g1/test_g1ServiceThread.cpp b/test/hotspot/gtest/gc/g1/test_g1ServiceThread.cpp new file mode 100644 index 00000000000..5fe28daee4d --- /dev/null +++ b/test/hotspot/gtest/gc/g1/test_g1ServiceThread.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc/g1/g1ServiceThread.hpp" +#include "runtime/interfaceSupport.inline.hpp" +#include "runtime/os.hpp" +#include "utilities/autoRestore.hpp" +#include "unittest.hpp" + +class CheckTask : public G1ServiceTask { + int _execution_count; + bool _reschedule; + +public: + CheckTask(const char* name) : + G1ServiceTask(name), + _execution_count(0), + _reschedule(true) { } + virtual void execute() { + _execution_count++; + if (_reschedule) { + schedule(100); + } + } + + int execution_count() { return _execution_count;} + void set_reschedule(bool reschedule) { _reschedule = reschedule; } +}; + +static void stop_service_thread(G1ServiceThread* thread) { + ThreadInVMfromNative tvn(JavaThread::current()); + thread->stop(); +} + +// Test that a task that is added during runtime gets run. +TEST_VM(G1ServiceThread, test_add) { + // Create thread and let it start. + G1ServiceThread* st = new G1ServiceThread(); + os::naked_short_sleep(500); + + CheckTask ct("AddAndRun"); + st->register_task(&ct); + + // Give CheckTask time to run. + os::naked_short_sleep(500); + stop_service_thread(st); + + ASSERT_GT(ct.execution_count(), 0); +} + +// Test that a task that is added while the service thread is +// waiting gets run in a timely manner. +TEST_VM(G1ServiceThread, test_add_while_waiting) { + // Make sure default tasks use long intervals so that the service thread + // is doing a long wait for the next execution. + AutoModifyRestore f1(G1PeriodicGCInterval, 100000); + AutoModifyRestore f2(G1ConcRefinementServiceIntervalMillis, 100000); + + // Create thread and let it start. + G1ServiceThread* st = new G1ServiceThread(); + os::naked_short_sleep(500); + + // Register a new task that should run right away. + CheckTask ct("AddWhileWaiting"); + st->register_task(&ct); + + // Give CheckTask time to run. + os::naked_short_sleep(500); + stop_service_thread(st); + + ASSERT_GT(ct.execution_count(), 0); +} + +// Test that a task with negative timeout is not rescheduled. +TEST_VM(G1ServiceThread, test_add_run_once) { + // Create thread and let it start. + G1ServiceThread* st = new G1ServiceThread(); + os::naked_short_sleep(500); + + // Set reschedule to false to only run once. + CheckTask ct("AddRunOnce"); + ct.set_reschedule(false); + st->register_task(&ct); + + // Give CheckTask time to run. + os::naked_short_sleep(500); + stop_service_thread(st); + + // Should be exactly 1 since negative timeout should + // prevent rescheduling. + ASSERT_EQ(ct.execution_count(), 1); +} + +class TestTask : public G1ServiceTask { + jlong _delay_ms; +public: + TestTask(jlong delay) : + G1ServiceTask("TestTask"), + _delay_ms(delay) { + set_time(delay); + } + virtual void execute() {} + void update_time(jlong now, int multiplier) { + set_time(now + (_delay_ms * multiplier)); + } +}; + +TEST_VM(G1ServiceTaskQueue, add_ordered) { + G1ServiceTaskQueue queue; + + int num_test_tasks = 5; + for (int i = 1; i <= num_test_tasks; i++) { + // Create tasks with different timeout. + TestTask* task = new TestTask(100 * i); + queue.add_ordered(task); + } + + // Now fake a run-loop, that reschedules the tasks using a + // random multiplier. + for (jlong now = 0; now < 1000000; now++) { + // Random multiplier is at least 1 to ensure progress. + int multiplier = 1 + os::random() % 10; + while (queue.peek()->time() < now) { + TestTask* task = (TestTask*) queue.pop(); + // Update delay multiplier. + task->execute(); + task->update_time(now, multiplier); + // All additions will verify that the queue is sorted. + queue.add_ordered(task); + } + } + + while (!queue.is_empty()) { + G1ServiceTask* task = queue.pop(); + delete task; + } +} + +#ifdef ASSERT +TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, pop_empty, + "Should never try to verify empty queue") { + G1ServiceTaskQueue queue; + queue.pop(); +} + +TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, peek_empty, + "Should never try to verify empty queue") { + G1ServiceTaskQueue queue; + queue.peek(); +} + +TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, set_time_in_queue, + "Not allowed to update time while in queue") { + G1ServiceTaskQueue queue; + TestTask a(100); + queue.add_ordered(&a); + // Not allowed to update time while in queue. + a.update_time(500, 1); +} + +#endif diff --git a/test/hotspot/gtest/runtime/test_stackoverflow.cpp b/test/hotspot/gtest/runtime/test_stackoverflow.cpp new file mode 100644 index 00000000000..52a7611e839 --- /dev/null +++ b/test/hotspot/gtest/runtime/test_stackoverflow.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "runtime/os.hpp" +#include "runtime/globals.hpp" +#include "runtime/stackOverflow.hpp" +#include "utilities/align.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/ostream.hpp" +#include "unittest.hpp" + + +TEST_VM(StackOverflow, basics) { + StackOverflow so; + + // Make up a stack range. No need to allocate anything. Size has to be large enough + // to fit sum of all zones into them. + address base = (address) 0x40000000; + const size_t size = os::vm_page_size() * 100; + address end = base - size; + so.initialize(base, end); + + // Walking down the "stack" check for consistency of the three "in_stack_xxx" functions + enum { normal_stack, reserved_or_yellow_zone, red_zone } where = normal_stack; + for (address p = base - 1; p >= end; p -= os::vm_page_size()) { + // tty->print_cr(PTR_FORMAT " %d %d %d", p2i(p), + // (int)so.in_stack_reserved_zone(p), + // (int)so.in_stack_yellow_reserved_zone(p), + // (int)so.in_stack_red_zone(p)); + switch (where) { + case normal_stack: + ASSERT_FALSE(so.in_stack_red_zone(p)); + if (so.in_stack_yellow_reserved_zone(p)) { + if (StackReservedPages > 0) { + ASSERT_TRUE(so.in_stack_reserved_zone(p)); + } else { + ASSERT_FALSE(so.in_stack_reserved_zone(p)); + } + where = reserved_or_yellow_zone; + } else { + ASSERT_FALSE(so.in_stack_reserved_zone((p))); + } + break; + case reserved_or_yellow_zone: + if (so.in_stack_red_zone(p)) { + ASSERT_FALSE(so.in_stack_yellow_reserved_zone(p)); + where = red_zone; + } else { + ASSERT_TRUE(so.in_stack_yellow_reserved_zone(p)); + } + break; + case red_zone: + ASSERT_TRUE(so.in_stack_red_zone(p)); + ASSERT_FALSE(so.in_stack_yellow_reserved_zone(p)); + ASSERT_FALSE(so.in_stack_reserved_zone((p))); + break; + } + } + ASSERT_EQ(where, red_zone); + + // Check bases. + ASSERT_FALSE(so.in_stack_red_zone(so.stack_red_zone_base())); + ASSERT_TRUE(so.in_stack_red_zone(so.stack_red_zone_base() - 1)); + ASSERT_TRUE(so.in_stack_yellow_reserved_zone(so.stack_red_zone_base())); + ASSERT_FALSE(so.in_stack_reserved_zone(so.stack_reserved_zone_base())); + if (so.stack_reserved_zone_size() > 0) { + ASSERT_TRUE(so.in_stack_reserved_zone(so.stack_reserved_zone_base() - 1)); + } +} diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index 2b46a846915..dcdddd62658 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -217,7 +217,6 @@ tier1_gc_2 = \ -gc/g1/ \ -gc/logging/TestUnifiedLoggingSwitchStress.java \ -gc/stress \ - -gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java \ -gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java \ -gc/shenandoah \ -gc/nvdimm @@ -345,6 +344,7 @@ hotspot_appcds_dynamic = \ -runtime/cds/appcds/dynamicArchive \ -runtime/cds/appcds/loaderConstraints/DynamicLoaderConstraintsTest.java \ -runtime/cds/appcds/javaldr/ArrayTest.java \ + -runtime/cds/appcds/javaldr/ExceptionDuringDumpAtObjectsInitPhase.java \ -runtime/cds/appcds/javaldr/GCSharedStringsDuringDump.java \ -runtime/cds/appcds/javaldr/HumongousDuringDump.java \ -runtime/cds/appcds/javaldr/LockDuringDump.java \ diff --git a/test/hotspot/jtreg/compiler/jvmci/compilerToVM/IsCompilableTest.java b/test/hotspot/jtreg/compiler/jvmci/compilerToVM/IsCompilableTest.java index 7b6727515e2..e9d38bddde0 100644 --- a/test/hotspot/jtreg/compiler/jvmci/compilerToVM/IsCompilableTest.java +++ b/test/hotspot/jtreg/compiler/jvmci/compilerToVM/IsCompilableTest.java @@ -27,6 +27,7 @@ * @requires vm.jvmci & vm.compMode == "Xmixed" * @library /test/lib / * @library ../common/patches + * @modules jdk.internal.vm.compiler * @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.org.objectweb.asm * java.base/jdk.internal.org.objectweb.asm.tree @@ -41,6 +42,23 @@ * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler * compiler.jvmci.compilerToVM.IsCompilableTest + */ + +/** + * @test + * @requires vm.jvmci & vm.compMode == "Xmixed" + * @library /test/lib / + * @library ../common/patches + * @modules java.base/jdk.internal.misc + * @modules java.base/jdk.internal.org.objectweb.asm + * java.base/jdk.internal.org.objectweb.asm.tree + * jdk.internal.vm.ci/jdk.vm.ci.hotspot + * jdk.internal.vm.ci/jdk.vm.ci.code + * jdk.internal.vm.ci/jdk.vm.ci.meta + * jdk.internal.vm.ci/jdk.vm.ci.runtime + * + * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler diff --git a/test/hotspot/jtreg/compiler/unsafe/TestUnsafeStaticFieldAccess.java b/test/hotspot/jtreg/compiler/unsafe/TestUnsafeStaticFieldAccess.java new file mode 100644 index 00000000000..ef31ebd8eb0 --- /dev/null +++ b/test/hotspot/jtreg/compiler/unsafe/TestUnsafeStaticFieldAccess.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8255466 + * @summary unsafe access to static field causes crash + * @modules java.base/jdk.internal.misc + * + * @run main/othervm -Xcomp -XX:CompileCommand=compileonly,TestUnsafeStaticFieldAccess::* TestUnsafeStaticFieldAccess + * + */ + +import jdk.internal.misc.Unsafe; +import java.lang.reflect.Field; + +public class TestUnsafeStaticFieldAccess { + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); + private static final long offset; + private static volatile Class clazz; + + private static int field; + + static { + long o = 0; + for (Field f : TestUnsafeStaticFieldAccess.class.getDeclaredFields()) { + if (f.getName().equals("field")) { + o = UNSAFE.staticFieldOffset(f); + break; + } + } + offset = o; + clazz = TestUnsafeStaticFieldAccess.class; + } + + + public static void main(String[] args) { + for (int i = 0; i < 12000; i++) { + UNSAFE.getInt(clazz, offset); + } + } +} diff --git a/test/hotspot/jtreg/gc/TestReferenceRefersTo.java b/test/hotspot/jtreg/gc/TestReferenceRefersTo.java new file mode 100644 index 00000000000..09d4fec3d14 --- /dev/null +++ b/test/hotspot/jtreg/gc/TestReferenceRefersTo.java @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package gc; + +/* @test + * @requires vm.gc != "Epsilon" + * @library /test/lib + * @build sun.hotspot.WhiteBox + * @modules java.base + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm + * -Xbootclasspath/a:. + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * gc.TestReferenceRefersTo + */ + +import java.lang.ref.PhantomReference; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import sun.hotspot.WhiteBox; + +public class TestReferenceRefersTo { + private static final WhiteBox WB = WhiteBox.getWhiteBox(); + + private static final class TestObject { + public final int value; + + public TestObject(int value) { + this.value = value; + } + } + + private static volatile TestObject testObjectNone = null; + private static volatile TestObject testObject1 = null; + private static volatile TestObject testObject2 = null; + private static volatile TestObject testObject3 = null; + private static volatile TestObject testObject4 = null; + + private static ReferenceQueue queue = null; + + private static PhantomReference testPhantom1 = null; + + private static WeakReference testWeak2 = null; + private static WeakReference testWeak3 = null; + private static WeakReference testWeak4 = null; + + private static void setup() { + testObjectNone = new TestObject(0); + testObject1 = new TestObject(1); + testObject2 = new TestObject(2); + testObject3 = new TestObject(3); + testObject4 = new TestObject(4); + + queue = new ReferenceQueue(); + + testPhantom1 = new PhantomReference(testObject1, queue); + + testWeak2 = new WeakReference(testObject2, queue); + testWeak3 = new WeakReference(testObject3, queue); + testWeak4 = new WeakReference(testObject4, queue); + } + + private static void gcUntilOld(Object o) throws Exception { + if (!WB.isObjectInOldGen(o)) { + WB.fullGC(); + if (!WB.isObjectInOldGen(o)) { + fail("object not promoted by full gc"); + } + } + } + + private static void gcUntilOld() throws Exception { + gcUntilOld(testObjectNone); + gcUntilOld(testObject1); + gcUntilOld(testObject2); + gcUntilOld(testObject3); + gcUntilOld(testObject4); + + gcUntilOld(testPhantom1); + + gcUntilOld(testWeak2); + gcUntilOld(testWeak3); + gcUntilOld(testWeak4); + } + + private static void progress(String msg) { + System.out.println(msg); + } + + private static void fail(String msg) throws Exception { + throw new RuntimeException(msg); + } + + private static void expectCleared(Reference ref, + String which) throws Exception { + expectNotValue(ref, testObjectNone, which); + if (!ref.refersTo(null)) { + fail("expected " + which + " to be cleared"); + } + } + + private static void expectNotCleared(Reference ref, + String which) throws Exception { + expectNotValue(ref, testObjectNone, which); + if (ref.refersTo(null)) { + fail("expected " + which + " to not be cleared"); + } + } + + private static void expectValue(Reference ref, + TestObject value, + String which) throws Exception { + expectNotValue(ref, testObjectNone, which); + expectNotCleared(ref, which); + if (!ref.refersTo(value)) { + fail(which + " doesn't refer to expected value"); + } + } + + private static void expectNotValue(Reference ref, + TestObject value, + String which) throws Exception { + if (ref.refersTo(value)) { + fail(which + " refers to unexpected value"); + } + } + + private static void checkInitialStates() throws Exception { + expectValue(testPhantom1, testObject1, "testPhantom1"); + expectValue(testWeak2, testObject2, "testWeak2"); + expectValue(testWeak3, testObject3, "testWeak3"); + expectValue(testWeak4, testObject4, "testWeak4"); + } + + private static void discardStrongReferences() { + // testObjectNone not dropped + testObject1 = null; + testObject2 = null; + // testObject3 not dropped + testObject4 = null; + } + + private static void testConcurrentCollection() throws Exception { + progress("setup concurrent collection test"); + setup(); + progress("gcUntilOld"); + gcUntilOld(); + + progress("acquire control of concurrent cycles"); + WB.concurrentGCAcquireControl(); + try { + progress("check initial states"); + checkInitialStates(); + + progress("discard strong references"); + discardStrongReferences(); + + progress("run GC to before marking completed"); + WB.concurrentGCRunTo(WB.BEFORE_MARKING_COMPLETED); + + progress("fetch test objects, possibly keeping some alive"); + expectNotCleared(testPhantom1, "testPhantom1"); + expectNotCleared(testWeak2, "testWeak2"); + expectValue(testWeak3, testObject3, "testWeak3"); + + // For some collectors, calling get() will keep testObject4 alive. + if (testWeak4.get() == null) { + fail("testWeak4 unexpectedly == null"); + } + + progress("finish collection"); + WB.concurrentGCRunToIdle(); + + progress("verify expected clears"); + expectCleared(testPhantom1, "testPhantom1"); + expectCleared(testWeak2, "testWeak2"); + expectValue(testWeak3, testObject3, "testWeak3"); + // This is true for all currently supported concurrent collectors. + expectNotCleared(testWeak4, "testWeak4"); + + progress("verify get returns expected values"); + if (testWeak2.get() != null) { + fail("testWeak2.get() != null"); + } + + TestObject obj3 = testWeak3.get(); + if (obj3 == null) { + fail("testWeak3.get() returned null"); + } else if (obj3.value != 3) { + fail("testWeak3.get().value is " + obj3.value); + } + + TestObject obj4 = testWeak4.get(); + if (obj4 == null) { + fail("testWeak4.get() returned null"); + } else if (obj4.value != 4) { + fail("testWeak4.get().value is " + obj4.value); + } + + progress("verify queue entries"); + long timeout = 60000; // 1 minute of milliseconds. + while (true) { + Reference ref = queue.remove(timeout); + if (ref == null) { + break; + } else if (ref == testPhantom1) { + testPhantom1 = null; + } else if (ref == testWeak2) { + testWeak2 = null; + } else if (ref == testWeak3) { + testWeak3 = null; + } else if (ref == testWeak4) { + testWeak4 = null; + } else { + fail("unexpected reference in queue"); + } + } + if (testPhantom1 != null) { + fail("testPhantom1 not notified"); + } else if (testWeak2 != null) { + fail("testWeak2 not notified"); + } else if (testWeak3 == null) { + fail("testWeak3 notified"); + } else if (testWeak4 == null) { + if (obj4 != null) { + fail("testWeak4 notified"); + } + } + + } finally { + progress("release control of concurrent cycles"); + WB.concurrentGCReleaseControl(); + } + progress("finished concurrent collection test"); + } + + private static void testSimpleCollection() throws Exception { + progress("setup simple collection test"); + setup(); + progress("gcUntilOld"); + gcUntilOld(); + + progress("check initial states"); + checkInitialStates(); + + progress("discard strong references"); + TestObject tw4 = testWeak4.get(); // Keep testObject4 alive. + discardStrongReferences(); + + progress("collect garbage"); + WB.fullGC(); + + progress("verify expected clears"); + expectCleared(testPhantom1, "testPhantom1"); + expectCleared(testWeak2, "testWeak2"); + expectValue(testWeak3, testObject3, "testWeak3"); + expectNotCleared(testWeak4, "testWeak4"); + + progress("verify get returns expected values"); + if (testWeak2.get() != null) { + fail("testWeak2.get() != null"); + } else if (testWeak3.get() != testObject3) { + fail("testWeak3.get() is not expected value"); + } else if (testWeak4.get() != tw4) { + fail("testWeak4.get() is not expected value"); + } + + progress("finished simple collection test"); + } + + public static void main(String[] args) throws Exception { + if (WB.supportsConcurrentGCBreakpoints()) { + testConcurrentCollection(); + } + testSimpleCollection(); + } +} diff --git a/test/hotspot/jtreg/gc/TestSoftReferencesBehaviorOnOOME.java b/test/hotspot/jtreg/gc/TestSoftReferencesBehaviorOnOOME.java index 12c246ca44d..7f8442ccf0a 100644 --- a/test/hotspot/jtreg/gc/TestSoftReferencesBehaviorOnOOME.java +++ b/test/hotspot/jtreg/gc/TestSoftReferencesBehaviorOnOOME.java @@ -28,6 +28,7 @@ * @key randomness * @summary Tests that all SoftReferences has been cleared at time of OOM. * @requires vm.gc != "Z" + * @requires vm.gc != "Shenandoah" * @library /test/lib * @modules java.base/jdk.internal.misc * @run main/othervm -Xmx128m gc.TestSoftReferencesBehaviorOnOOME 512 2k diff --git a/test/hotspot/jtreg/gc/arguments/TestSurvivorAlignmentInBytesOption.java b/test/hotspot/jtreg/gc/arguments/TestSurvivorAlignmentInBytesOption.java deleted file mode 100644 index 6a515c7b10c..00000000000 --- a/test/hotspot/jtreg/gc/arguments/TestSurvivorAlignmentInBytesOption.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package gc.arguments; - -import jdk.test.lib.Platform; -import jdk.test.lib.process.ExitCode; -import jdk.test.lib.cli.CommandLineOptionTest; - -/** - * @test - * @bug 8031323 - * @summary Verify SurvivorAlignmentInBytes option processing. - * @library /test/lib - * @requires vm.opt.SurvivorAlignmentInBytes == null - * & vm.opt.ObjectAlignmentInBytes == null - * & vm.opt.UnlockExperimentalVMOptions == null - * & (vm.opt.IgnoreUnrecognizedVMOptions == null - * | vm.opt.IgnoreUnrecognizedVMOptions == "false") - * @modules java.base/jdk.internal.misc - * java.management - * @run driver gc.arguments.TestSurvivorAlignmentInBytesOption - */ -public class TestSurvivorAlignmentInBytesOption { - public static void main(String args[]) throws Throwable { - String optionName = "SurvivorAlignmentInBytes"; - String unlockExperimentalVMOpts = "UnlockExperimentalVMOptions"; - String optionIsExperimental - = CommandLineOptionTest.getExperimentalOptionErrorMessage( - optionName); - String valueIsTooSmall= ".*SurvivorAlignmentInBytes.*must be greater" - + " than or equal to ObjectAlignmentInBytes.*"; - String mustBePowerOf2 = ".*SurvivorAlignmentInBytes.*must be " - + "power of 2.*"; - - // Verify that without -XX:+UnlockExperimentalVMOptions usage of - // SurvivorAlignmentInBytes option will cause JVM startup failure - // with the warning message saying that that option is experimental. - String shouldFailMessage = String.format("JVM option '%s' is " - + "experimental.%nJVM startup should fail without " - + "-XX:+UnlockExperimentalVMOptions option", optionName); - CommandLineOptionTest.verifyJVMStartup( - new String[]{optionIsExperimental}, null, - shouldFailMessage, shouldFailMessage, - ExitCode.FAIL, false, - "-XX:-UnlockExperimentalVMOptions", - CommandLineOptionTest.prepareBooleanFlag( - unlockExperimentalVMOpts, false), - CommandLineOptionTest.prepareNumericFlag(optionName, 64)); - - // Verify that with -XX:+UnlockExperimentalVMOptions passed to JVM - // usage of SurvivorAlignmentInBytes option won't cause JVM startup - // failure. - String shouldPassMessage = String.format("JVM option '%s' is " - + "experimental.%nJVM startup should pass with " - + "-XX:+UnlockExperimentalVMOptions option", optionName); - String noWarningMessage = "There should be no warnings when use " - + "with -XX:+UnlockExperimentalVMOptions option"; - CommandLineOptionTest.verifyJVMStartup( - null, new String[]{optionIsExperimental}, - shouldPassMessage, noWarningMessage, - ExitCode.OK, false, - CommandLineOptionTest.prepareBooleanFlag( - unlockExperimentalVMOpts, true), - CommandLineOptionTest.prepareNumericFlag(optionName, 64)); - - // Verify that if specified SurvivorAlignmentInBytes is lower than - // ObjectAlignmentInBytes, then the JVM startup will fail with - // appropriate error message. - if (Platform.is64bit()) { - shouldFailMessage = String.format("JVM startup should fail with " - + "'%s' option value lower than ObjectAlignmentInBytes", optionName); - CommandLineOptionTest.verifyJVMStartup( - new String[]{valueIsTooSmall}, null, - shouldFailMessage, shouldFailMessage, - ExitCode.FAIL, false, - CommandLineOptionTest.prepareBooleanFlag( - unlockExperimentalVMOpts, true), - CommandLineOptionTest.prepareNumericFlag(optionName, 8), - CommandLineOptionTest.prepareNumericFlag("ObjectAlignmentInBytes", 16)); - } - - // Verify that if specified SurvivorAlignmentInBytes value is not - // a power of 2 then the JVM startup will fail with appropriate error - // message. - shouldFailMessage = String.format("JVM startup should fail with " - + "'%s' option value is not a power of 2", optionName); - CommandLineOptionTest.verifyJVMStartup( - new String[]{mustBePowerOf2}, null, - shouldFailMessage, shouldFailMessage, - ExitCode.FAIL, false, - CommandLineOptionTest.prepareBooleanFlag( - unlockExperimentalVMOpts, true), - CommandLineOptionTest.prepareNumericFlag(optionName, 127)); - - // Verify that if SurvivorAlignmentInBytes has correct value, then - // the JVM will be started without errors. - shouldPassMessage = String.format("JVM startup should pass with " - + "correct '%s' option value", optionName); - noWarningMessage = String.format("There should be no warnings when use " - + "correct '%s' option value", optionName); - CommandLineOptionTest.verifyJVMStartup( - null, new String[]{".*SurvivorAlignmentInBytes.*"}, - shouldPassMessage, noWarningMessage, - ExitCode.OK, false, - CommandLineOptionTest.prepareBooleanFlag( - unlockExperimentalVMOpts, true), - CommandLineOptionTest.prepareNumericFlag(optionName, 128)); - - // Verify that we can setup different SurvivorAlignmentInBytes values. - for (int alignment = 32; alignment <= 128; alignment *= 2) { - shouldPassMessage = String.format("JVM startup should pass with " - + "'%s' = %d", optionName, alignment); - CommandLineOptionTest.verifyOptionValue(optionName, - Integer.toString(alignment), shouldPassMessage, - CommandLineOptionTest.prepareBooleanFlag( - unlockExperimentalVMOpts, true), - CommandLineOptionTest.prepareNumericFlag( - optionName, alignment)); - } - } -} diff --git a/test/hotspot/jtreg/gc/shenandoah/compiler/TestBarrierExpansionDeadMemPhi.java b/test/hotspot/jtreg/gc/shenandoah/compiler/TestBarrierExpansionDeadMemPhi.java new file mode 100644 index 00000000000..80d73392a7b --- /dev/null +++ b/test/hotspot/jtreg/gc/shenandoah/compiler/TestBarrierExpansionDeadMemPhi.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8255400 + * @summary C2 failures after JDK-8255000 + * @requires vm.gc.Shenandoah + * @modules java.base/jdk.internal.misc:+open + * + * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:-TieredCompilation -XX:+UseShenandoahGC TestBarrierExpansionDeadMemPhi + * + * + */ + +import jdk.internal.misc.Unsafe; +import java.util.Arrays; +import java.lang.reflect.Field; + +public class TestBarrierExpansionDeadMemPhi { + + static final jdk.internal.misc.Unsafe UNSAFE = Unsafe.getUnsafe(); + + static final long F_OFFSET; + + static class A { + int f; + } + + static { + try { + Field fField = A.class.getDeclaredField("f"); + F_OFFSET = UNSAFE.objectFieldOffset(fField); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + static int test(Object[] array) { + int f = 0; + for (int i = 0; i < 100; i++) { + f += UNSAFE.getInt(array[i], F_OFFSET); + } + return f; + } + + static public void main(String[] args) { + Object[] array = new Object[100]; + Arrays.fill(array, new A()); + + for (int i = 0; i < 20000; i++) { + test(array); + } + } +} diff --git a/test/hotspot/jtreg/gc/survivorAlignment/AlignmentHelper.java b/test/hotspot/jtreg/gc/survivorAlignment/AlignmentHelper.java deleted file mode 100644 index 39246cadb75..00000000000 --- a/test/hotspot/jtreg/gc/survivorAlignment/AlignmentHelper.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package gc.survivorAlignment; - -import java.lang.management.MemoryPoolMXBean; -import java.util.Optional; - -import sun.hotspot.WhiteBox; - -/** - * Helper class aimed to provide information about alignment of objects in - * particular heap space, expected memory usage after objects' allocation so on. - */ -public class AlignmentHelper { - private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); - - private static final long OBJECT_ALIGNMENT_IN_BYTES_FOR_32_VM = 8L; - - /** - * Max relative allowed actual memory usage deviation from expected memory - * usage. - */ - private static final float MAX_RELATIVE_DEVIATION = 0.05f; // 5% - - public static final long OBJECT_ALIGNMENT_IN_BYTES = Optional.ofNullable( - AlignmentHelper.WHITE_BOX.getIntxVMFlag("ObjectAlignmentInBytes")) - .orElse(AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES_FOR_32_VM); - - public static final long SURVIVOR_ALIGNMENT_IN_BYTES = Optional.ofNullable( - AlignmentHelper.WHITE_BOX.getIntxVMFlag("SurvivorAlignmentInBytes")) - .orElseThrow(() ->new AssertionError( - "Unable to get SurvivorAlignmentInBytes value")); - /** - * Min amount of memory that will be occupied by an object. - */ - public static final long MIN_OBJECT_SIZE - = AlignmentHelper.WHITE_BOX.getObjectSize(new Object()); - /** - * Min amount of memory that will be occupied by an empty byte array. - */ - public static final long MIN_ARRAY_SIZE - = AlignmentHelper.WHITE_BOX.getObjectSize(new byte[0]); - - /** - * Precision at which actual memory usage in a heap space represented by - * this sizing helper could be measured. - */ - private final long memoryUsageMeasurementPrecision; - /** - * Min amount of memory that will be occupied by an object allocated in a - * heap space represented by this sizing helper. - */ - private final long minObjectSizeInThisSpace; - /** - * Object's alignment in a heap space represented by this sizing helper. - */ - private final long objectAlignmentInThisRegion; - /** - * MemoryPoolMXBean associated with a heap space represented by this sizing - * helper. - */ - private final MemoryPoolMXBean poolMXBean; - - private static long alignUp(long value, long alignment) { - return ((value - 1) / alignment + 1) * alignment; - } - - protected AlignmentHelper(long memoryUsageMeasurementPrecision, - long objectAlignmentInThisRegion, long minObjectSizeInThisSpace, - MemoryPoolMXBean poolMXBean) { - this.memoryUsageMeasurementPrecision = memoryUsageMeasurementPrecision; - this.minObjectSizeInThisSpace = minObjectSizeInThisSpace; - this.objectAlignmentInThisRegion = objectAlignmentInThisRegion; - this.poolMXBean = poolMXBean; - } - - /** - * Returns how many objects have to be allocated to fill - * {@code memoryToFill} bytes in this heap space using objects of size - * {@code objectSize}. - */ - public int getObjectsCount(long memoryToFill, long objectSize) { - return (int) (memoryToFill / getObjectSizeInThisSpace(objectSize)); - } - - /** - * Returns amount of memory that {@code objectsCount} of objects with size - * {@code objectSize} will occupy this this space after allocation. - */ - public long getExpectedMemoryUsage(long objectSize, int objectsCount) { - long correctedObjectSize = getObjectSizeInThisSpace(objectSize); - return AlignmentHelper.alignUp(correctedObjectSize * objectsCount, - memoryUsageMeasurementPrecision); - } - - /** - * Returns current memory usage in this heap space. - */ - public long getActualMemoryUsage() { - return poolMXBean.getUsage().getUsed(); - } - - /** - * Returns maximum memory usage deviation from {@code expectedMemoryUsage} - * given the max allowed relative deviation equal to - * {@code relativeDeviation}. - * - * Note that value returned by this method is aligned according to - * memory measurement precision for this heap space. - */ - public long getAllowedMemoryUsageDeviation(long expectedMemoryUsage) { - long unalignedDeviation = (long) (expectedMemoryUsage * - AlignmentHelper.MAX_RELATIVE_DEVIATION); - return AlignmentHelper.alignUp(unalignedDeviation, - memoryUsageMeasurementPrecision); - } - - /** - * Returns amount of memory that will be occupied by an object with size - * {@code objectSize} in this heap space. - */ - public long getObjectSizeInThisSpace(long objectSize) { - objectSize = Math.max(objectSize, minObjectSizeInThisSpace); - - long alignedObjectSize = AlignmentHelper.alignUp(objectSize, - objectAlignmentInThisRegion); - long sizeDiff = alignedObjectSize - objectSize; - - // If there is not enough space to fit padding object, then object will - // be aligned to {@code 2 * objectAlignmentInThisRegion}. - if (sizeDiff >= AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES - && sizeDiff < AlignmentHelper.MIN_OBJECT_SIZE) { - alignedObjectSize += AlignmentHelper.MIN_OBJECT_SIZE; - alignedObjectSize = AlignmentHelper.alignUp(alignedObjectSize, - objectAlignmentInThisRegion); - } - - return alignedObjectSize; - } - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - - builder.append(String.format("AlignmentHelper for memory pool '%s':%n", - poolMXBean.getName())); - builder.append(String.format("Memory usage measurement precision: %d%n", - memoryUsageMeasurementPrecision)); - builder.append(String.format("Min object size in this space: %d%n", - minObjectSizeInThisSpace)); - builder.append(String.format("Object alignment in this space: %d%n", - objectAlignmentInThisRegion)); - - return builder.toString(); - } -} diff --git a/test/hotspot/jtreg/gc/survivorAlignment/SurvivorAlignmentTestMain.java b/test/hotspot/jtreg/gc/survivorAlignment/SurvivorAlignmentTestMain.java deleted file mode 100644 index 6e2a70722b3..00000000000 --- a/test/hotspot/jtreg/gc/survivorAlignment/SurvivorAlignmentTestMain.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package gc.survivorAlignment; - -import java.lang.management.ManagementFactory; -import java.lang.management.MemoryPoolMXBean; -import java.util.Objects; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import jdk.test.lib.Asserts; -import com.sun.management.ThreadMXBean; -import sun.hotspot.WhiteBox; -import jdk.internal.misc.Unsafe; - -/** - * Main class for tests on {@code SurvivorAlignmentInBytes} option. - * - * Typical usage is to obtain instance using fromArgs method, allocate objects - * and verify that actual memory usage in tested heap space is close to - * expected. - */ -public class SurvivorAlignmentTestMain { - enum HeapSpace { - EDEN, - SURVIVOR, - TENURED - } - - public static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); - - public static final long MAX_TENURING_THRESHOLD = Optional.ofNullable( - SurvivorAlignmentTestMain.WHITE_BOX.getIntxVMFlag( - "MaxTenuringThreshold")).orElse(15L); - - /** - * Regexp used to parse memory size params, like 2G, 34m or 15k. - */ - private static final Pattern SIZE_REGEX - = Pattern.compile("(?[0-9]+)(?[GMKgmk])?"); - - // Names of different heap spaces. - private static final String DEF_NEW_EDEN = "Eden Space"; - private static final String DEF_NEW_SURVIVOR = "Survivor Space"; - private static final String PAR_NEW_EDEN = "Par Eden Space"; - private static final String PAR_NEW_SURVIVOR = "Par Survivor Space"; - private static final String PS_EDEN = "PS Eden Space"; - private static final String PS_SURVIVOR = "PS Survivor Space"; - private static final String G1_EDEN = "G1 Eden Space"; - private static final String G1_SURVIVOR = "G1 Survivor Space"; - private static final String SERIAL_TENURED = "Tenured Gen"; - private static final String PS_TENURED = "PS Old Gen"; - private static final String G1_TENURED = "G1 Old Gen"; - - private static final long G1_HEAP_REGION_SIZE = Optional.ofNullable( - SurvivorAlignmentTestMain.WHITE_BOX.getUintxVMFlag( - "G1HeapRegionSize")).orElse(-1L); - - private static final AlignmentHelper EDEN_SPACE_HELPER; - private static final AlignmentHelper SURVIVOR_SPACE_HELPER; - private static final AlignmentHelper TENURED_SPACE_HELPER; - /** - * Amount of memory that should be filled during a test run. - */ - private final long memoryToFill; - /** - * The size of an objects that will be allocated during a test run. - */ - private final long objectSize; - /** - * Amount of memory that will be actually occupied by an object in eden - * space. - */ - private final long actualObjectSize; - /** - * Storage for allocated objects. - */ - private final Object[] garbage; - /** - * Heap space whose memory usage is a subject of assertions during the test - * run. - */ - private final HeapSpace testedSpace; - - private long[] baselinedThreadMemoryUsage = null; - private long[] threadIds = null; - - /** - * Initialize {@code EDEN_SPACE_HELPER}, {@code SURVIVOR_SPACE_HELPER} and - * {@code TENURED_SPACE_HELPER} to represent heap spaces in use. - * - * Note that regardless to GC object's alignment in survivor space is - * expected to be equal to {@code SurvivorAlignmentInBytes} value and - * alignment in other spaces is expected to be equal to - * {@code ObjectAlignmentInBytes} value. - * - * For G1 GC MXBeans could report memory usage only with region size - * precision (if an object allocated in some G1 heap region, then all region - * will claimed as used), so for G1's spaces precision is equal to - * {@code G1HeapRegionSize} value. - */ - static { - AlignmentHelper edenHelper = null; - AlignmentHelper survivorHelper = null; - AlignmentHelper tenuredHelper = null; - for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) { - switch (pool.getName()) { - case SurvivorAlignmentTestMain.DEF_NEW_EDEN: - case SurvivorAlignmentTestMain.PAR_NEW_EDEN: - case SurvivorAlignmentTestMain.PS_EDEN: - Asserts.assertNull(edenHelper, - "Only one bean for eden space is expected."); - edenHelper = new AlignmentHelper( - AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES, - AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES, - AlignmentHelper.MIN_OBJECT_SIZE, pool); - break; - case SurvivorAlignmentTestMain.G1_EDEN: - Asserts.assertNull(edenHelper, - "Only one bean for eden space is expected."); - edenHelper = new AlignmentHelper( - SurvivorAlignmentTestMain.G1_HEAP_REGION_SIZE, - AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES, - AlignmentHelper.MIN_OBJECT_SIZE, pool); - break; - case SurvivorAlignmentTestMain.DEF_NEW_SURVIVOR: - case SurvivorAlignmentTestMain.PAR_NEW_SURVIVOR: - case SurvivorAlignmentTestMain.PS_SURVIVOR: - Asserts.assertNull(survivorHelper, - "Only one bean for survivor space is expected."); - survivorHelper = new AlignmentHelper( - AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES, - AlignmentHelper.SURVIVOR_ALIGNMENT_IN_BYTES, - AlignmentHelper.MIN_OBJECT_SIZE, pool); - break; - case SurvivorAlignmentTestMain.G1_SURVIVOR: - Asserts.assertNull(survivorHelper, - "Only one bean for survivor space is expected."); - survivorHelper = new AlignmentHelper( - SurvivorAlignmentTestMain.G1_HEAP_REGION_SIZE, - AlignmentHelper.SURVIVOR_ALIGNMENT_IN_BYTES, - AlignmentHelper.MIN_OBJECT_SIZE, pool); - break; - case SurvivorAlignmentTestMain.SERIAL_TENURED: - case SurvivorAlignmentTestMain.PS_TENURED: - case SurvivorAlignmentTestMain.G1_TENURED: - Asserts.assertNull(tenuredHelper, - "Only one bean for tenured space is expected."); - tenuredHelper = new AlignmentHelper( - AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES, - AlignmentHelper.OBJECT_ALIGNMENT_IN_BYTES, - AlignmentHelper.MIN_OBJECT_SIZE, pool); - break; - } - } - EDEN_SPACE_HELPER = Objects.requireNonNull(edenHelper, - "AlignmentHelper for eden space should be initialized."); - SURVIVOR_SPACE_HELPER = Objects.requireNonNull(survivorHelper, - "AlignmentHelper for survivor space should be initialized."); - TENURED_SPACE_HELPER = Objects.requireNonNull(tenuredHelper, - "AlignmentHelper for tenured space should be initialized."); - } - /** - * Returns an SurvivorAlignmentTestMain instance constructed using CLI - * options. - * - * Following options are expected: - *
      - *
    • memoryToFill
    • - *
    • objectSize
    • - *
    - * - * Both argument may contain multiplier suffix k, m or g. - */ - public static SurvivorAlignmentTestMain fromArgs(String[] args) { - Asserts.assertEQ(args.length, 3, "Expected three arguments: " - + "memory size, object size and tested heap space name."); - - long memoryToFill = parseSize(args[0]); - long objectSize = Math.max(parseSize(args[1]), - AlignmentHelper.MIN_ARRAY_SIZE); - HeapSpace testedSpace = HeapSpace.valueOf(args[2]); - - return new SurvivorAlignmentTestMain(memoryToFill, objectSize, - testedSpace); - } - - /** - * Returns a value parsed from a string with format - * <integer><multiplier>. - */ - private static long parseSize(String sizeString) { - Matcher matcher = SIZE_REGEX.matcher(sizeString); - Asserts.assertTrue(matcher.matches(), - "sizeString should have following format \"[0-9]+([MBK])?\""); - long size = Long.valueOf(matcher.group("size")); - - if (matcher.group("multiplier") != null) { - long K = 1024L; - // fall through multipliers - switch (matcher.group("multiplier").toLowerCase()) { - case "g": - size *= K; - case "m": - size *= K; - case "k": - size *= K; - } - } - return size; - } - - private SurvivorAlignmentTestMain(long memoryToFill, long objectSize, - HeapSpace testedSpace) { - this.objectSize = objectSize; - this.memoryToFill = memoryToFill; - this.testedSpace = testedSpace; - - AlignmentHelper helper = SurvivorAlignmentTestMain.EDEN_SPACE_HELPER; - - this.actualObjectSize = helper.getObjectSizeInThisSpace( - this.objectSize); - int arrayLength = helper.getObjectsCount(memoryToFill, this.objectSize); - garbage = new Object[arrayLength]; - } - - /** - * Allocate byte arrays to fill {@code memoryToFill} memory. - */ - public void allocate() { - int byteArrayLength = Math.max((int) (objectSize - - Unsafe.ARRAY_BYTE_BASE_OFFSET), 0); - - for (int i = 0; i < garbage.length; i++) { - garbage[i] = new byte[byteArrayLength]; - } - } - - /** - * Release memory occupied after {@code allocate} call. - */ - public void release() { - for (int i = 0; i < garbage.length; i++) { - garbage[i] = null; - } - } - - /** - * Returns expected amount of memory occupied in a {@code heapSpace} by - * objects referenced from {@code garbage} array. - */ - public long getExpectedMemoryUsage() { - AlignmentHelper alignmentHelper = getAlignmentHelper(testedSpace); - return alignmentHelper.getExpectedMemoryUsage(objectSize, - garbage.length); - } - - /** - * Verifies that memory usage in a {@code heapSpace} deviates from - * {@code expectedUsage} for no more than {@code MAX_RELATIVE_DEVIATION}. - */ - public void verifyMemoryUsage(long expectedUsage) { - AlignmentHelper alignmentHelper = getAlignmentHelper(testedSpace); - - long actualMemoryUsage = alignmentHelper.getActualMemoryUsage(); - boolean otherThreadsAllocatedMemory = areOtherThreadsAllocatedMemory(); - - long memoryUsageDiff = Math.abs(actualMemoryUsage - expectedUsage); - long maxAllowedUsageDiff - = alignmentHelper.getAllowedMemoryUsageDeviation(expectedUsage); - - System.out.println("Verifying memory usage in space: " + testedSpace); - System.out.println("Allocated objects count: " + garbage.length); - System.out.println("Desired object size: " + objectSize); - System.out.println("Actual object size: " + actualObjectSize); - System.out.println("Expected object size in space: " - + alignmentHelper.getObjectSizeInThisSpace(objectSize)); - System.out.println("Expected memory usage: " + expectedUsage); - System.out.println("Actual memory usage: " + actualMemoryUsage); - System.out.println("Memory usage diff: " + memoryUsageDiff); - System.out.println("Max allowed usage diff: " + maxAllowedUsageDiff); - - if (memoryUsageDiff > maxAllowedUsageDiff - && otherThreadsAllocatedMemory) { - System.out.println("Memory usage diff is incorrect, but it seems " - + "like someone else allocated objects"); - return; - } - - Asserts.assertLTE(memoryUsageDiff, maxAllowedUsageDiff, - "Actual memory usage should not deviate from expected for " + - "more then " + maxAllowedUsageDiff); - } - - /** - * Baselines amount of memory allocated by each thread. - */ - public void baselineMemoryAllocation() { - ThreadMXBean bean = (ThreadMXBean) ManagementFactory.getThreadMXBean(); - threadIds = bean.getAllThreadIds(); - baselinedThreadMemoryUsage = bean.getThreadAllocatedBytes(threadIds); - } - - /** - * Checks if threads other then the current thread were allocating objects - * after baselinedThreadMemoryUsage call. - * - * If baselinedThreadMemoryUsage was not called, then this method will return - * {@code false}. - */ - public boolean areOtherThreadsAllocatedMemory() { - if (baselinedThreadMemoryUsage == null) { - return false; - } - - ThreadMXBean bean = (ThreadMXBean) ManagementFactory.getThreadMXBean(); - long currentMemoryAllocation[] - = bean.getThreadAllocatedBytes(threadIds); - boolean otherThreadsAllocatedMemory = false; - - System.out.println("Verifying amount of memory allocated by threads:"); - for (int i = 0; i < threadIds.length; i++) { - System.out.format("Thread %d%nbaseline allocation: %d" - + "%ncurrent allocation:%d%n", threadIds[i], - baselinedThreadMemoryUsage[i], currentMemoryAllocation[i]); - System.out.println(bean.getThreadInfo(threadIds[i])); - - long bytesAllocated = Math.abs(currentMemoryAllocation[i] - - baselinedThreadMemoryUsage[i]); - if (bytesAllocated > 0 - && threadIds[i] != Thread.currentThread().getId()) { - otherThreadsAllocatedMemory = true; - } - } - - return otherThreadsAllocatedMemory; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - - builder.append(String.format("SurvivorAlignmentTestMain info:%n")); - builder.append(String.format("Desired object size: %d%n", objectSize)); - builder.append(String.format("Memory to fill: %d%n", memoryToFill)); - builder.append(String.format("Objects to be allocated: %d%n", - garbage.length)); - - builder.append(String.format("Alignment helpers to be used: %n")); - for (HeapSpace heapSpace: HeapSpace.values()) { - builder.append(String.format("For space %s:%n%s%n", heapSpace, - getAlignmentHelper(heapSpace))); - } - - return builder.toString(); - } - - /** - * Returns {@code AlignmentHelper} for a space {@code heapSpace}. - */ - public static AlignmentHelper getAlignmentHelper(HeapSpace heapSpace) { - switch (heapSpace) { - case EDEN: - return SurvivorAlignmentTestMain.EDEN_SPACE_HELPER; - case SURVIVOR: - return SurvivorAlignmentTestMain.SURVIVOR_SPACE_HELPER; - case TENURED: - return SurvivorAlignmentTestMain.TENURED_SPACE_HELPER; - default: - throw new Error("Unexpected heap space: " + heapSpace); - } - } -} diff --git a/test/hotspot/jtreg/gc/survivorAlignment/TestAllocationInEden.java b/test/hotspot/jtreg/gc/survivorAlignment/TestAllocationInEden.java deleted file mode 100644 index 45db235a50c..00000000000 --- a/test/hotspot/jtreg/gc/survivorAlignment/TestAllocationInEden.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package gc.survivorAlignment; - -/** - * @test gc.survivorAlignment.TestAllocationInEden - * @bug 8031323 - * @summary Verify that object's alignment in eden space is not affected by - * SurvivorAlignmentInBytes option. - * @requires vm.gc != "Z" & vm.gc != "Shenandoah" - * @library /test/lib - * @library / - * @modules java.base/jdk.internal.misc - * java.management - * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=32 -XX:-UseTLAB -XX:-ResizePLAB - * -XX:OldSize=128m -XX:MaxHeapSize=192m - * -XX:-ExplicitGCInvokesConcurrent - * gc.survivorAlignment.TestAllocationInEden 10m 9 EDEN - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=32 -XX:-UseTLAB -XX:-ResizePLAB - * -XX:OldSize=128m -XX:MaxHeapSize=192m - * -XX:-ExplicitGCInvokesConcurrent - * gc.survivorAlignment.TestAllocationInEden 10m 47 EDEN - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=64 -XX:-UseTLAB -XX:-ResizePLAB - * -XX:OldSize=128m -XX:MaxHeapSize=192m - * -XX:-ExplicitGCInvokesConcurrent - * gc.survivorAlignment.TestAllocationInEden 10m 9 EDEN - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=64 -XX:-UseTLAB -XX:-ResizePLAB - * -XX:OldSize=128m -XX:MaxHeapSize=192m - * -XX:-ExplicitGCInvokesConcurrent - * gc.survivorAlignment.TestAllocationInEden 10m 87 EDEN - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=128 -XX:-UseTLAB -XX:-ResizePLAB - * -XX:OldSize=128m -XX:MaxHeapSize=192m - * -XX:-ExplicitGCInvokesConcurrent - * gc.survivorAlignment.TestAllocationInEden 10m 9 EDEN - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=128 -XX:-UseTLAB -XX:-ResizePLAB - * -XX:OldSize=128m -XX:MaxHeapSize=192m - * -XX:-ExplicitGCInvokesConcurrent - * gc.survivorAlignment.TestAllocationInEden 10m 147 EDEN - */ -public class TestAllocationInEden { - public static void main(String args[]) { - SurvivorAlignmentTestMain test - = SurvivorAlignmentTestMain.fromArgs(args); - System.out.println(test); - - long expectedMemoryUsage = test.getExpectedMemoryUsage(); - test.baselineMemoryAllocation(); - System.gc(); - - test.allocate(); - - test.verifyMemoryUsage(expectedMemoryUsage); - } -} diff --git a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromEdenToTenured.java b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromEdenToTenured.java deleted file mode 100644 index cdbc1ffc0a0..00000000000 --- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromEdenToTenured.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package gc.survivorAlignment; - -/** - * @test gc.survivorAlignment.TestPromotionFromEdenToTenured - * @bug 8031323 - * @summary Verify that objects promoted from eden space to tenured space during - * full GC are not aligned to SurvivorAlignmentInBytes value. - * @requires vm.gc != "Z" & vm.gc != "Shenandoah" - * @library /test/lib - * @library / - * @modules java.base/jdk.internal.misc - * java.management - * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32m -XX:MaxHeapSize=96m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=32 - * gc.survivorAlignment.TestPromotionFromEdenToTenured 10m 9 TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32m -XX:MaxHeapSize=96m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=32 - * gc.survivorAlignment.TestPromotionFromEdenToTenured 10m 47 TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32m -XX:MaxHeapSize=96m - * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=64 - * gc.survivorAlignment.TestPromotionFromEdenToTenured 10m 9 TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32m -XX:MaxHeapSize=128m - * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=64 - * gc.survivorAlignment.TestPromotionFromEdenToTenured 10m 87 TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32M -XX:MaxHeapSize=96m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=128 - * gc.survivorAlignment.TestPromotionFromEdenToTenured 10m 9 TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32m -XX:MaxHeapSize=96m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=128 - * gc.survivorAlignment.TestPromotionFromEdenToTenured 10m 147 TENURED - */ -public class TestPromotionFromEdenToTenured { - public static void main(String args[]) { - SurvivorAlignmentTestMain test - = SurvivorAlignmentTestMain.fromArgs(args); - System.out.println(test); - - long expectedMemoryUsage = test.getExpectedMemoryUsage(); - test.baselineMemoryAllocation(); - System.gc(); - // increase expected usage by current old gen usage - expectedMemoryUsage += SurvivorAlignmentTestMain.getAlignmentHelper( - SurvivorAlignmentTestMain.HeapSpace.TENURED) - .getActualMemoryUsage(); - - test.allocate(); - System.gc(); - - test.verifyMemoryUsage(expectedMemoryUsage); - } -} diff --git a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java deleted file mode 100644 index 0f926f1d596..00000000000 --- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package gc.survivorAlignment; - -/** - * @test gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterFullGC - * @bug 8031323 - * @summary Verify that objects promoted from survivor space to tenured space - * during full GC are not aligned to SurvivorAlignmentInBytes value. - * @requires vm.gc != "Z" & vm.gc != "Shenandoah" - * @library /test/lib - * @library / - * @modules java.base/jdk.internal.misc - * java.management - * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32m -XX:MaxHeapSize=160m - * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=32 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterFullGC 10m 9 TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32m -XX:MaxHeapSize=160m -XX:-ResizePLAB - * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=32 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterFullGC 20m 47 - * TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=200m -XX:MaxNewSize=200m - * -XX:OldSize=32m -XX:MaxHeapSize=232m - * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=64 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterFullGC 10m 9 TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32m -XX:MaxHeapSize=160m - * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=64 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterFullGC 20m 87 - * TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m - * -XX:OldSize=32M -XX:MaxHeapSize=288m - * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=128 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterFullGC 10m 9 - * TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32m -XX:MaxHeapSize=160m - * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=128 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterFullGC 20m 147 - * TENURED - */ -public class TestPromotionFromSurvivorToTenuredAfterFullGC { - public static void main(String args[]) { - SurvivorAlignmentTestMain test - = SurvivorAlignmentTestMain.fromArgs(args); - System.out.println(test); - - long expectedMemoryUsage = test.getExpectedMemoryUsage(); - test.baselineMemoryAllocation(); - System.gc(); - // increase expected usage by current old gen usage - expectedMemoryUsage += SurvivorAlignmentTestMain.getAlignmentHelper( - SurvivorAlignmentTestMain.HeapSpace.TENURED) - .getActualMemoryUsage(); - - test.allocate(); - SurvivorAlignmentTestMain.WHITE_BOX.youngGC(); - System.gc(); - - test.verifyMemoryUsage(expectedMemoryUsage); - } -} diff --git a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java deleted file mode 100644 index 8f45164163d..00000000000 --- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package gc.survivorAlignment; - -/** - * @test gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterMinorGC - * @bug 8031323 - * @summary Verify that objects promoted from survivor space to tenured space - * when their age exceeded tenuring threshold are not aligned to - * SurvivorAlignmentInBytes value. - * @requires vm.gc != "Z" & vm.gc != "Shenandoah" - * @library /test/lib - * @library / - * @modules java.base/jdk.internal.misc - * java.management - * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1 -XX:-ResizePLAB - * -XX:-ExplicitGCInvokesConcurrent - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=32 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterMinorGC 10m 9 - * TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1 -XX:-ResizePLAB - * -XX:-ExplicitGCInvokesConcurrent - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=32 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterMinorGC 20m 47 - * TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=200m -XX:MaxNewSize=200m - * -XX:OldSize=32M -XX:MaxHeapSize=232m -XX:SurvivorRatio=1 -XX:-ResizePLAB - * -XX:-ExplicitGCInvokesConcurrent - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=64 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterMinorGC 10m 9 - * TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1 -XX:-ResizePLAB - * -XX:-ExplicitGCInvokesConcurrent - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=64 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterMinorGC 20m 87 - * TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m - * -XX:OldSize=32M -XX:MaxHeapSize=288m -XX:SurvivorRatio=1 -XX:-ResizePLAB - * -XX:-ExplicitGCInvokesConcurrent - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=128 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterMinorGC 10m 9 - * TENURED - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1 -XX:-ResizePLAB - * -XX:-ExplicitGCInvokesConcurrent - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=128 - * gc.survivorAlignment.TestPromotionFromSurvivorToTenuredAfterMinorGC 20m 147 - * TENURED - */ -public class TestPromotionFromSurvivorToTenuredAfterMinorGC { - public static void main(String args[]) throws Exception { - SurvivorAlignmentTestMain test - = SurvivorAlignmentTestMain.fromArgs(args); - System.out.println(test); - - long expectedMemoryUsage = test.getExpectedMemoryUsage(); - test.baselineMemoryAllocation(); - SurvivorAlignmentTestMain.WHITE_BOX.fullGC(); - // increase expected usage by current old gen usage - expectedMemoryUsage += SurvivorAlignmentTestMain.getAlignmentHelper( - SurvivorAlignmentTestMain.HeapSpace.TENURED) - .getActualMemoryUsage(); - - test.allocate(); - for (int i = 0; i <= SurvivorAlignmentTestMain.MAX_TENURING_THRESHOLD; i++) { - SurvivorAlignmentTestMain.WHITE_BOX.youngGC(); - } - - // Sometimes we see that data unrelated to the test has been allocated during - // the loop. This data is included in the expectedMemoryUsage since we look - // through all threads to see what they allocated. If this data is still in - // the survivor area however, it should not be included in expectedMemoryUsage - // since the verification below only look at what's in tenured space. - expectedMemoryUsage -= SurvivorAlignmentTestMain.getAlignmentHelper( - SurvivorAlignmentTestMain.HeapSpace.SURVIVOR) - .getActualMemoryUsage(); - test.verifyMemoryUsage(expectedMemoryUsage); - } -} diff --git a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java deleted file mode 100644 index e0a92f550d4..00000000000 --- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionLABLargeSurvivorAlignment.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package gc.survivorAlignment; - -/** - * @test gc.survivorAlignment.TestPromotionLABLargeSurvivorAlignment - * @bug 8060463 - * @summary Verify that objects promoted from eden space to survivor space - * with large values for SurvivorAlignmentInBytes succeed. - * @requires vm.opt.ExplicitGCInvokesConcurrent != true - * @run main/othervm -Xmx128m - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=8 -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * gc.survivorAlignment.TestPromotionLABLargeSurvivorAlignment - * @run main/othervm -Xmx128m - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=16 -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * gc.survivorAlignment.TestPromotionLABLargeSurvivorAlignment - * @run main/othervm -Xmx128m - * -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=256 -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * gc.survivorAlignment.TestPromotionLABLargeSurvivorAlignment - */ -public class TestPromotionLABLargeSurvivorAlignment { - public static void main(String args[]) { - Object garbage[] = new Object[1000000]; - for (int i = 0; i < garbage.length; i++) { - garbage[i] = new byte[0]; - } - for (int i = 0; i < 2; i++) { - System.gc(); - } - } -} - diff --git a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionToSurvivor.java b/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionToSurvivor.java deleted file mode 100644 index 3a6cb7e3421..00000000000 --- a/test/hotspot/jtreg/gc/survivorAlignment/TestPromotionToSurvivor.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package gc.survivorAlignment; - -/** - * @test gc.survivorAlignment.TestPromotionToSurvivor - * @bug 8031323 - * @summary Verify that objects promoted from eden space to survivor space after - * minor GC are aligned to SurvivorAlignmentInBytes. - * @requires vm.gc != "Z" & vm.gc != "Shenandoah" - * @library /test/lib - * @library / - * @modules java.base/jdk.internal.misc - * java.management - * @build sun.hotspot.WhiteBox - * @run driver ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=32 -XX:OldSize=128m - * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * gc.survivorAlignment.TestPromotionToSurvivor 10m 9 SURVIVOR - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=32 -XX:OldSize=128m - * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * gc.survivorAlignment.TestPromotionToSurvivor 20m 47 SURVIVOR - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=64 -XX:OldSize=128m - * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * gc.survivorAlignment.TestPromotionToSurvivor 8m 9 SURVIVOR - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=64 -XX:OldSize=128m - * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * gc.survivorAlignment.TestPromotionToSurvivor 20m 87 SURVIVOR - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=128 -XX:OldSize=128m - * -XX:MaxHeapSize=384m -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * gc.survivorAlignment.TestPromotionToSurvivor 10m 9 SURVIVOR - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=128 -XX:OldSize=128m - * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent -XX:-ResizePLAB - * gc.survivorAlignment.TestPromotionToSurvivor 20m 147 SURVIVOR - */ -public class TestPromotionToSurvivor { - public static void main(String args[]) { - SurvivorAlignmentTestMain test - = SurvivorAlignmentTestMain.fromArgs(args); - System.out.println(test); - - long expectedUsage = test.getExpectedMemoryUsage(); - test.baselineMemoryAllocation(); - SurvivorAlignmentTestMain.WHITE_BOX.fullGC(); - - test.allocate(); - SurvivorAlignmentTestMain.WHITE_BOX.youngGC(); - - test.verifyMemoryUsage(expectedUsage); - } -} diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java index 494158b5d91..7790d069ac3 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java @@ -60,7 +60,7 @@ public static void main(String[] args) throws Exception { // we should have crashed with a SIGFPE output_detail.shouldMatch("# A fatal error has been detected by the Java Runtime Environment:.*"); - output_detail.shouldMatch("# +SIGFPE.*"); + output_detail.shouldMatch("#.+SIGFPE.*"); // extract hs-err file String hs_err_file = output_detail.firstMatch("# *(\\S*hs_err_pid\\d+\\.log)", 1); diff --git a/test/hotspot/jtreg/runtime/InvocationTests/invocationGraalTests.java b/test/hotspot/jtreg/runtime/InvocationTests/invocationGraalTests.java index 9c60973c67a..402b7c669a0 100644 --- a/test/hotspot/jtreg/runtime/InvocationTests/invocationGraalTests.java +++ b/test/hotspot/jtreg/runtime/InvocationTests/invocationGraalTests.java @@ -30,6 +30,7 @@ * @library /test/lib * @modules java.base/jdk.internal.org.objectweb.asm * java.base/jdk.internal.misc + * @modules jdk.internal.vm.compiler * @compile shared/AbstractGenerator.java shared/AccessCheck.java shared/AccessType.java * shared/Caller.java shared/ExecutorGenerator.java shared/Utils.java * shared/ByteArrayClassLoader.java shared/Checker.java shared/GenericClassGenerator.java diff --git a/test/hotspot/jtreg/runtime/cds/appcds/BadBSM.java b/test/hotspot/jtreg/runtime/cds/appcds/BadBSM.java index 07d2c046f06..ae26d96d456 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/BadBSM.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/BadBSM.java @@ -42,7 +42,7 @@ public static void main(String[] args) throws Exception { OutputAnalyzer out = TestCommon.dump(appJar, TestCommon.list("WrongBSM", - "@lambda-proxy: WrongBSM 7")); + "@lambda-proxy WrongBSM 7")); out.shouldHaveExitValue(0); out.shouldContain( "is_supported_invokedynamic check failed for cp_index 7"); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/DumpClassListWithLF.java b/test/hotspot/jtreg/runtime/cds/appcds/DumpClassListWithLF.java index 6dba666c458..a0a898989e1 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/DumpClassListWithLF.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/DumpClassListWithLF.java @@ -105,5 +105,12 @@ appJar, classlist( "Hello", "@lambda-form-invoker [SPECIES_RESOLVE] java.lang.invoke.BoundMethodHandle$Species_L L"), "Incorrect number of items in the line: 3"); + // 10. The line with incorrect (less) number of items. + dumpShouldFail( + "TESTCASE 10: With incorrect @lambda-form-invoker tag", + appJar, classlist( + "Hello", + "@lambda-form-invoker-xxx [LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeStatic"), + "Invalid @ tag at the beginning of line \"@lambda-form-invoker-xxx\" line #2"); } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LambdaProxyClasslist.java b/test/hotspot/jtreg/runtime/cds/appcds/LambdaProxyClasslist.java index cb755c368b2..adafa0d9c69 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/LambdaProxyClasslist.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/LambdaProxyClasslist.java @@ -43,35 +43,42 @@ public static void main(String[] args) throws Exception { // 1. No error with a correct @lambda-proxy entry. OutputAnalyzer out = TestCommon.dump(appJar, TestCommon.list("LambHello", - "@lambda-proxy: LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V")); + "@lambda-proxy LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V")); out.shouldHaveExitValue(0); // 2. Error if the @lambda-proxy entry is too short. out = TestCommon.dump(appJar, TestCommon.list("LambHello", - "@lambda-proxy: LambHello")); + "@lambda-proxy LambHello")); out.shouldContain("An error has occurred while processing class list file") - .shouldContain("Line with @ tag has too few items \"@lambda-proxy:\" line #2") + .shouldContain("Line with @ tag has too few items \"@lambda-proxy\" line #2") .shouldContain("class list format error") .shouldHaveExitValue(1); // 3. Warning message if there's an incorrect signature in the @lambda-proxy entry. out = TestCommon.dump(appJar, TestCommon.list("LambHello", - "@lambda-proxy: LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()Z")); + "@lambda-proxy LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()Z")); out.shouldContain("[warning][cds] No invoke dynamic constant pool entry can be found for class LambHello. The classlist is probably out-of-date.") .shouldHaveExitValue(0); // 4. More blank spaces in between items should be fine. out = TestCommon.dump(appJar, TestCommon.list("LambHello", - "@lambda-proxy: LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V")); + "@lambda-proxy LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V")); out.shouldHaveExitValue(0); // 5. Trailing spaces at the end of the @lambda-proxy line should be fine. out = TestCommon.dump(appJar, TestCommon.list("LambHello", - "@lambda-proxy: LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V ")); + "@lambda-proxy LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V ")); out.shouldHaveExitValue(0); + + // 6. Error on invalid @lambda-proxy tag + out = TestCommon.dump(appJar, + TestCommon.list("LambHello", + "@lambda-proxy: LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V")); + out.shouldContain("Invalid @ tag at the beginning of line \"@lambda-proxy:\" line #2") + .shouldHaveExitValue(1); } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/ExceptionDuringDumpAtObjectsInitPhase.java b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/ExceptionDuringDumpAtObjectsInitPhase.java new file mode 100644 index 00000000000..78081a40f98 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/ExceptionDuringDumpAtObjectsInitPhase.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @summary Out of memory When dumping the CDS archive + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes + * @requires vm.cds.archived.java.heap + * @requires vm.jvmti + * @run driver ExceptionDuringDumpAtObjectsInitPhase + */ + +import jdk.test.lib.cds.CDSOptions; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class ExceptionDuringDumpAtObjectsInitPhase { + public static String appClasses[] = { + Hello.class.getName(), + }; + public static String agentClasses[] = { + GCDuringDumpTransformer.class.getName(), + GCDuringDumpTransformer.MyCleaner.class.getName(), + }; + + public static void main(String[] args) throws Throwable { + String agentJar = + ClassFileInstaller.writeJar("GCDuringDumpTransformer.jar", + ClassFileInstaller.Manifest.fromSourceFile("GCDuringDumpTransformer.mf"), + agentClasses); + + String appJar = + ClassFileInstaller.writeJar("GCDuringDumpApp.jar", appClasses); + + String gcLog = Boolean.getBoolean("test.cds.verbose.gc") ? + "-Xlog:gc*=info,gc+region=trace,gc+alloc+region=debug" : "-showversion"; + + // 1. Test with exception + System.out.println("1. Exception during dump"); + TestCommon.dump(appJar, + TestCommon.list(Hello.class.getName()), + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+AllowArchivingWithJavaAgent", + "-javaagent:" + agentJar, + "-Xlog:cds,class+load", + "-Xmx32m", + "-Dtest.with.exception=true", + gcLog).shouldNotHaveExitValue(0) + .shouldContain("Preload Error: Failed to load jdk/internal/math/FDBigInteger") + .shouldContain("VM exits due to exception, use -Xlog:cds,exceptions=trace for detail"); + + // 2. Test with OOM + System.out.println("2. OOM during dump"); + TestCommon.dump(appJar, + TestCommon.list(Hello.class.getName()), + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+AllowArchivingWithJavaAgent", + "-javaagent:" + agentJar, + "-Dtest.with.oom=true", + "-Xlog:cds,class+load", + "-Xmx12M", + gcLog).shouldNotHaveExitValue(0) + .shouldContain("Out of memory. Please run with a larger Java heap, current MaxHeapSize"); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDumpTransformer.java b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDumpTransformer.java index c523f2cc7b9..f50be0cedb2 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDumpTransformer.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/javaldr/GCDuringDumpTransformer.java @@ -26,10 +26,16 @@ import java.lang.instrument.Instrumentation; import java.lang.instrument.IllegalClassFormatException; import java.lang.ref.Cleaner; +import java.util.ArrayList; +import java.util.List; import java.security.ProtectionDomain; public class GCDuringDumpTransformer implements ClassFileTransformer { static boolean TEST_WITH_CLEANER = Boolean.getBoolean("test.with.cleaner"); + static boolean TEST_WITH_EXCEPTION = Boolean.getBoolean("test.with.exception"); + static boolean TEST_WITH_OOM = Boolean.getBoolean("test.with.oom"); + static List waste = new ArrayList(); + static Cleaner cleaner; static Thread thread; static Object garbage; @@ -45,6 +51,22 @@ public class GCDuringDumpTransformer implements ClassFileTransformer { public byte[] transform(ClassLoader loader, String name, Class classBeingRedefined, ProtectionDomain pd, byte[] buffer) throws IllegalClassFormatException { + // jdk/internal/math/FDBigInteger is loaded as part of archived heap. + if (name.equals("jdk/internal/math/FDBigInteger")) { + System.out.println("Transforming class jdk/internal/math/FDBigInteger"); + if (TEST_WITH_EXCEPTION) { + System.out.println("Return bad buffer for " + name); + return new byte[] {1, 2, 3, 4, 5, 6, 7, 8}; + } + if (TEST_WITH_OOM) { + // fill until OOM + System.out.println("Fill objects until OOM"); + for (;;) { + waste.add(new byte[64*1024]); + } + } + } + if (TEST_WITH_CLEANER) { if (name.equals("Hello")) { garbage = null; @@ -60,7 +82,6 @@ public byte[] transform(ClassLoader loader, String name, Class classBeingRede } catch (Throwable t2) {} } } - return null; } @@ -68,6 +89,8 @@ public byte[] transform(ClassLoader loader, String name, Class classBeingRede public static void premain(String agentArguments, Instrumentation instrumentation) { System.out.println("ClassFileTransformer.premain() is called: TEST_WITH_CLEANER = " + TEST_WITH_CLEANER); + System.out.println("ClassFileTransformer.premain() is called: TEST_WITH_EXCEPTION = " + TEST_WITH_EXCEPTION); + System.out.println("ClassFileTransformer.premain() is called: TEST_WITH_OOM = " + TEST_WITH_OOM); instrumentation.addTransformer(new GCDuringDumpTransformer(), /*canRetransform=*/true); savedInstrumentation = instrumentation; } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/NewModuleFinderTest.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/NewModuleFinderTest.java index 93c50b2a459..7f2a3edb3fa 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/NewModuleFinderTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/NewModuleFinderTest.java @@ -70,6 +70,7 @@ public static void main(String... args) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-Xlog:cds", "-Xlog:module=debug", + "-Dtest.src=" + TEST_SRC, "NewModuleFinderTest$Helper"); OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "exec"); out.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/serviceability/dcmd/compiler/PerfMapTest.java b/test/hotspot/jtreg/serviceability/dcmd/compiler/PerfMapTest.java new file mode 100644 index 00000000000..f4da5e979e3 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/dcmd/compiler/PerfMapTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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. + */ + +/* + * @test PerfMapTest + * @bug 8254723 + * @requires os.family == "linux" + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.compiler + * java.management + * jdk.internal.jvmstat/sun.jvmstat.monitor + * @run testng/othervm PerfMapTest + * @summary Test of diagnostic command Compiler.perfmap + */ + +import org.testng.annotations.Test; +import org.testng.Assert; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.dcmd.CommandExecutor; +import jdk.test.lib.dcmd.JMXExecutor; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Call jcmd Compiler.perfmap and check the output file has the expected + * format. + */ +public class PerfMapTest { + + static final Pattern LINE_PATTERN = + Pattern.compile("^((?:0x)?\\p{XDigit}+)\\s+((?:0x)?\\p{XDigit}+)\\s+(.*)$"); + + public void run(CommandExecutor executor) { + OutputAnalyzer output = executor.execute("Compiler.perfmap"); + + output.stderrShouldBeEmpty(); + output.stdoutShouldBeEmpty(); + + final long pid = ProcessHandle.current().pid(); + final Path path = Paths.get(String.format("/tmp/perf-%d.map", pid)); + + Assert.assertTrue(Files.exists(path)); + + // Sanity check the file contents + try { + for (String entry : Files.readAllLines(path)) { + Matcher m = LINE_PATTERN.matcher(entry); + Assert.assertTrue(m.matches(), "Invalid file format: " + entry); + } + } catch (IOException e) { + Assert.fail(e.toString()); + } + } + + @Test + public void jmx() { + run(new JMXExecutor()); + } +} diff --git a/test/jdk/ProblemList-zgc.txt b/test/jdk/ProblemList-zgc.txt index 98343188917..8fd7a85d1c4 100644 --- a/test/jdk/ProblemList-zgc.txt +++ b/test/jdk/ProblemList-zgc.txt @@ -26,5 +26,3 @@ # List of quarantined tests for testing with ZGC. # ############################################################################# - -com/sun/jdi/EATests.java#id0 8255072 generic-all diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index ebb3c420b24..fc16e0f81d0 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -254,7 +254,6 @@ java/awt/image/DrawImage/IncorrectAlphaSurface2SW.java 8056077 generic-all java/awt/image/DrawImage/IncorrectClipXorModeSW2Surface.java 8196025 windows-all java/awt/image/DrawImage/IncorrectClipXorModeSurface2Surface.java 8196025 windows-all java/awt/image/DrawImage/IncorrectSourceOffset.java 8196086 windows-all -java/awt/image/DrawImage/IncorrectUnmanagedImageRotatedClip.java 8196087 windows-all java/awt/image/MultiResolutionImage/MultiResolutionDrawImageWithTransformTest.java 8198390 generic-all java/awt/image/multiresolution/MultiresolutionIconTest.java 8169187 macosx-all,windows-all java/awt/print/Headless/HeadlessPrinterJob.java 8196088 windows-all @@ -741,14 +740,11 @@ javax/swing/JWindow/ShapedAndTranslucentWindows/TranslucentJComboBox.java 802462 # The next test below is an intermittent failure javax/swing/JComboBox/8033069/bug8033069ScrollBar.java 8163367 generic-all javax/swing/JColorChooser/Test6827032.java 8197825 windows-all -javax/swing/JColorChooser/Test6541987.java 8143021 windows-all,linux-all,macosx-all javax/swing/JTable/4235420/bug4235420.java 8079127 generic-all javax/swing/JSplitPane/4201995/bug4201995.java 8079127 generic-all javax/swing/JTree/DnD/LastNodeLowerHalfDrop.java 8159131 linux-all javax/swing/JTree/4633594/JTreeFocusTest.java 8173125 macosx-all -javax/swing/JFileChooser/8041694/bug8041694.java 8196302 windows-all,macosx-all javax/swing/AbstractButton/6711682/bug6711682.java 8060765 windows-all,macosx-all -javax/swing/Action/8133039/bug8133039.java 8196089 windows-all,macosx-all javax/swing/JComboBox/6559152/bug6559152.java 8196090 windows-all,macosx-all javax/swing/JComboBox/8032878/bug8032878.java 8196092,8196439 windows-all,macosx-all,linux-all javax/swing/JComboBox/8072767/bug8072767.java 8196093 windows-all,macosx-all @@ -762,14 +758,12 @@ javax/swing/JTabbedPane/8007563/Test8007563.java 8051591 generic-all javax/swing/JTabbedPane/4624207/bug4624207.java 8064922 macosx-all javax/swing/SwingUtilities/TestBadBreak/TestBadBreak.java 8160720 generic-all javax/swing/plaf/basic/Test6984643.java 8198340 windows-all -javax/swing/text/CSSBorder/6796710/bug6796710.java 8196099 windows-all javax/swing/text/DefaultCaret/HidingSelection/HidingSelectionTest.java 8194048 windows-all javax/swing/text/DefaultCaret/HidingSelection/MultiSelectionTest.java 8213562 linux-all javax/swing/text/JTextComponent/5074573/bug5074573.java 8196100 windows-all javax/swing/JFileChooser/6798062/bug6798062.java 8146446 windows-all javax/swing/JComboBox/8182031/ComboPopupTest.java 8196465 linux-all,macosx-all javax/swing/JFileChooser/6738668/bug6738668.java 8194946 generic-all -javax/swing/JFileChooser/8021253/bug8021253.java 8169954 windows-all,linux-all,macosx-all javax/swing/JFileChooser/8062561/bug8062561.java 8196466 linux-all,macosx-all javax/swing/JInternalFrame/Test6325652.java 8224977 macosx-all javax/swing/JInternalFrame/8146321/JInternalFrameIconTest.java 8225045 linux-all @@ -783,19 +777,12 @@ javax/swing/dnd/8139050/NativeErrorsInTableDnD.java 8202765 macosx-all,linux-al javax/swing/Popup/TaskbarPositionTest.java 8065097 macosx-all,linux-all javax/swing/JEditorPane/6917744/bug6917744.java 8213124 macosx-all javax/swing/JTree/6263446/bug6263446.java 8213125 macosx-all -javax/swing/ToolTipManager/Test6256140.java 8233560 macosx-all -javax/swing/text/View/8014863/bug8014863.java 8233561 macosx-all -javax/swing/text/StyledEditorKit/4506788/bug4506788.java 8233562 macosx-all -javax/swing/text/JTextComponent/6361367/bug6361367.java 8233569 macosx-all -javax/swing/text/html/HTMLEditorKit/5043626/bug5043626.java 233570 macosx-all javax/swing/JRootPane/4670486/bug4670486.java 8042381 macosx-all javax/swing/JRadioButton/ButtonGroupFocus/ButtonGroupFocusTest.java 8233555 macosx-all javax/swing/JRadioButton/8075609/bug8075609.java 8233555 macosx-all javax/swing/JRadioButton/8033699/bug8033699.java 8233555 macosx-all javax/swing/JPopupMenu/4634626/bug4634626.java 8017175 macosx-all -javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java 8233637 macosx-all javax/swing/JMenuItem/6249972/bug6249972.java 8233640 macosx-all -javax/swing/JMenuItem/4171437/bug4171437.java 8233641 macosx-all sanity/client/SwingSet/src/ToolTipDemoTest.java 8225012 windows-all,macosx-all sanity/client/SwingSet/src/ScrollPaneDemoTest.java 8225013 linux-all diff --git a/test/jdk/build/AbsPathsInImage.java b/test/jdk/build/AbsPathsInImage.java index e33bd0a9b1d..c3fe885554e 100644 --- a/test/jdk/build/AbsPathsInImage.java +++ b/test/jdk/build/AbsPathsInImage.java @@ -168,12 +168,12 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO private void scanFile(Path file, List searchPatterns) throws IOException { List matches = scanBytes(Files.readAllBytes(file), searchPatterns); - // For the same reason as the *.dll above, the jdk.incubator.jpackage module + // For the same reason as the *.dll above, the jdk.jpackage module // contains some unavoidable header references in the launcher which is // stored as a java resource inside the modules file. if (IS_WINDOWS && file.toString().endsWith("modules")) { matches = matches.stream() - .filter(f -> !f.matches(".*jdk\\.incubator\\.jpackage.*\\.h.*")) + .filter(f -> !f.matches(".*jdk\\.jpackage.*\\.h.*")) .collect(Collectors.toList()); } if (matches.size() > 0) { diff --git a/test/jdk/com/sun/jdi/EATests.java b/test/jdk/com/sun/jdi/EATests.java index 5a8db04fb3a..b19d364ed87 100644 --- a/test/jdk/com/sun/jdi/EATests.java +++ b/test/jdk/com/sun/jdi/EATests.java @@ -82,7 +82,7 @@ * * @author Richard Reingruber richard DOT reingruber AT sap DOT com * - * @requires ((vm.compMode == "Xmixed") & vm.jvmci) + * @requires ((vm.compMode == "Xmixed") & vm.graal.enabled) * * @library /test/lib /test/hotspot/jtreg * @@ -115,6 +115,7 @@ import jdk.test.lib.Asserts; import sun.hotspot.WhiteBox; +import sun.hotspot.gc.GC; // @@ -265,6 +266,7 @@ public static class TargetVMOptions { public final boolean EliminateAllocations; public final boolean DeoptimizeObjectsALot; public final boolean DoEscapeAnalysis; + public final boolean ZGCIsSelected; public TargetVMOptions(EATests env, ClassType testCaseBaseTargetClass) { Value val; @@ -277,6 +279,8 @@ public TargetVMOptions(EATests env, ClassType testCaseBaseTargetClass) { DeoptimizeObjectsALot = ((PrimitiveValue) val).booleanValue(); val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("UseJVMCICompiler")); UseJVMCICompiler = ((PrimitiveValue) val).booleanValue(); + val = testCaseBaseTargetClass.getValue(testCaseBaseTargetClass.fieldByName("ZGCIsSelected")); + ZGCIsSelected = ((PrimitiveValue) val).booleanValue(); } } @@ -742,12 +746,14 @@ public static boolean unbox(Boolean value, boolean dflt) { return value == null ? dflt : value; } - public static final boolean UseJVMCICompiler = unbox(WB.getBooleanVMFlag("UseJVMCICompiler"), false); // read by debugger - public static final boolean DoEscapeAnalysis = unbox(WB.getBooleanVMFlag("DoEscapeAnalysis"), UseJVMCICompiler); - public static final boolean EliminateAllocations = unbox(WB.getBooleanVMFlag("EliminateAllocations"), UseJVMCICompiler); // read by debugger - public static final boolean DeoptimizeObjectsALot = WB.getBooleanVMFlag("DeoptimizeObjectsALot"); // read by debugger + // Some of the fields are only read by the debugger + public static final boolean UseJVMCICompiler = unbox(WB.getBooleanVMFlag("UseJVMCICompiler"), false); + public static final boolean DoEscapeAnalysis = unbox(WB.getBooleanVMFlag("DoEscapeAnalysis"), UseJVMCICompiler); + public static final boolean EliminateAllocations = unbox(WB.getBooleanVMFlag("EliminateAllocations"), UseJVMCICompiler); + public static final boolean DeoptimizeObjectsALot = WB.getBooleanVMFlag("DeoptimizeObjectsALot"); public static final long BiasedLockingBulkRebiasThreshold = WB.getIntxVMFlag("BiasedLockingBulkRebiasThreshold"); public static final long BiasedLockingBulkRevokeThreshold = WB.getIntxVMFlag("BiasedLockingBulkRevokeThreshold"); + public static final boolean ZGCIsSelected = GC.Z.isSelected(); public String testMethodName; public int testMethodDepth; @@ -1047,7 +1053,7 @@ static class LinkedList { LinkedList l; public long[] array; public LinkedList(LinkedList l, int size) { - this.array = new long[size]; + this.array = size > 0 ? new long[size] : null; this.l = l; } } @@ -1057,12 +1063,13 @@ public LinkedList(LinkedList l, int size) { public void consumeAllMemory() { msg("consume all memory"); int size = 128 * 1024 * 1024; - while(size > 0) { + while(true) { try { while(true) { consumedMemory = new LinkedList(consumedMemory, size); } } catch(OutOfMemoryError oom) { + if (size == 0) break; } size = size / 2; } @@ -2571,10 +2578,8 @@ public void runTestCase() throws Exception { } freeAllMemory(); // We succeeded to pop just one frame. When we continue, we will call dontinline_brkpt() again. - Asserts.assertTrue(coughtOom || !env.targetVMOptions.EliminateAllocations, - "PopFrame should have triggered an OOM exception in target"); - String expectedTopFrame = - env.targetVMOptions.EliminateAllocations ? "dontinline_consume_all_memory_brkpt" : "dontinline_testMethod"; + Asserts.assertTrue(coughtOom, "PopFrame should have triggered an OOM exception in target"); + String expectedTopFrame = "dontinline_consume_all_memory_brkpt"; Asserts.assertEQ(expectedTopFrame, thread.frame(0).location().method().name()); printStack(thread); } @@ -2583,7 +2588,12 @@ public void runTestCase() throws Exception { public boolean shouldSkip() { // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random. // And Graal currently doesn't provide all information about non-escaping objects in debug info - return super.shouldSkip() || env.targetVMOptions.DeoptimizeObjectsALot || env.targetVMOptions.UseJVMCICompiler; + return super.shouldSkip() || + !env.targetVMOptions.EliminateAllocations || + // With ZGC the OOME is not always thrown as expected + env.targetVMOptions.ZGCIsSelected || + env.targetVMOptions.DeoptimizeObjectsALot || + env.targetVMOptions.UseJVMCICompiler; } } @@ -2623,7 +2633,12 @@ public long getExpectedLResult() { public boolean shouldSkip() { // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random. // And Graal currently doesn't provide all information about non-escaping objects in debug info - return super.shouldSkip() || DeoptimizeObjectsALot || UseJVMCICompiler; + return super.shouldSkip() || + !EliminateAllocations || + // With ZGC the OOME is not always thrown as expected + ZGCIsSelected || + DeoptimizeObjectsALot || + UseJVMCICompiler; } } @@ -2662,10 +2677,8 @@ public void runTestCase() throws Exception { freeAllMemory(); setField(testCase, "loopCount", env.vm().mirrorOf(0)); // terminate loop - Asserts.assertTrue(coughtOom || !env.targetVMOptions.EliminateAllocations, - "PopFrame should have triggered an OOM exception in target"); - String expectedTopFrame = - env.targetVMOptions.EliminateAllocations ? "inlinedCallForcedToReturn" : "dontinline_testMethod"; + Asserts.assertTrue(coughtOom, "PopFrame should have triggered an OOM exception in target"); + String expectedTopFrame = "inlinedCallForcedToReturn"; Asserts.assertEQ(expectedTopFrame, thread.frame(0).location().method().name()); } @@ -2673,7 +2686,12 @@ public void runTestCase() throws Exception { public boolean shouldSkip() { // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random. // And Graal currently doesn't provide all information about non-escaping objects in debug info - return super.shouldSkip() || env.targetVMOptions.DeoptimizeObjectsALot || env.targetVMOptions.UseJVMCICompiler; + return super.shouldSkip() || + !env.targetVMOptions.EliminateAllocations || + // With ZGC the OOME is not always thrown as expected + env.targetVMOptions.ZGCIsSelected || + env.targetVMOptions.DeoptimizeObjectsALot || + env.targetVMOptions.UseJVMCICompiler; } } @@ -2729,7 +2747,12 @@ public void warmupDone() { public boolean shouldSkip() { // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random. // And Graal currently doesn't provide all information about non-escaping objects in debug info - return super.shouldSkip() || DeoptimizeObjectsALot || UseJVMCICompiler; + return super.shouldSkip() || + !EliminateAllocations || + // With ZGC the OOME is not always thrown as expected + ZGCIsSelected || + DeoptimizeObjectsALot || + UseJVMCICompiler; } } @@ -2916,12 +2939,10 @@ public void runTestCase() throws Exception { coughtOom = true; } freeAllMemory(); - if (env.targetVMOptions.EliminateAllocations) { - printStack(thread); - Asserts.assertTrue(coughtOom, "ForceEarlyReturn should have triggered an OOM exception in target"); - msg("ForceEarlyReturn(2)"); - thread.forceEarlyReturn(env.vm().mirrorOf(43)); - } + Asserts.assertTrue(coughtOom, "ForceEarlyReturn should have triggered an OOM exception in target"); + printStack(thread); + msg("ForceEarlyReturn(2)"); + thread.forceEarlyReturn(env.vm().mirrorOf(43)); msg("Step over instruction to do the forced return"); env.stepOverInstruction(thread); printStack(thread); @@ -2932,7 +2953,12 @@ public void runTestCase() throws Exception { public boolean shouldSkip() { // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random. // And Graal currently doesn't support Force Early Return - return super.shouldSkip() || env.targetVMOptions.DeoptimizeObjectsALot || env.targetVMOptions.UseJVMCICompiler; + return super.shouldSkip() || + !env.targetVMOptions.EliminateAllocations || + // With ZGC the OOME is not always thrown as expected + env.targetVMOptions.ZGCIsSelected || + env.targetVMOptions.DeoptimizeObjectsALot || + env.targetVMOptions.UseJVMCICompiler; } } @@ -2989,7 +3015,12 @@ public void warmupDone() { public boolean shouldSkip() { // OOMEs because of realloc failures with DeoptimizeObjectsALot are too random. // And Graal currently doesn't support Force Early Return - return super.shouldSkip() || DeoptimizeObjectsALot || UseJVMCICompiler; + return super.shouldSkip() || + !EliminateAllocations || + // With ZGC the OOME is not always thrown as expected + ZGCIsSelected || + DeoptimizeObjectsALot || + UseJVMCICompiler; } } diff --git a/test/jdk/java/awt/image/DrawImage/IncorrectUnmanagedImageRotatedClip.java b/test/jdk/java/awt/image/DrawImage/IncorrectUnmanagedImageRotatedClip.java index 52b06c9021b..a942e303783 100644 --- a/test/jdk/java/awt/image/DrawImage/IncorrectUnmanagedImageRotatedClip.java +++ b/test/jdk/java/awt/image/DrawImage/IncorrectUnmanagedImageRotatedClip.java @@ -48,7 +48,9 @@ * @bug 8059942 * @summary Tests rotated clip when unmanaged image is drawn to VI. * Results of the blit to compatibleImage are used for comparison. - * @author Sergey Bylokhov + * @run main/othervm -Dsun.java2d.uiScale=1 IncorrectUnmanagedImageRotatedClip + * @run main/othervm -Dsun.java2d.uiScale=2 IncorrectUnmanagedImageRotatedClip + * @run main/othervm -Dsun.java2d.uiScale=3 IncorrectUnmanagedImageRotatedClip */ public final class IncorrectUnmanagedImageRotatedClip { diff --git a/test/jdk/java/io/InputStream/ReadNBytes.java b/test/jdk/java/io/InputStream/ReadNBytes.java index c4f643a7c5c..daac3d05a7f 100644 --- a/test/jdk/java/io/InputStream/ReadNBytes.java +++ b/test/jdk/java/io/InputStream/ReadNBytes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /* * @test - * @bug 8080835 8139206 + * @bug 8080835 8139206 8254742 * @library /test/lib * @build jdk.test.lib.RandomFactory * @run main ReadNBytes @@ -44,6 +44,7 @@ public class ReadNBytes { private static Random generator = RandomFactory.getRandom(); public static void main(String[] args) throws IOException { + test(); test(new byte[]{1, 2, 3}); test(createRandomBytes(1024)); for (int shift : new int[] {13, 15, 17}) { @@ -135,6 +136,19 @@ static void test(int max) throws IOException { check(!in.isClosed(), "Stream unexpectedly closed"); } + static void test() throws IOException { + final int chunkSize = 8192; + int size = (10 + generator.nextInt(11))*chunkSize; + + byte[] buf = new byte[size]; + generator.nextBytes(buf); + InputStream s = new ThrottledByteArrayInputStream(buf); + + byte[] b = s.readNBytes(size); + + check(Arrays.equals(b, buf), "Arrays not equal"); + } + static byte[] createRandomBytes(int size) { byte[] bytes = new byte[size]; generator.nextBytes(bytes); @@ -150,11 +164,32 @@ static void check(boolean cond, Object ... failedArgs) { throw new RuntimeException(sb.toString()); } - static class WrapperInputStream extends FilterInputStream { private boolean closed; WrapperInputStream(InputStream in) { super(in); } @Override public void close() throws IOException { closed = true; in.close(); } boolean isClosed() { return closed; } } + + static class ThrottledByteArrayInputStream extends ByteArrayInputStream { + private int count = 0; + + ThrottledByteArrayInputStream(byte[] buf) { + super(buf); + } + + @Override + // + // Sometimes return zero or a smaller count than requested. + // + public int read(byte[] buf, int off, int len) { + if (generator.nextBoolean()) { + return 0; + } else if (++count / 3 == 0) { + len /= 3; + } + + return super.read(buf, off, len); + } + } } diff --git a/test/jdk/java/lang/invoke/MethodHandles/TestDropReturn.java b/test/jdk/java/lang/invoke/MethodHandles/TestDropReturn.java new file mode 100644 index 00000000000..ff31dd63f0b --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandles/TestDropReturn.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8255398 + * @run testng TestDropReturn + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + +import static java.lang.invoke.MethodType.methodType; +import static org.testng.Assert.assertEquals; + +public class TestDropReturn { + + @Test(dataProvider = "dropReturnCases") + public void testDropReturn(Class cls, Object testValue) throws Throwable { + MethodHandle mh = MethodHandles.identity(cls); + assertEquals(mh.type(), methodType(cls, cls)); + Object x = mh.invoke(testValue); + assertEquals(x, testValue); + + mh = MethodHandles.dropReturn(mh); + assertEquals(mh.type(), methodType(void.class, cls)); + mh.invoke(testValue); // should at least work + } + + @DataProvider + public static Object[][] dropReturnCases() { + return new Object[][]{ + { boolean.class, true }, + { byte.class, (byte) 10 }, + { char.class, 'x' }, + { short.class, (short) 10 }, + { int.class, 10 }, + { long.class, 10L }, + { float.class, 10F }, + { double.class, 10D }, + { Object.class, new Object() }, + { String.class, "ABCD" }, + }; + } +} diff --git a/test/jdk/java/lang/invoke/MethodHandlesPermuteArgumentsTest.java b/test/jdk/java/lang/invoke/MethodHandlesPermuteArgumentsTest.java index 085ff908f60..ff25a14c29a 100644 --- a/test/jdk/java/lang/invoke/MethodHandlesPermuteArgumentsTest.java +++ b/test/jdk/java/lang/invoke/MethodHandlesPermuteArgumentsTest.java @@ -44,7 +44,7 @@ import static org.junit.Assert.*; -public class MethodHandlesPermuteArgumentsTest extends MethodHandlesTest { +public class MethodHandlesPermuteArgumentsTest extends test.java.lang.invoke.MethodHandlesTest { @Test // SLOW public void testPermuteArguments() throws Throwable { @@ -58,6 +58,11 @@ public void testPermuteArguments0() throws Throwable { if (CAN_TEST_LIGHTLY) return; testPermuteArguments(4, Integer.class, 2, String.class, 0); testPermuteArguments(6, Integer.class, 0, null, 30); + + testBadReorderArrayLength(); + testBadReorderIndex(); + testReturnTypeMismatch(); + testReorderTypeMismatch(); } public void testPermuteArguments(int max, Class type1, int t2c, Class type2, int dilution) throws Throwable { @@ -191,4 +196,57 @@ void testPermuteArguments(Object[] args, Class[] types, int[] reorder) throws } assertEquals(expected, result); } + + public void testBadReorderArrayLength() throws Throwable { + MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class)); + MethodType newType = MethodType.methodType(void.class, int.class, String.class); + assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 1), + IllegalArgumentException.class, ".*old type parameter count and reorder array length do not match.*"); + } + + public void testBadReorderIndex() throws Throwable { + MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class)); + MethodType newType = MethodType.methodType(void.class, int.class, String.class); + assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, 2), + IllegalArgumentException.class, ".*index is out of bounds for new type.*"); + assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, -1), + IllegalArgumentException.class, ".*index is out of bounds for new type.*"); + } + + public void testReturnTypeMismatch() throws Throwable { + MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class)); + MethodType newType = MethodType.methodType(int.class, int.class, String.class); + assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, 1), + IllegalArgumentException.class, ".*return types do not match.*"); + } + + public void testReorderTypeMismatch() throws Throwable { + MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class)); + MethodType newType = MethodType.methodType(void.class, double.class, String.class); + assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, 1), + IllegalArgumentException.class, ".*parameter types do not match after reorder.*"); + } + + private interface RunnableX { + void run() throws Throwable; + } + + private static void assertThrows(RunnableX r, Class exceptionClass, String messagePattern) throws Throwable { + try { + r.run(); + fail("Exception expected"); + } catch (Throwable e) { + if (exceptionClass.isInstance(e)) { + assertMatches(e.getMessage(), messagePattern); + } else { + throw e; + } + } + } + + private static void assertMatches(String str, String pattern) { + if (!str.matches(pattern)) { + throw new AssertionError("'" + str + "' did not match the pattern '" + pattern + "'."); + } + } } diff --git a/test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java b/test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java index 86e4ae1b0a1..89e0a56335e 100644 --- a/test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java +++ b/test/jdk/java/lang/invoke/defineHiddenClass/BasicTest.java @@ -31,7 +31,7 @@ * BadClassFileVersion.jcod * @build jdk.test.lib.Utils * jdk.test.lib.compiler.CompilerUtils - * @run testng/othervm --enable-preview BasicTest + * @run testng/othervm BasicTest */ import java.io.File; @@ -77,8 +77,7 @@ public class BasicTest { @BeforeTest static void setup() throws IOException { - compileSources(SRC_DIR, CLASSES_DIR, - "--enable-preview", "-source", String.valueOf(Runtime.version().feature())); + compileSources(SRC_DIR, CLASSES_DIR); hiddenClassBytes = Files.readAllBytes(CLASSES_DIR.resolve("HiddenClass.class")); // compile with --release 10 with no NestHost and NestMembers attribute diff --git a/test/jdk/java/lang/invoke/lambda/superProtectedMethod/SuperMethodTest.java b/test/jdk/java/lang/invoke/lambda/superProtectedMethod/SuperMethodTest.java index 333e87669db..624d2173a35 100644 --- a/test/jdk/java/lang/invoke/lambda/superProtectedMethod/SuperMethodTest.java +++ b/test/jdk/java/lang/invoke/lambda/superProtectedMethod/SuperMethodTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,11 @@ /* * @test - * @bug 8227415 - * @run main p.SuperMethodTest + * @bug 8227415 8254975 + * @run testng/othervm p.SuperMethodTest * @summary method reference to a protected method inherited from its - * superclass in a different package must be accessed via - * a bridge method. Lambda proxy class has no access to it. + * superclass in a different runtime package where + * lambda proxy class has no access to it. */ package p; @@ -35,12 +35,24 @@ import q.I; import q.J; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.function.Function; +import org.testng.annotations.Test; +import static org.testng.Assert.*; + public class SuperMethodTest { - public static void main(String... args) { + @Test + public static void remotePackageSameLoader() { Sub_I sub = new Sub_I(); sub.test(Paths.get("test")); } @@ -62,4 +74,68 @@ public void test(Path path) { c.check(path); } } + + @Test + public static void splitPackage() throws Throwable { + ClassLoader parent = new Loader("loader-A", null, A.class); + ClassLoader loader = new Loader("loader-B", parent, B.class); + Class aClass = Class.forName(A.class.getName(), false, loader); + Class bClass = Class.forName(B.class.getName(), false, loader); + assertTrue(aClass.getClassLoader() == parent); + assertTrue(bClass.getClassLoader() == loader); + assertEquals(aClass.getPackageName(), bClass.getPackageName()); + + Object b = bClass.getDeclaredConstructor().newInstance(); + + // verify subclass can access a protected member inherited from + // its superclass in a split package + MethodHandle test = MethodHandles.lookup() + .findVirtual(bClass, "test", MethodType.methodType(void.class)); + test.invoke(b); + + // verify lambda can access a protected member inherited from + // a superclass of the host class where the superclass is in + // a split package (not the same runtime package as the host class) + MethodHandle get = MethodHandles.lookup() + .findVirtual(bClass, "get", MethodType.methodType(Runnable.class)); + ((Runnable) get.invoke(b)).run(); + } + + static class Loader extends URLClassLoader { + static final Path CLASSES_DIR = Paths.get(System.getProperty("test.class.path")); + private final Class c; + Loader(String name, ClassLoader parent, Class c) { + super(name, new URL[]{}, parent); + this.c = c; + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + if (name.equals(c.getName())) { + try { + String path = name.replace('.', '/') + ".class"; + byte[] bytes = Files.readAllBytes(CLASSES_DIR.resolve(path)); + return defineClass(name, bytes, 0, bytes.length); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + return super.findClass(name); + } + + } + + public static class A { + protected void func() { } + } + + public static class B extends A { + public Runnable get() { + return this::func; + } + public void test() { + func(); + } + } } diff --git a/test/jdk/java/lang/ref/ReferenceRefersTo.java b/test/jdk/java/lang/ref/ReferenceRefersTo.java new file mode 100644 index 00000000000..8ccaf4f3d53 --- /dev/null +++ b/test/jdk/java/lang/ref/ReferenceRefersTo.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8188055 + * @summary Basic functional test of Reference.refersTo. + */ + +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.PhantomReference; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; + +public class ReferenceRefersTo { + private static final void fail(String msg) throws Exception { + throw new RuntimeException(msg); + } + + private static final void test(T ref, + Object expectedValue, + Object unexpectedValue, + String kind) throws Exception { + if ((expectedValue != null) && ref.refersTo(null)) { + fail(kind + "refers to null"); + } + if (!ref.refersTo(expectedValue)) { + fail(kind + " doesn't refer to expected value"); + } + if (ref.refersTo(unexpectedValue)) { + fail(kind + " refers to unexpected value"); + } + } + + public static void main(String[] args) throws Exception { + var queue = new ReferenceQueue(); + + var obj0 = new Object(); + var obj1 = new Object(); + var obj2 = new Object(); + var obj3 = new Object(); + + var pref = new PhantomReference(obj0, queue); + var wref = new WeakReference(obj1); + var sref = new SoftReference(obj2); + + test(pref, obj0, obj3, "phantom"); + test(wref, obj1, obj3, "weak"); + test(sref, obj2, obj3, "soft"); + + pref.clear(); + wref.clear(); + sref.clear(); + + test(pref, null, obj3, "phantom"); + test(wref, null, obj3, "weak"); + test(sref, null, obj3, "soft"); + } +} diff --git a/test/jdk/java/nio/channels/DatagramChannel/Connect.java b/test/jdk/java/nio/channels/DatagramChannel/Connect.java index c2d837289b4..a02b5fcf105 100644 --- a/test/jdk/java/nio/channels/DatagramChannel/Connect.java +++ b/test/jdk/java/nio/channels/DatagramChannel/Connect.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ /* @test * @bug 4313882 7183800 * @summary Test DatagramChannel's send and receive methods - * @author Mike McCloskey */ import java.io.*; @@ -32,7 +31,11 @@ import java.nio.*; import java.nio.channels.*; import java.nio.charset.*; - +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.stream.Stream; public class Connect { @@ -43,124 +46,127 @@ public static void main(String[] args) throws Exception { } static void test() throws Exception { - Reactor r = new Reactor(); - Actor a = new Actor(r.port()); - invoke(a, r); + ExecutorService threadPool = Executors.newCachedThreadPool(); + try (Reactor r = new Reactor(); + Actor a = new Actor(r.getSocketAddress()) + ) { + invoke(threadPool, a, r); + } finally { + threadPool.shutdown(); + } } - static void invoke(Sprintable reader, Sprintable writer) throws Exception { - - Thread writerThread = new Thread(writer); - writerThread.start(); - - Thread readerThread = new Thread(reader); - readerThread.start(); - - writerThread.join(); - readerThread.join(); - - reader.throwException(); - writer.throwException(); + static void invoke(ExecutorService e, Runnable reader, Runnable writer) throws CompletionException { + CompletableFuture f1 = CompletableFuture.runAsync(writer, e); + CompletableFuture f2 = CompletableFuture.runAsync(reader, e); + wait(f1, f2); } - public interface Sprintable extends Runnable { - public void throwException() throws Exception; - } - public static class Actor implements Sprintable { - final int port; - Exception e = null; + // This method waits for either one of the given futures to complete exceptionally + // or for all of the given futures to complete successfully. + private static void wait(CompletableFuture... futures) throws CompletionException { + CompletableFuture future = CompletableFuture.allOf(futures); + Stream.of(futures) + .forEach(f -> f.exceptionally(ex -> { + future.completeExceptionally(ex); + return null; + })); + future.join(); + } - Actor(int port) { - this.port = port; - } + public static class Actor implements AutoCloseable, Runnable { + final SocketAddress socketAddress; + final DatagramChannel dc; - public void throwException() throws Exception { - if (e != null) - throw e; + Actor(SocketAddress socketAddress) throws IOException { + this.socketAddress = socketAddress; + dc = DatagramChannel.open(); } public void run() { try { - DatagramChannel dc = DatagramChannel.open(); - - // Send a message ByteBuffer bb = ByteBuffer.allocateDirect(256); bb.put("hello".getBytes()); bb.flip(); - InetAddress address = InetAddress.getLocalHost(); - if (address.isLoopbackAddress()) { - address = InetAddress.getLoopbackAddress(); - } - InetSocketAddress isa = new InetSocketAddress(address, port); - dc.connect(isa); + dc.connect(socketAddress); + + // Send a message + log.println("Actor attempting to write to Reactor at " + socketAddress.toString()); dc.write(bb); // Try to send to some other address - address = InetAddress.getLocalHost(); - InetSocketAddress bogus = new InetSocketAddress(address, 3333); try { - dc.send(bb, bogus); - throw new RuntimeException("Allowed bogus send while connected"); + int port = dc.socket().getLocalPort(); + InetAddress loopback = InetAddress.getLoopbackAddress(); + InetSocketAddress otherAddress = new InetSocketAddress(loopback, (port == 3333 ? 3332 : 3333)); + log.println("Testing if Actor throws AlreadyConnectedException" + otherAddress.toString()); + dc.send(bb, otherAddress); + throw new RuntimeException("Actor allowed send to other address while already connected"); } catch (AlreadyConnectedException ace) { // Correct behavior } // Read a reply bb.flip(); + log.println("Actor waiting to read"); dc.read(bb); bb.flip(); - CharBuffer cb = Charset.forName("US-ASCII"). - newDecoder().decode(bb); - log.println("From Reactor: "+isa+ " said " +cb); - - // Clean up - dc.disconnect(); - dc.close(); + CharBuffer cb = StandardCharsets.US_ASCII. + newDecoder().decode(bb); + log.println("Actor received from Reactor at " + socketAddress + ": " + cb); } catch (Exception ex) { - e = ex; + log.println("Actor threw exception: " + ex); + throw new RuntimeException(ex); + } finally { + log.println("Actor finished"); } } + + @Override + public void close() throws IOException { + dc.close(); + } } - public static class Reactor implements Sprintable { + public static class Reactor implements AutoCloseable, Runnable { final DatagramChannel dc; - Exception e = null; Reactor() throws IOException { - dc = DatagramChannel.open().bind(new InetSocketAddress(0)); + dc = DatagramChannel.open().bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); } - int port() { - return dc.socket().getLocalPort(); - } - - public void throwException() throws Exception { - if (e != null) - throw e; + SocketAddress getSocketAddress() throws IOException { + return dc.getLocalAddress(); } public void run() { try { // Listen for a message ByteBuffer bb = ByteBuffer.allocateDirect(100); + log.println("Reactor waiting to receive"); SocketAddress sa = dc.receive(bb); bb.flip(); - CharBuffer cb = Charset.forName("US-ASCII"). - newDecoder().decode(bb); - log.println("From Actor: "+sa+ " said " +cb); + CharBuffer cb = StandardCharsets.US_ASCII. + newDecoder().decode(bb); + log.println("Reactor received from Actor at" + sa + ": " + cb); // Reply to sender dc.connect(sa); bb.flip(); + log.println("Reactor attempting to write: " + dc.getRemoteAddress().toString()); dc.write(bb); - - // Clean up - dc.disconnect(); - dc.close(); } catch (Exception ex) { - e = ex; + log.println("Reactor threw exception: " + ex); + throw new RuntimeException(ex); + } finally { + log.println("Reactor finished"); } } + + @Override + public void close() throws IOException { + dc.close(); + } } } diff --git a/test/jdk/java/nio/file/Files/Misc.java b/test/jdk/java/nio/file/Files/Misc.java index 553f8910a1d..0bfc0c410dc 100644 --- a/test/jdk/java/nio/file/Files/Misc.java +++ b/test/jdk/java/nio/file/Files/Misc.java @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6838333 8005566 8032220 8215467 + * @bug 4313887 6838333 8005566 8032220 8215467 8255576 * @summary Unit test for miscellenous methods in java.nio.file.Files * @library .. */ @@ -87,6 +87,9 @@ static void testCreateDirectories(Path tmpdir) throws IOException { * Tests isHidden */ static void testIsHidden(Path tmpdir) throws IOException { + // passing an empty path must not throw any runtime exception + assertTrue(!isHidden(Path.of(""))); + assertTrue(!isHidden(tmpdir)); Path file = tmpdir.resolve(".foo"); diff --git a/test/jdk/java/nio/file/Path/PathOps.java b/test/jdk/java/nio/file/Path/PathOps.java index 69d0c85e4a8..d6992c8ed2c 100644 --- a/test/jdk/java/nio/file/Path/PathOps.java +++ b/test/jdk/java/nio/file/Path/PathOps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,7 @@ */ /* @test - * @bug 4313887 6838333 6925932 7006126 8037945 8072495 8140449 + * @bug 4313887 6838333 6925932 7006126 8037945 8072495 8140449 8254876 * @summary Unit test for java.nio.file.Path path operations */ @@ -2042,6 +2042,18 @@ static void doUnixTests() { static void npes() { header("NullPointerException"); + try { + Path.of(null, "foo"); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + + try { + Path.of("foo", null); + throw new RuntimeException("NullPointerException not thrown"); + } catch (NullPointerException npe) { + } + Path path = FileSystems.getDefault().getPath("foo"); try { diff --git a/test/jdk/java/text/Bidi/BidiConformance.java b/test/jdk/java/text/Bidi/BidiConformance.java index 8c359361969..7fc7e61cd2e 100644 --- a/test/jdk/java/text/Bidi/BidiConformance.java +++ b/test/jdk/java/text/Bidi/BidiConformance.java @@ -1246,6 +1246,11 @@ private void testMethod_reorderVisually2() { "when levelStart is -1."); } catch (IllegalArgumentException e) { + if (!e.getMessage().equals( + "Value levelStart -1 is out of range 0 to " + (llen - 1))) { + errorHandling("reorderVisually() should throw an IAE" + + " mentioning levelStart is beyond the levels range. Message: " + e.getMessage()); + } } catch (ArrayIndexOutOfBoundsException e) { errorHandling("reorderVisually() should not throw an AIOoBE " + @@ -1258,6 +1263,11 @@ private void testMethod_reorderVisually2() { "when levelStart is 6(levels.length)."); } catch (IllegalArgumentException e) { + if (!e.getMessage().equals( + "Value levelStart " + llen + " is out of range 0 to " + (llen - 1))) { + errorHandling("reorderVisually() should throw an IAE" + + " mentioning levelStart is beyond the levels range. Message: " + e.getMessage()); + } } catch (ArrayIndexOutOfBoundsException e) { errorHandling("reorderVisually() should not throw an AIOoBE " + @@ -1278,6 +1288,11 @@ private void testMethod_reorderVisually2() { " when objectStart is -1."); } catch (IllegalArgumentException e) { + if (!e.getMessage().equals( + "Value objectStart -1 is out of range 0 to " + (olen - 1))) { + errorHandling("reorderVisually() should throw an IAE" + + " mentioning objectStart is beyond the objects range. Message: " + e.getMessage()); + } } catch (ArrayIndexOutOfBoundsException e) { errorHandling("reorderVisually() should not throw an AIOoBE " + @@ -1290,6 +1305,11 @@ private void testMethod_reorderVisually2() { "when objectStart is 6(objects.length)."); } catch (IllegalArgumentException e) { + if (!e.getMessage().equals( + "Value objectStart 6 is out of range 0 to " + (olen - 1))) { + errorHandling("reorderVisually() should throw an IAE" + + " mentioning objectStart is beyond the objects range. Message: " + e.getMessage()); + } } try { @@ -1298,6 +1318,12 @@ private void testMethod_reorderVisually2() { "when count is -1."); } catch (IllegalArgumentException e) { + if (!e.getMessage().equals( + "Value count -1 is less than zero, or objectStart + count " + + "is beyond objects length " + olen)) { + errorHandling("reorderVisually() should throw an IAE" + + " mentioning objectStart/count is beyond the objects range. Message: " + e.getMessage()); + } } catch (NegativeArraySizeException e) { errorHandling("reorderVisually() should not throw an NASE " + @@ -1310,6 +1336,12 @@ private void testMethod_reorderVisually2() { "when count is 7(objects.length+1)."); } catch (IllegalArgumentException e) { + if (!e.getMessage().equals( + "Value count " + (count + 1) + " is less than zero, or objectStart + count " + + "is beyond objects length " + olen)) { + errorHandling("reorderVisually() should throw an IAE" + + " mentioning objectStart/count is beyond the objects range. Message: " + e.getMessage()); + } } catch (ArrayIndexOutOfBoundsException e) { errorHandling("reorderVisually() should not throw an AIOoBE " + diff --git a/test/jdk/javax/swing/Action/8133039/bug8133039.java b/test/jdk/javax/swing/Action/8133039/bug8133039.java index 766a71204c0..f36b1b1ab10 100644 --- a/test/jdk/javax/swing/Action/8133039/bug8133039.java +++ b/test/jdk/javax/swing/Action/8133039/bug8133039.java @@ -89,7 +89,7 @@ private static void testPopupAction() throws Exception { SwingUtilities.invokeAndWait(bug8133039::createAndShowGUI); Robot robot = new Robot(); - robot.setAutoDelay(50); + robot.setAutoDelay(100); robot.waitForIdle(); robot.keyPress(KeyEvent.VK_A); @@ -130,6 +130,7 @@ private static void createAndShowGUI() { comboBox.getActionMap().put("showPopup", showPopupAction); frame.getContentPane().add(comboBox); + frame.setLocationRelativeTo(null); frame.setVisible(true); } diff --git a/test/jdk/javax/swing/JColorChooser/Test6541987.java b/test/jdk/javax/swing/JColorChooser/Test6541987.java index 84053cd1b8f..79e78e993bf 100644 --- a/test/jdk/javax/swing/JColorChooser/Test6541987.java +++ b/test/jdk/javax/swing/JColorChooser/Test6541987.java @@ -42,24 +42,33 @@ public class Test6541987 implements Runnable { private static Robot robot; + private static JFrame frame; - public static void main(String[] args) throws AWTException { - robot = new Robot(); - // test escape after selection - start(); - click(KeyEvent.VK_ESCAPE); - robot.waitForIdle(); - // test double escape after editing - start(); - click(KeyEvent.VK_1); - click(KeyEvent.VK_0); - click(KeyEvent.VK_ESCAPE); - click(KeyEvent.VK_ESCAPE); - robot.waitForIdle(); - // all windows should be closed - for (Window window : Window.getWindows()) { - if (window.isVisible()) { - throw new Error("found visible window: " + window.getName()); + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + robot.setAutoDelay(100); + // test escape after selection + start(); + click(KeyEvent.VK_ESCAPE); + robot.waitForIdle(); + // test double escape after editing + start(); + click(KeyEvent.VK_1); + click(KeyEvent.VK_0); + click(KeyEvent.VK_ESCAPE); + click(KeyEvent.VK_ESCAPE); + robot.waitForIdle(); + robot.delay(500); + // all windows should be closed + for (Window window : Window.getWindows()) { + if (window.isVisible()) { + throw new Error("found visible window: " + window.getName()); + } + } + } finally { + if (frame != null) { + SwingUtilities.invokeAndWait(frame::dispose); } } } @@ -85,7 +94,8 @@ private static void click(int...keys) { public void run() { String title = getClass().getName(); - JFrame frame = new JFrame(title); + frame = new JFrame(title); + frame.setLocationRelativeTo(null); frame.setVisible(true); Color color = JColorChooser.showDialog(frame, title, Color.BLACK); diff --git a/test/jdk/javax/swing/JFileChooser/8021253/bug8021253.java b/test/jdk/javax/swing/JFileChooser/8021253/bug8021253.java index 831711b260f..35750d506b6 100644 --- a/test/jdk/javax/swing/JFileChooser/8021253/bug8021253.java +++ b/test/jdk/javax/swing/JFileChooser/8021253/bug8021253.java @@ -47,34 +47,41 @@ public class bug8021253 { private static volatile boolean defaultKeyPressed; private static JFileChooser fileChooser; private static File file; + private static JFrame frame; public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + robot.setAutoDelay(100); - Robot robot = new Robot(); - robot.setAutoDelay(50); - - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - createAndShowGUI(); - } - }); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); - robot.waitForIdle(); + robot.waitForIdle(); + robot.delay(1000); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - fileChooser.setSelectedFile(file); - } - }); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + fileChooser.setSelectedFile(file); + } + }); - robot.waitForIdle(); + robot.waitForIdle(); - robot.keyPress(KeyEvent.VK_ENTER); - robot.keyRelease(KeyEvent.VK_ENTER); - robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.waitForIdle(); - if (!defaultKeyPressed) { - throw new RuntimeException("Default button is not pressed"); + if (!defaultKeyPressed) { + throw new RuntimeException("Default button is not pressed"); + } + } finally { + if (frame != null) { + SwingUtilities.invokeAndWait(frame::dispose); + } } } @@ -82,7 +89,7 @@ private static void createAndShowGUI() { file = getTempFile(); - final JFrame frame = new JFrame("Test"); + frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(200, 300); @@ -97,6 +104,7 @@ public void actionPerformed(ActionEvent e) { frame.getContentPane().add(BorderLayout.CENTER, fileChooser); frame.setSize(fileChooser.getPreferredSize()); + frame.setLocationRelativeTo(null); frame.setVisible(true); } diff --git a/test/jdk/javax/swing/JFileChooser/8041694/bug8041694.java b/test/jdk/javax/swing/JFileChooser/8041694/bug8041694.java index 311f19a44a1..3e3cb3b9658 100644 --- a/test/jdk/javax/swing/JFileChooser/8041694/bug8041694.java +++ b/test/jdk/javax/swing/JFileChooser/8041694/bug8041694.java @@ -57,6 +57,7 @@ private static void runTest() { // Set Metal L&F to make the test compatible with OS X. UIManager.setLookAndFeel(new MetalLookAndFeel()); Robot robot = new Robot(); + robot.setAutoDelay(100); dir1 = Files.createTempDirectory("bug8041694").toFile(); if (Platform.isWindows()) { @@ -83,15 +84,17 @@ public void run() { } }); - robot.setAutoDelay(50); robot.delay(1000); robot.waitForIdle(); robot.keyPress(KeyEvent.VK_D); robot.keyRelease(KeyEvent.VK_D); + robot.waitForIdle(); robot.keyPress(KeyEvent.VK_SPACE); robot.keyRelease(KeyEvent.VK_SPACE); + robot.waitForIdle(); robot.keyPress(KeyEvent.VK_ENTER); robot.keyRelease(KeyEvent.VK_ENTER); + robot.waitForIdle(); fChooserClosedSignal.await(); if (selectedDir == null) { diff --git a/test/jdk/javax/swing/JMenuItem/4171437/bug4171437.java b/test/jdk/javax/swing/JMenuItem/4171437/bug4171437.java index 3bac95fad72..da2e8dccdc3 100644 --- a/test/jdk/javax/swing/JMenuItem/4171437/bug4171437.java +++ b/test/jdk/javax/swing/JMenuItem/4171437/bug4171437.java @@ -44,21 +44,21 @@ public class bug4171437 { public static void main(String[] args) throws Exception { try { + Robot robot = new Robot(); + robot.setAutoDelay(100); SwingUtilities.invokeAndWait(new Runnable() { public void run() { createAndShowGUI(); } }); - Robot robot = new Robot(); - robot.setAutoDelay(50); robot.waitForIdle(); + robot.delay(1000); Util.hitMnemonics(robot, KeyEvent.VK_F); Util.hitKeys(robot, KeyEvent.VK_C); robot.waitForIdle(); - Thread.sleep(1000); if (!closeActivated || customActivated) { throw new RuntimeException("Didn't pass the muster"); @@ -109,6 +109,7 @@ public void menuCanceled(MenuEvent e) {} frame.setSize(300, 300); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); + frame.setLocationRelativeTo(null); frame.setVisible(true); } } diff --git a/test/jdk/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java b/test/jdk/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java index 141eb204a4f..800c7693206 100644 --- a/test/jdk/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java +++ b/test/jdk/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java @@ -63,13 +63,15 @@ public static void main(String[] args) throws Exception { } try { + Robot robot = new Robot(); + robot.setAutoDelay(100); System.setProperty("apple.laf.useScreenMenuBar", "true"); SwingUtilities.invokeAndWait( ActionListenerCalledTwiceTest::createAndShowGUI); - Robot robot = new Robot(); - robot.setAutoDelay(100); + robot.waitForIdle(); + robot.delay(1000); testForTwice(robot, ""); @@ -99,6 +101,7 @@ private static void createAndShowGUI() { frame.setJMenuBar(bar); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); + frame.setLocationRelativeTo(null); frame.setVisible(true); } diff --git a/test/jdk/javax/swing/JSpinner/SerializationTest.java b/test/jdk/javax/swing/JSpinner/SerializationTest.java new file mode 100644 index 00000000000..40467a679c6 --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/SerializationTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +import javax.swing.JSpinner; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +import static javax.swing.UIManager.getInstalledLookAndFeels; + +/** + * @test + * @bug 7124397 + * @summary Verifies that JSpinner can be serialized/deserialized correctly. + */ +public final class SerializationTest { + + public static void main(String[] argv) throws Exception { + for (UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) { + EventQueue.invokeAndWait(() -> setLookAndFeel(laf)); + EventQueue.invokeAndWait(() -> { + JSpinner spinner = new JSpinner(); + JSpinner firstCopy = (JSpinner) createCopy(spinner); + JSpinner secondCopy = (JSpinner) createCopy(firstCopy); + }); + } + } + + private static Object createCopy(Serializable objectToCopy) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(objectToCopy); + InputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bais); + return ois.readObject(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static void setLookAndFeel(UIManager.LookAndFeelInfo laf) { + try { + UIManager.setLookAndFeel(laf.getClassName()); + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Unsupported LookAndFeel: " + laf.getClassName()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/test/jdk/javax/swing/ToolTipManager/Test6256140.java b/test/jdk/javax/swing/ToolTipManager/Test6256140.java index 3456c0ecec8..641d58ac09e 100644 --- a/test/jdk/javax/swing/ToolTipManager/Test6256140.java +++ b/test/jdk/javax/swing/ToolTipManager/Test6256140.java @@ -40,49 +40,58 @@ public class Test6256140 { private final static String initialText = "value"; private final static JLabel toolTipLabel = new JLabel("tip"); + private static JFrame frame; public static void main(String[] args) throws Exception { - - Robot robot = new Robot(); - robot.setAutoDelay(10); - - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - createAndShowGUI(); + try { + Robot robot = new Robot(); + robot.setAutoDelay(100); + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); + robot.waitForIdle(); + robot.delay(1000); + + Point point = ft.getLocationOnScreen(); + robot.mouseMove(point.x, point.y); + robot.waitForIdle(); + robot.mouseMove(point.x + 3, point.y + 3); + robot.waitForIdle(); + + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.waitForIdle(); + + if (!isTooltipShowning()) { + throw new RuntimeException("Tooltip is not shown"); } - }); - robot.waitForIdle(); - - Point point = ft.getLocationOnScreen(); - robot.mouseMove(point.x, point.y); - robot.mouseMove(point.x + 3, point.y + 3); - robot.keyPress(KeyEvent.VK_A); - robot.keyRelease(KeyEvent.VK_A); - robot.waitForIdle(); - - if (!isTooltipShowning()) { - throw new RuntimeException("Tooltip is not shown"); - } + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.waitForIdle(); - robot.keyPress(KeyEvent.VK_ESCAPE); - robot.keyRelease(KeyEvent.VK_ESCAPE); - robot.waitForIdle(); - - if (isTooltipShowning()) { - throw new RuntimeException("Tooltip must be hidden now"); - } + if (isTooltipShowning()) { + throw new RuntimeException("Tooltip must be hidden now"); + } - if (isTextEqual()) { - throw new RuntimeException("FormattedTextField must *not* cancel the updated value this time"); - } + if (isTextEqual()) { + throw new RuntimeException("FormattedTextField must *not* cancel the updated value this time"); + } - robot.keyPress(KeyEvent.VK_ESCAPE); - robot.keyRelease(KeyEvent.VK_ESCAPE); - robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.waitForIdle(); - if (!isTextEqual()) { - throw new RuntimeException("FormattedTextField must cancel the updated value"); + if (!isTextEqual()) { + throw new RuntimeException("FormattedTextField must cancel the updated value"); + } + } finally { + if (frame != null) { + SwingUtilities.invokeAndWait(frame::dispose); + } } } @@ -116,7 +125,7 @@ private static void createAndShowGUI() { ToolTipManager.sharedInstance().setDismissDelay(Integer.MAX_VALUE); ToolTipManager.sharedInstance().setInitialDelay(0); - final JFrame frame = new JFrame(); + frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new FlowLayout()); diff --git a/test/jdk/javax/swing/text/CSSBorder/6796710/bug6796710.java b/test/jdk/javax/swing/text/CSSBorder/6796710/bug6796710.java index e492a62c7de..c8945c761fd 100644 --- a/test/jdk/javax/swing/text/CSSBorder/6796710/bug6796710.java +++ b/test/jdk/javax/swing/text/CSSBorder/6796710/bug6796710.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,12 +28,23 @@ * @summary Html content in JEditorPane is overlapping on swing components while resizing the application. * @library ../../../regtesthelpers * @build Util - @run main bug6796710 + * @run main/othervm -Dsun.java2d.uiScale=1 bug6796710 */ -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Rectangle; +import java.awt.Robot; import java.awt.image.BufferedImage; -import javax.swing.*; +import java.io.File; + +import javax.imageio.ImageIO; +import javax.swing.JButton; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; public class bug6796710 { // The page is inlined because we want to be sure that the JEditorPane filled synchronously @@ -89,6 +100,7 @@ public void run() { frame.setContentPane(pnContent); frame.setSize(400, 600); + frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } @@ -113,7 +125,10 @@ public void run() { // On Linux platforms realSync doesn't guaranties setSize completion Thread.sleep(1000); - if (!Util.compareBufferedImages(bufferedImage, getPnBottomImage())) { + BufferedImage pnBottomImage = getPnBottomImage(); + if (!Util.compareBufferedImages(bufferedImage, pnBottomImage)) { + ImageIO.write(bufferedImage, "png", new File("bufferedImage.png")); + ImageIO.write(pnBottomImage, "png", new File("pnBottomImage.png")); throw new RuntimeException("The test failed"); } diff --git a/test/jdk/javax/swing/text/JTextComponent/6361367/bug6361367.java b/test/jdk/javax/swing/text/JTextComponent/6361367/bug6361367.java index 153e6c7d655..0c00e561bcd 100644 --- a/test/jdk/javax/swing/text/JTextComponent/6361367/bug6361367.java +++ b/test/jdk/javax/swing/text/JTextComponent/6361367/bug6361367.java @@ -79,7 +79,7 @@ public JTextComponent call() throws Exception { waitForFocus(textComponent); Robot robot = new Robot(); robot.setAutoWaitForIdle(true); - robot.setAutoDelay(250); + robot.setAutoDelay(100); robot.keyPress(KeyEvent.VK_END); robot.keyRelease(KeyEvent.VK_END); robot.keyPress(KeyEvent.VK_SHIFT); diff --git a/test/jdk/javax/swing/text/StyledEditorKit/4506788/bug4506788.java b/test/jdk/javax/swing/text/StyledEditorKit/4506788/bug4506788.java index d2d16f681c3..e7c31a26d0f 100644 --- a/test/jdk/javax/swing/text/StyledEditorKit/4506788/bug4506788.java +++ b/test/jdk/javax/swing/text/StyledEditorKit/4506788/bug4506788.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,6 +65,7 @@ public void start() { Robot robot; try { robot = new Robot(); + robot.setAutoDelay(100); } catch (AWTException e) { throw new RuntimeException("Robot could not be created"); } @@ -78,7 +79,6 @@ public void start() { throw new RuntimeException("Could not get JEditorPane location on screen"); } - robot.setAutoDelay(50); robot.mouseMove(p.x, p.y); robot.mousePress(InputEvent.BUTTON1_MASK); robot.mouseRelease(InputEvent.BUTTON1_MASK); diff --git a/test/jdk/javax/swing/text/View/8014863/bug8014863.java b/test/jdk/javax/swing/text/View/8014863/bug8014863.java index 30e54b69c69..fba4fd255c2 100644 --- a/test/jdk/javax/swing/text/View/8014863/bug8014863.java +++ b/test/jdk/javax/swing/text/View/8014863/bug8014863.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ public class bug8014863 { public static void main(String[] args) throws Exception { robot = new Robot(); - robot.setAutoDelay(50); + robot.setAutoDelay(100); glyphViews = new ArrayList(); createAndShowGUI(text1); @@ -152,6 +152,7 @@ public void run() { frame.add(editorPane); frame.setSize(200, 200); + frame.setLocationRelativeTo(null); frame.setVisible(true); } }); diff --git a/test/jdk/javax/swing/text/html/HTMLEditorKit/5043626/bug5043626.java b/test/jdk/javax/swing/text/html/HTMLEditorKit/5043626/bug5043626.java index 8184b6a9562..cdce0dab584 100644 --- a/test/jdk/javax/swing/text/html/HTMLEditorKit/5043626/bug5043626.java +++ b/test/jdk/javax/swing/text/html/HTMLEditorKit/5043626/bug5043626.java @@ -26,9 +26,6 @@ * @key headful * @bug 5043626 * @summary Tests pressing Home or Ctrl+Home set cursor to invisible element - * @author Alexander Potochkin - * @library ../../../../regtesthelpers - * @build Util * @run main bug5043626 */ @@ -43,38 +40,51 @@ public class bug5043626 { private static Document doc; private static Robot robot; + private static JFrame frame; public static void main(String[] args) throws Exception { - robot = new Robot(); + try { + robot = new Robot(); + robot.setAutoDelay(100); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - createAndShowGUI(); - } - }); + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + createAndShowGUI(); + } + }); - robot.waitForIdle(); + robot.waitForIdle(); + robot.delay(1000); - Util.hitKeys(robot, KeyEvent.VK_HOME); - Util.hitKeys(robot, KeyEvent.VK_1); + robot.keyPress(KeyEvent.VK_HOME); + robot.keyRelease(KeyEvent.VK_HOME); + robot.keyPress(KeyEvent.VK_1); + robot.keyRelease(KeyEvent.VK_1); - robot.waitForIdle(); + robot.waitForIdle(); - String test = getText(); + String test = getText(); - if (!"1test".equals(test)) { - throw new RuntimeException("Begin line action set cursor inside tag"); - } + if (!"1test".equals(test)) { + throw new RuntimeException("Begin line action set cursor inside tag"); + } - Util.hitKeys(robot, KeyEvent.VK_HOME); - Util.hitKeys(robot, KeyEvent.VK_2); + robot.keyPress(KeyEvent.VK_HOME); + robot.keyRelease(KeyEvent.VK_HOME); + robot.keyPress(KeyEvent.VK_2); + robot.keyRelease(KeyEvent.VK_2); - robot.waitForIdle(); + robot.waitForIdle(); - test = getText(); + test = getText(); - if (!"21test".equals(test)) { - throw new RuntimeException("Begin action set cursor inside tag"); + if (!"21test".equals(test)) { + throw new RuntimeException("Begin action set cursor inside tag"); + } + } finally { + if (frame != null) { + SwingUtilities.invokeAndWait(frame::dispose); + } } } @@ -95,7 +105,7 @@ public void run() { } private static void createAndShowGUI() { - JFrame frame = new JFrame(); + frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JEditorPane editorPane = new JEditorPane(); @@ -104,6 +114,7 @@ private static void createAndShowGUI() { editorPane.setEditable(true); frame.add(editorPane); frame.pack(); + frame.setLocationRelativeTo(null); frame.setVisible(true); doc = editorPane.getDocument(); editorPane.setCaretPosition(doc.getLength()); diff --git a/test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java b/test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java new file mode 100644 index 00000000000..f38aa0d0629 --- /dev/null +++ b/test/jdk/jdk/nio/zipfs/TestLocOffsetFromZip64EF.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipFile; + +import static java.lang.String.format; + +/** + * @test + * @bug 8255380 + * @summary Test that Zip FS can access the LOC offset from the Zip64 extra field + * @modules jdk.zipfs + * @requires (os.family == "linux") | (os.family == "mac") + * @run testng/manual TestLocOffsetFromZip64EF + */ +public class TestLocOffsetFromZip64EF { + + private static final String ZIP_FILE_NAME = "LargeZipTest.zip"; + // File that will be created with a size greater than 0xFFFFFFFF + private static final String LARGE_FILE_NAME = "LargeZipEntry.txt"; + // File that will be created with a size less than 0xFFFFFFFF + private static final String SMALL_FILE_NAME = "SmallZipEntry.txt"; + // The size (4GB) of the large file to be created + private static final long LARGE_FILE_SIZE = 4L * 1024L * 1024L * 1024L; + + /** + * Create the files used by this test + * @throws IOException if an error occurs + */ + @BeforeClass + public void setUp() throws IOException { + System.out.println("In setup"); + cleanup(); + createFiles(); + createZipWithZip64Ext(); + } + + /** + * Delete files used by this test + * @throws IOException if an error occurs + */ + @AfterClass + public void cleanup() throws IOException { + System.out.println("In cleanup"); + Files.deleteIfExists(Path.of(ZIP_FILE_NAME)); + Files.deleteIfExists(Path.of(LARGE_FILE_NAME)); + Files.deleteIfExists(Path.of(SMALL_FILE_NAME)); + } + + /** + * Create a Zip file that will result in the an Zip64 Extra (EXT) header + * being added to the CEN entry in order to find the LOC offset for + * SMALL_FILE_NAME. + */ + public static void createZipWithZip64Ext() { + System.out.println("Executing zip..."); + List commands = List.of("zip", "-0", ZIP_FILE_NAME, + LARGE_FILE_NAME, SMALL_FILE_NAME); + Result rc = run(new ProcessBuilder(commands)); + rc.assertSuccess(); + } + + /** + * Navigate through the Zip file entries using Zip FS + * @throws IOException if an error occurs + */ + @Test + public void walkZipFSTest() throws IOException { + try (FileSystem fs = + FileSystems.newFileSystem(Paths.get(ZIP_FILE_NAME), Map.of("zipinfo-time", "False"))) { + for (Path root : fs.getRootDirectories()) { + Files.walkFileTree(root, new SimpleFileVisitor<>() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes + attrs) throws IOException { + System.out.println(Files.readAttributes(file, + BasicFileAttributes.class).toString()); + return FileVisitResult.CONTINUE; + } + }); + } + } + } + + /** + * Navigate through the Zip file entries using ZipFile + * @throws IOException if an error occurs + */ + @Test + public void walkZipFileTest() throws IOException { + try (ZipFile zip = new ZipFile(ZIP_FILE_NAME)) { + zip.stream().forEach(z -> System.out.printf("%s, %s, %s%n", + z.getName(), z.getMethod(), z.getLastModifiedTime())); + } + } + + /** + * Create the files that will be added to the ZIP file + * @throws IOException if there is a problem creating the files + */ + private static void createFiles() throws IOException { + try (RandomAccessFile file = new RandomAccessFile(LARGE_FILE_NAME, "rw") + ) { + System.out.printf("Creating %s%n", LARGE_FILE_NAME); + file.setLength(LARGE_FILE_SIZE); + System.out.printf("Creating %s%n", SMALL_FILE_NAME); + Files.writeString(Path.of(SMALL_FILE_NAME), "Hello"); + } + } + + /** + * Utility method to execute a ProcessBuilder command + * @param pb ProcessBuilder to execute + * @return The Result(s) from the ProcessBuilder execution + */ + private static Result run(ProcessBuilder pb) { + Process p; + System.out.printf("Running: %s%n", pb.command()); + try { + p = pb.start(); + } catch (IOException e) { + throw new RuntimeException( + format("Couldn't start process '%s'", pb.command()), e); + } + + String output; + try { + output = toString(p.getInputStream(), p.getErrorStream()); + } catch (IOException e) { + throw new RuntimeException( + format("Couldn't read process output '%s'", pb.command()), e); + } + + try { + p.waitFor(); + } catch (InterruptedException e) { + throw new RuntimeException( + format("Process hasn't finished '%s'", pb.command()), e); + } + return new Result(p.exitValue(), output); + } + + /** + * Utility Method for combining the output from a ProcessBuilder invocation + * @param in1 ProccessBuilder.getInputStream + * @param in2 ProcessBuilder.getErrorStream + * @return The ProcessBuilder output + * @throws IOException if an error occurs + */ + static String toString(InputStream in1, InputStream in2) throws IOException { + try (ByteArrayOutputStream dst = new ByteArrayOutputStream(); + InputStream concatenated = new SequenceInputStream(in1, in2)) { + concatenated.transferTo(dst); + return new String(dst.toByteArray(), StandardCharsets.UTF_8); + } + } + + /** + * Utility class used to hold the results from a ProcessBuilder execution + */ + static class Result { + final int ec; + final String output; + + private Result(int ec, String output) { + this.ec = ec; + this.output = output; + } + Result assertSuccess() { + assertTrue(ec == 0, "Expected ec 0, got: ", ec, " , output [", output, "]"); + return this; + } + } + static void assertTrue(boolean cond, Object ... failedArgs) { + if (cond) + return; + StringBuilder sb = new StringBuilder(); + for (Object o : failedArgs) + sb.append(o); + Assert.fail(sb.toString()); + } +} diff --git a/test/jdk/jdk/security/jarsigner/Properties.java b/test/jdk/jdk/security/jarsigner/Properties.java index c96a6c3731e..05c50c16979 100644 --- a/test/jdk/jdk/security/jarsigner/Properties.java +++ b/test/jdk/jdk/security/jarsigner/Properties.java @@ -75,15 +75,10 @@ public static void main(String[] args) throws Exception { Asserts.assertTrue(sf.startsWith("Signature-Version")); // There is a SignedAttributes - byte[] d0 = sign(jsb.setProperty("directsign", "false")); + byte[] d0 = sign(jsb); Asserts.assertTrue(DerUtils.innerDerValue(d0, "10403") .isContextSpecific((byte)0)); - // There is no SignedAttributes - byte[] d1 = sign(jsb.setProperty("directsign", "true")); - Asserts.assertFalse(DerUtils.innerDerValue(d1, "10403") - .isContextSpecific((byte)0)); - // Has a hash for the whole manifest byte[] s0 = sign(jsb.setProperty("sectionsonly", "false")); sf = new String(DerUtils.innerDerValue(s0, "10210").getOctetString()); diff --git a/test/jdk/jdk/security/jarsigner/Spec.java b/test/jdk/jdk/security/jarsigner/Spec.java index ae18236d217..b089f4af929 100644 --- a/test/jdk/jdk/security/jarsigner/Spec.java +++ b/test/jdk/jdk/security/jarsigner/Spec.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8056174 8242068 + * @bug 8056174 8242068 8255536 * @summary Make sure JarSigner impl conforms to spec * @library /test/lib * @modules java.base/sun.security.tools.keytool @@ -70,6 +70,9 @@ public static void main(String[] args) throws Exception { sun.security.tools.keytool.Main.main( ("-keystore ks -storepass changeit -keypass changeit -dname" + " CN=DSA -alias d -genkeypair -keyalg dsa").split(" ")); + sun.security.tools.keytool.Main.main( + ("-keystore ks -storepass changeit -keypass changeit -dname" + + " CN=Ed25519 -alias e -genkeypair -keyalg Ed25519").split(" ")); char[] pass = "changeit".toCharArray(); @@ -127,8 +130,6 @@ public static void main(String[] args) throws Exception { iae(()->b1.setProperty("sectionsonly", "OK")); npe(()->b1.setProperty("sectionsonly", null)); npe(()->b1.setProperty("altsigner", null)); - iae(()->b1.setProperty("directsign", "OK")); - npe(()->b1.setProperty("directsign", null)); npe(()->b1.eventHandler(null)); // default values @@ -146,7 +147,6 @@ public static void main(String[] args) throws Exception { assertTrue(js2.getProperty("tsapolicyid") == null); assertTrue(js2.getProperty("internalsf").equals("false")); assertTrue(js2.getProperty("sectionsonly").equals("false")); - assertTrue(js2.getProperty("directsign").equals("false")); assertTrue(js2.getProperty("altsigner") == null); uoe(()->js2.getProperty("invalid")); @@ -163,7 +163,6 @@ public static void main(String[] args) throws Exception { .setProperty("tsapolicyid", "1.2.3.4") .setProperty("internalsf", "true") .setProperty("sectionsonly", "true") - .setProperty("directsign", "true") .setProperty("altsigner", "MyContentSigner") .eventHandler(myeh); JarSigner js3 = b3.build(); @@ -176,7 +175,6 @@ public static void main(String[] args) throws Exception { assertTrue(js3.getProperty("tsapolicyid").equals("1.2.3.4")); assertTrue(js3.getProperty("internalsf").equals("true")); assertTrue(js3.getProperty("sectionsonly").equals("true")); - assertTrue(js3.getProperty("directsign").equals("true")); assertTrue(js3.getProperty("altsigner").equals("MyContentSigner")); assertTrue(js3.getProperty("altsignerpath") == null); @@ -208,6 +206,14 @@ public static void main(String[] args) throws Exception { assertTrue(JarSigner.Builder .getDefaultSignatureAlgorithm(kpg.generateKeyPair().getPrivate()) .equals("SHA512withECDSA")); + + // altsigner does not support modern algorithms + JarSigner.Builder b4 = new JarSigner.Builder( + (PrivateKey)ks.getKey("e", pass), + CertificateFactory.getInstance("X.509") + .generateCertPath(Arrays.asList(ks.getCertificateChain("e")))); + b4.setProperty("altsigner", "MyContentSigner"); + iae(() -> b4.build()); } interface RunnableWithException { diff --git a/test/jdk/sun/net/ftp/TestFtpTimeValue.java b/test/jdk/sun/net/ftp/TestFtpTimeValue.java index 4179afe77fd..e51837db238 100644 --- a/test/jdk/sun/net/ftp/TestFtpTimeValue.java +++ b/test/jdk/sun/net/ftp/TestFtpTimeValue.java @@ -28,7 +28,8 @@ * @library /test/lib * @modules java.base/sun.net.ftp * @build jdk.test.lib.Asserts - * @run main TestFtpTimeValue + * @run main/othervm -Duser.timezone=UTC TestFtpTimeValue + * @run main/othervm -Duser.timezone=America/Los_Angeles TestFtpTimeValue */ import jdk.test.lib.Asserts; @@ -61,23 +62,24 @@ private enum TestCase { calendar.set(year, month - 1, day, hrs, min, sec); calendar.set(Calendar.MILLISECOND, milliseconds); expectedCreated = calendar.getTime(); - var s = String.format("%4d%2d%2d%2d%2d%2d", year, month, day, hrs, min, sec); + var s = String.format("%4d%02d%02d%02d%02d%02d", year, month, day, hrs, min, sec); if (milliseconds != 0) { - s += "." + String.format("%3d", milliseconds); + s += "." + String.format("%03d", milliseconds); } create = s; calendar.add(GregorianCalendar.SECOND, 1); expectedModified = calendar.getTime(); - s = String.format("%4d%2d%2d%2d%2d%2d", year, month, day, hrs, min, sec + 1); + s = String.format("%4d%02d%02d%02d%02d%02d", year, month, day, hrs, min, sec + 1); if (milliseconds != 0) { - s += "." + String.format("%3d", milliseconds); + s += "." + String.format("%03d", milliseconds); } modify = s; } } public static void main(String[] args) throws Exception { + System.out.println("user.timezone: " + System.getProperty("user.timezone")); try (FtpServer server = new FtpServer(); FtpClient client = FtpClient.create()) { (new Thread(server)).start(); diff --git a/test/jdk/sun/security/mscapi/VeryLongAlias.java b/test/jdk/sun/security/mscapi/VeryLongAlias.java index dfdf5eb508b..b7649f8eaf4 100644 --- a/test/jdk/sun/security/mscapi/VeryLongAlias.java +++ b/test/jdk/sun/security/mscapi/VeryLongAlias.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8223063 + * @bug 8223063 8153005 * @requires os.family == "windows" * @library /test/lib * @summary Support CNG RSA keys @@ -48,7 +48,11 @@ public class VeryLongAlias { public static void main(String[] args) throws Throwable { - SecurityTools.keytool("-genkeypair -storetype pkcs12 -keystore ks" + // Using the old algorithms to make sure the file is recognized + // by the certutil command on old versions of Windows. + SecurityTools.keytool( + "-J-Dkeystore.pkcs12.legacy" + + " -genkeypair -storetype pkcs12 -keystore ks" + " -storepass changeit -keyalg RSA -dname CN=A -alias " + alias); String id = ((X509Certificate)KeyStore.getInstance( diff --git a/test/jdk/sun/security/pkcs/pkcs7/TwoHash.java b/test/jdk/sun/security/pkcs/pkcs7/TwoHash.java new file mode 100644 index 00000000000..6aaf7825c26 --- /dev/null +++ b/test/jdk/sun/security/pkcs/pkcs7/TwoHash.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8255494 + * @summary Make sure the signature algorithm to verify a PKCS7 block is + * DIGwithENC instead of HASHwithENC. + * @modules java.base/sun.security.pkcs + * java.base/sun.security.tools.keytool + * java.base/sun.security.x509 + */ + +import sun.security.pkcs.PKCS7; +import sun.security.tools.keytool.CertAndKeyGen; +import sun.security.x509.X500Name; + +import java.nio.charset.StandardCharsets; +import java.security.cert.X509Certificate; + +public class TwoHash { + public static void main(String[] args) throws Exception { + + byte[] content = "Hello You fool I love you".getBytes(); + + CertAndKeyGen cak = new CertAndKeyGen("EC", "SHA512withECDSA"); + cak.generate("secp256r1"); + byte[] signature = PKCS7.generateNewSignedData( + "SHA256withECDSA", + null, + cak.getPrivateKey(), + new X509Certificate[] {cak.getSelfCertificate(new X500Name("CN=Me"), 1000)}, + content, + false, + true, // direct sign, so that RFC 6211 check is not possible + null); + + // The original signature should verify. + if (new PKCS7(signature).verify(content) == null) { + throw new RuntimeException("Should be verified"); + } + + // Modify the SHA256withECDSA signature algorithm (OID encoded as + // "06 08 2A 86 48 CE 3D 04 03 02") to SHA384withECDSA (OID encoded as + // "06 08 2A 86 48 CE 3D 04 03 03"). ISO_8859_1 charset is chosen + // because it's a strictly one byte per char encoding. + String s = new String(signature, StandardCharsets.ISO_8859_1); + String s1 = s.replace( + "\u0006\u0008\u002A\u0086\u0048\u00CE\u003D\u0004\u0003\u0002", + "\u0006\u0008\u002A\u0086\u0048\u00CE\u003D\u0004\u0003\u0003"); + byte[] modified = s1.getBytes(StandardCharsets.ISO_8859_1); + + // The modified signature should still verify because the HASH + // part of signature algorithm is ignored. + if (new PKCS7(modified).verify(content) == null) { + throw new RuntimeException("Should be verified"); + } + } +} diff --git a/test/jdk/sun/security/pkcs12/ParamsPreferences.java b/test/jdk/sun/security/pkcs12/ParamsPreferences.java index 3c87e045120..06f066897d0 100644 --- a/test/jdk/sun/security/pkcs12/ParamsPreferences.java +++ b/test/jdk/sun/security/pkcs12/ParamsPreferences.java @@ -22,217 +22,247 @@ */ import jdk.test.lib.SecurityTools; -import sun.security.util.ObjectIdentifier; +import sun.security.util.KnownOIDs; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Map; import static jdk.test.lib.security.DerUtils.*; -import static sun.security.pkcs.ContentInfo.DATA_OID; -import static sun.security.pkcs.ContentInfo.ENCRYPTED_DATA_OID; -import sun.security.util.ObjectIdentifier; -import sun.security.util.KnownOIDs; +import static sun.security.util.KnownOIDs.*; /* * @test - * @bug 8076190 8242151 + * @bug 8076190 8242151 8153005 * @library /test/lib * @modules java.base/sun.security.pkcs * java.base/sun.security.util - * @summary Checks the preferences order of pkcs12 params + * @summary Checks the preferences order of pkcs12 params, whether it's + * a system property or a security property, whether the name has + * "pkcs12" or "PKCS12", whether the legacy property is set. */ public class ParamsPreferences { public static final void main(String[] args) throws Exception { int c = 0; - // with storepass - test(c++, "-", "-", - oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, - oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, - oid(KnownOIDs.SHA_1), 100000); + // default + test(c++, + Map.of(), + Map.of(), + PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000, + PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000, + SHA_256, 10000); + + // legacy settings + test(c++, + Map.of("keystore.pkcs12.legacy", ""), + Map.of(), + PBEWithSHA1AndRC2_40, 50000, + PBEWithSHA1AndDESede, 50000, + SHA_1, 100000); + + // legacy override everything else + test(c++, + Map.of("keystore.pkcs12.legacy", "", + "keystore.pkcs12.certProtectionAlgorithm", "PBEWithHmacSHA256AndAES_128", + "keystore.pkcs12.certPbeIterationCount", 3000, + "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithHmacSHA256AndAES_128", + "keystore.pkcs12.keyPbeIterationCount", 4000, + "keystore.pkcs12.macAlgorithm", "HmacPBESHA384", + "keystore.pkcs12.macIterationCount", 2000), + Map.of(), + PBEWithSHA1AndRC2_40, 50000, + PBEWithSHA1AndDESede, 50000, + SHA_1, 100000); // password-less with system property - test(c++, "keystore.pkcs12.certProtectionAlgorithm", "NONE", - "keystore.pkcs12.macAlgorithm", "NONE", - "-", "-", - null, 0, - oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, - null, 0); + test(c++, + Map.of("keystore.pkcs12.certProtectionAlgorithm", "NONE", + "keystore.pkcs12.macAlgorithm", "NONE"), + Map.of(), + null, + PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000, + null); // password-less with security property - test(c++, "-", - "keystore.pkcs12.certProtectionAlgorithm", "NONE", - "keystore.pkcs12.macAlgorithm", "NONE", - "-", - null, 0, - oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, - null, 0); + test(c++, + Map.of(), + Map.of("keystore.pkcs12.certProtectionAlgorithm", "NONE", + "keystore.pkcs12.macAlgorithm", "NONE"), + null, + PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000, + null); // back to with storepass by overriding security property with system property - test(c++, "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", - "keystore.pkcs12.macAlgorithm", "HmacPBESHA256", - "-", - "keystore.pkcs12.certProtectionAlgorithm", "NONE", - "keystore.pkcs12.macAlgorithm", "NONE", - "-", - oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, - oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, - oid(KnownOIDs.SHA_256), 100000); + test(c++, + Map.of("keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", + "keystore.pkcs12.macAlgorithm", "HmacPBESHA256"), + Map.of("keystore.pkcs12.certProtectionAlgorithm", "NONE", + "keystore.pkcs12.macAlgorithm", "NONE"), + PBEWithSHA1AndDESede, 10000, + PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000, + SHA_256, 10000); // back to with storepass by using "" to force hardcoded default - test(c++, "keystore.pkcs12.certProtectionAlgorithm", "", - "keystore.pkcs12.keyProtectionAlgorithm", "", - "keystore.pkcs12.macAlgorithm", "", - "-", - "keystore.pkcs12.certProtectionAlgorithm", "NONE", - "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", - "keystore.pkcs12.macAlgorithm", "NONE", - "-", - oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, - oid(KnownOIDs.PBEWithSHA1AndDESede), 50000, - oid(KnownOIDs.SHA_1), 100000); + test(c++, + Map.of("keystore.pkcs12.certProtectionAlgorithm", "", + "keystore.pkcs12.keyProtectionAlgorithm", "", + "keystore.pkcs12.macAlgorithm", ""), + Map.of("keystore.pkcs12.certProtectionAlgorithm", "NONE", + "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", + "keystore.pkcs12.macAlgorithm", "NONE"), + PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000, + PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000, + SHA_256, 10000); // change everything with system property - test(c++, "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", - "keystore.pkcs12.certPbeIterationCount", 3000, - "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", - "keystore.pkcs12.keyPbeIterationCount", 4000, - "keystore.pkcs12.macAlgorithm", "HmacPBESHA256", - "keystore.pkcs12.macIterationCount", 2000, - "-", "-", - oid(KnownOIDs.PBEWithSHA1AndDESede), 3000, - oid(KnownOIDs.PBEWithSHA1AndRC2_40), 4000, - oid(KnownOIDs.SHA_256), 2000); + test(c++, + Map.of("keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", + "keystore.pkcs12.certPbeIterationCount", 3000, + "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", + "keystore.pkcs12.keyPbeIterationCount", 4000, + "keystore.pkcs12.macAlgorithm", "HmacPBESHA256", + "keystore.pkcs12.macIterationCount", 2000), + Map.of(), + PBEWithSHA1AndDESede, 3000, + PBEWithSHA1AndRC2_40, 4000, + SHA_256, 2000); // change everything with security property - test(c++, "-", - "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", - "keystore.pkcs12.certPbeIterationCount", 3000, - "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", - "keystore.pkcs12.keyPbeIterationCount", 4000, - "keystore.pkcs12.macAlgorithm", "HmacPBESHA256", - "keystore.pkcs12.macIterationCount", 2000, - "-", - oid(KnownOIDs.PBEWithSHA1AndDESede), 3000, - oid(KnownOIDs.PBEWithSHA1AndRC2_40), 4000, - oid(KnownOIDs.SHA_256), 2000); + test(c++, + Map.of(), + Map.of("keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", + "keystore.pkcs12.certPbeIterationCount", 3000, + "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", + "keystore.pkcs12.keyPbeIterationCount", 4000, + "keystore.pkcs12.macAlgorithm", "HmacPBESHA256", + "keystore.pkcs12.macIterationCount", 2000), + PBEWithSHA1AndDESede, 3000, + PBEWithSHA1AndRC2_40, 4000, + SHA_256, 2000); // override security property with system property - test(c++, "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", - "keystore.pkcs12.certPbeIterationCount", 13000, - "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", - "keystore.pkcs12.keyPbeIterationCount", 14000, - "keystore.pkcs12.macAlgorithm", "HmacPBESHA256", - "keystore.pkcs12.macIterationCount", 12000, - "-", - "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndRC2_40", - "keystore.pkcs12.certPbeIterationCount", 3000, - "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndDESede", - "keystore.pkcs12.keyPbeIterationCount", 4000, - "keystore.pkcs12.macAlgorithm", "HmacPBESHA1", - "keystore.pkcs12.macIterationCount", 2000, - "-", - oid(KnownOIDs.PBEWithSHA1AndDESede), 13000, - oid(KnownOIDs.PBEWithSHA1AndRC2_40), 14000, - oid(KnownOIDs.SHA_256), 12000); + test(c++, + Map.of("keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede", + "keystore.pkcs12.certPbeIterationCount", 13000, + "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", + "keystore.pkcs12.keyPbeIterationCount", 14000, + "keystore.pkcs12.macAlgorithm", "HmacPBESHA256", + "keystore.pkcs12.macIterationCount", 12000), + Map.of("keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndRC2_40", + "keystore.pkcs12.certPbeIterationCount", 3000, + "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndDESede", + "keystore.pkcs12.keyPbeIterationCount", 4000, + "keystore.pkcs12.macAlgorithm", "HmacPBESHA1", + "keystore.pkcs12.macIterationCount", 2000), + PBEWithSHA1AndDESede, 13000, + PBEWithSHA1AndRC2_40, 14000, + SHA_256, 12000); // check keyProtectionAlgorithm old behavior. Preferences of // 4 different settings. - test(c++, "-", - "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", - "-", - oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, - oid(KnownOIDs.PBEWithSHA1AndRC2_128), 50000, - oid(KnownOIDs.SHA_1), 100000); - test(c++, "-", - "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", - "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", - "-", - oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, - oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, - oid(KnownOIDs.SHA_1), 100000); test(c++, - "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128", - "-", - "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", - "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", - "-", - oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, - oid(KnownOIDs.PBEWithSHA1AndRC4_128), 50000, - oid(KnownOIDs.SHA_1), 100000); + Map.of(), + Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128"), + PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000, + PBEWithSHA1AndRC2_128, 10000, + SHA_256, 10000); test(c++, - "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128", - "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_40", - "-", - "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", - "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40", - "-", - oid(KnownOIDs.PBEWithSHA1AndRC2_40), 50000, - oid(KnownOIDs.PBEWithSHA1AndRC4_40), 50000, - oid(KnownOIDs.SHA_1), 100000); - } - - private static ObjectIdentifier oid(KnownOIDs o) { - return ObjectIdentifier.of(o); + Map.of(), + Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", + "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40"), + PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000, + PBEWithSHA1AndRC2_40, 10000, + SHA_256, 10000); + test(c++, + Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128"), + Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", + "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40"), + PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000, + PBEWithSHA1AndRC4_128, 10000, + SHA_256, 10000); + test(c++, + Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128", + "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_40"), + Map.of("keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128", + "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40"), + PBES2, HmacSHA256, AES_256$CBC$NoPadding, 10000, + PBEWithSHA1AndRC4_40, 10000, + SHA_256, 10000); } /** * Run once. * - * @param args an array containing system properties and values, "-", - * security properties and values, "-", expected certPbeAlg, - * certPbeIC, keyPbeAlg, keyPbeIc, macAlg, macIC. + * @param sysProps system properties + * @param secProps security properties + * @param args an array expected certPbeAlg (sub algs), certPbeIC, + * keyPbeAlg (sub algs), keyPbeIc, macAlg, macIC. */ - static void test(int n, Object... args) throws Exception { - boolean isSysProp = true; + static void test(int n, Map sysProps, + Map secProps, + Object... args) throws Exception { + String cmd = "-keystore ks" + n + " -genkeypair -keyalg EC " + "-alias a -dname CN=A -storepass changeit " + "-J-Djava.security.properties=" + n + ".conf"; + + for (var p : sysProps.entrySet()) { + cmd += " -J-D" + p.getKey() + "=" + p.getValue(); + } + List jsConf = new ArrayList<>(); - for (int i = 0; i < args.length; i++) { - if (isSysProp) { - if (args[i].equals("-")) { - isSysProp = false; - } else { - cmd += " -J-D" + args[i] + "=" + args[++i]; - } + for (var p : secProps.entrySet()) { + jsConf.add(p.getKey() + "=" + p.getValue()); + } + Files.write(Path.of(n + ".conf"), jsConf); + System.out.println("--------- test starts ----------"); + System.out.println(jsConf); + SecurityTools.keytool(cmd).shouldHaveExitValue(0); + + int i = 0; + byte[] data = Files.readAllBytes(Path.of("ks" + n)); + + // cert pbe alg + ic + KnownOIDs certAlg = (KnownOIDs)args[i++]; + if (certAlg == null) { + checkAlg(data, "110c10", Data); + } else { + checkAlg(data, "110c10", EncryptedData); + checkAlg(data, "110c110110", certAlg); + if (certAlg == PBES2) { + checkAlg(data, "110c11011100", PBKDF2WithHmacSHA1); + checkAlg(data, "110c1101110130", args[i++]); + checkAlg(data, "110c11011110", args[i++]); + checkInt(data, "110c110111011", (int) args[i++]); } else { - if (args[i] == "-") { - Files.write(Path.of(n + ".conf"), jsConf); - System.out.println("--------- test starts ----------"); - System.out.println(jsConf); - SecurityTools.keytool(cmd).shouldHaveExitValue(0); - - byte[] data = Files.readAllBytes(Path.of("ks" + n)); - - // cert pbe alg + ic - if (args[i+1] == null) { - checkAlg(data, "110c10", DATA_OID); - } else { - checkAlg(data, "110c10", ENCRYPTED_DATA_OID); - checkAlg(data, "110c110110", (ObjectIdentifier)args[i+1]); - checkInt(data, "110c1101111", (int)args[i+2]); - } - - // key pbe alg + ic - checkAlg(data, "110c010c01000", (ObjectIdentifier)args[i+3]); - checkInt(data, "110c010c010011", (int)args[i+4]); - - // mac alg + ic - if (args[i+5] == null) { - shouldNotExist(data, "2"); - } else { - checkAlg(data, "2000", (ObjectIdentifier)args[i+5]); - checkInt(data, "22", (int)args[i+6]); - } - } else { - jsConf.add(args[i] + "=" + args[++i]); - } + checkInt(data, "110c1101111", (int) args[i++]); } } + + // key pbe alg + ic + KnownOIDs keyAlg = (KnownOIDs)args[i++]; + checkAlg(data, "110c010c01000", keyAlg); + if (keyAlg == PBES2) { + checkAlg(data, "110c010c0100100", PBKDF2WithHmacSHA1); + checkAlg(data, "110c010c010010130", args[i++]); + checkAlg(data, "110c010c0100110", args[i++]); + checkInt(data, "110c010c01001011", (int) args[i++]); + } else { + checkInt(data, "110c010c010011", (int) args[i++]); + } + + // mac alg + ic + KnownOIDs macAlg = (KnownOIDs)args[i++]; + if (macAlg == null) { + shouldNotExist(data, "2"); + } else { + checkAlg(data, "2000", macAlg); + checkInt(data, "22", (int) args[i++]); + } } } diff --git a/test/jdk/sun/security/pkcs12/ParamsTest.java b/test/jdk/sun/security/pkcs12/ParamsTest.java index 54910f47cb6..d292a7e563e 100644 --- a/test/jdk/sun/security/pkcs12/ParamsTest.java +++ b/test/jdk/sun/security/pkcs12/ParamsTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8076190 8242151 + * @bug 8076190 8242151 8153005 * @library /test/lib * @modules java.base/sun.security.pkcs * java.base/sun.security.util @@ -41,6 +41,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.UncheckedIOException; +import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.security.KeyStore; @@ -48,8 +49,7 @@ import java.util.Objects; import static jdk.test.lib.security.DerUtils.*; -import sun.security.util.ObjectIdentifier; -import sun.security.util.KnownOIDs; +import static sun.security.util.KnownOIDs.*; import static sun.security.pkcs.ContentInfo.*; public class ParamsTest { @@ -57,15 +57,18 @@ public class ParamsTest { public static void main(String[] args) throws Throwable { // De-BASE64 textual files in ./params to `pwd` - Files.newDirectoryStream(Path.of(System.getProperty("test.src"), "params")) - .forEach(p -> { - try (InputStream is = Files.newInputStream(p); - OutputStream os = Files.newOutputStream(p.getFileName())){ - Base64.getMimeDecoder().wrap(is).transferTo(os); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - }); + try (DirectoryStream stream = Files.newDirectoryStream( + Path.of(System.getProperty("test.src"), "params"), + p -> !p.getFileName().toString().equals("README"))) { + stream.forEach(p -> { + try (InputStream is = Files.newInputStream(p); + OutputStream os = Files.newOutputStream(p.getFileName())) { + Base64.getMimeDecoder().wrap(is).transferTo(os); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + } byte[] data; @@ -100,34 +103,44 @@ public static void main(String[] args) throws Throwable { // Current default pkcs12 setting keytool("-importkeystore -srckeystore ks -srcstorepass changeit " + "-destkeystore ksnormal -deststorepass changeit"); + data = Files.readAllBytes(Path.of("ksnormal")); - checkInt(data, "22", 100000); // Mac ic - checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg - checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg - checkInt(data, "110c010c010011", 50000); // key ic + checkInt(data, "22", 10000); // Mac ic + checkAlg(data, "2000", SHA_256); // Mac alg + checkAlg(data, "110c010c01000", PBES2); // key alg + checkInt(data, "110c010c01001011", 10000); // key ic checkAlg(data, "110c10", ENCRYPTED_DATA_OID); - checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg - checkInt(data, "110c1101111", 50000); // cert ic - + checkAlg(data, "110c110110", PBES2); // cert alg check("ksnormal", "a", "changeit", "changeit", true, true, true); check("ksnormal", "a", null, "changeit", true, false, true); check("ksnormal", "a", "wrongpass", "-", IOException.class, "-", "-"); + // Import it into a new keystore with legacy algorithms + keytool("-importkeystore -srckeystore ksnormal -srcstorepass changeit " + + "-destkeystore kslegacyimp -deststorepass changeit " + + "-J-Dkeystore.pkcs12.legacy"); + data = Files.readAllBytes(Path.of("kslegacyimp")); + checkInt(data, "22", 100000); // Mac ic + checkAlg(data, "2000", SHA_1); // Mac alg + checkAlg(data, "110c010c01000", PBEWithSHA1AndDESede); // key alg + checkInt(data, "110c010c010011", 50000); // key ic + checkAlg(data, "110c110110", PBEWithSHA1AndRC2_40); // cert alg + checkInt(data, "110c1101111", 50000); // cert ic + // Add a new entry with password-less settings, still has a storepass keytool("-keystore ksnormal -genkeypair -keyalg DSA " + "-storepass changeit -alias b -dname CN=b " + "-J-Dkeystore.pkcs12.certProtectionAlgorithm=NONE " + "-J-Dkeystore.pkcs12.macAlgorithm=NONE"); data = Files.readAllBytes(Path.of("ksnormal")); - checkInt(data, "22", 100000); // Mac ic - checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg - checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg - checkInt(data, "110c010c010011", 50000); // key ic - checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // new key alg - checkInt(data, "110c010c110011", 50000); // new key ic + checkInt(data, "22", 10000); // Mac ic + checkAlg(data, "2000", SHA_256); // Mac alg + checkAlg(data, "110c010c01000", PBES2); // key alg + checkInt(data, "110c010c01001011", 10000); // key ic + checkAlg(data, "110c010c11000", PBES2); // new key alg + checkInt(data, "110c010c11001011", 10000); // new key ic checkAlg(data, "110c10", ENCRYPTED_DATA_OID); - checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg - checkInt(data, "110c1101111", 50000); // cert ic + checkAlg(data, "110c110110", PBES2); // cert alg check("ksnormal", "b", null, "changeit", true, false, true); check("ksnormal", "b", "changeit", "changeit", true, true, true); @@ -139,8 +152,8 @@ public static void main(String[] args) throws Throwable { + "-J-Dkeystore.pkcs12.macAlgorithm=NONE"); data = Files.readAllBytes(Path.of("ksnopass")); shouldNotExist(data, "2"); // no Mac - checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); - checkInt(data, "110c010c010011", 50000); + checkAlg(data, "110c010c01000", PBEWithSHA1AndRC4_128); + checkInt(data, "110c010c010011", 10000); checkAlg(data, "110c10", DATA_OID); check("ksnopass", "a", null, "changeit", true, true, true); check("ksnopass", "a", "changeit", "changeit", true, true, true); @@ -151,10 +164,10 @@ public static void main(String[] args) throws Throwable { + "-storepass changeit -alias b -dname CN=B"); data = Files.readAllBytes(Path.of("ksnopass")); shouldNotExist(data, "2"); // no Mac - checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); - checkInt(data, "110c010c010011", 50000); - checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); - checkInt(data, "110c010c110011", 50000); + checkAlg(data, "110c010c01000", PBEWithSHA1AndRC4_128); + checkInt(data, "110c010c010011", 10000); + checkAlg(data, "110c010c11000", PBES2); + checkInt(data, "110c010c11001011", 10000); checkAlg(data, "110c10", DATA_OID); check("ksnopass", "a", null, "changeit", true, true, true); check("ksnopass", "b", null, "changeit", true, true, true); @@ -166,11 +179,11 @@ public static void main(String[] args) throws Throwable { + "-J-Dkeystore.pkcs12.keyPbeIterationCount=7777"); data = Files.readAllBytes(Path.of("ksnewic")); checkInt(data, "22", 5555); // Mac ic - checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg - checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg - checkInt(data, "110c010c010011", 7777); // key ic - checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg - checkInt(data, "110c1101111", 6666); // cert ic + checkAlg(data, "2000", SHA_256); // Mac alg + checkAlg(data, "110c010c01000", PBES2); // key alg + checkInt(data, "110c010c01001011", 7777); // key ic + checkAlg(data, "110c110110", PBES2); // cert alg + checkInt(data, "110c110111011", 6666); // cert ic // keypbe alg cannot be NONE keytool("-keystore ksnewic -genkeypair -keyalg DSA " @@ -185,13 +198,13 @@ public static void main(String[] args) throws Throwable { + "-J-Dkeystore.pkcs12.keyProtectionAlgorithm=PBEWithSHA1AndRC4_128"); data = Files.readAllBytes(Path.of("ksnewic")); checkInt(data, "22", 5555); // Mac ic - checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg - checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg - checkInt(data, "110c010c010011", 7777); // key ic - checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); // new key alg - checkInt(data, "110c010c110011", 50000); // new key ic - checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg - checkInt(data, "110c1101111", 6666); // cert ic + checkAlg(data, "2000", SHA_256); // Mac alg + checkAlg(data, "110c010c01000", PBES2); // key alg + checkInt(data, "110c010c01001011", 7777); // key ic + checkAlg(data, "110c010c11000", PBEWithSHA1AndRC4_128); // new key alg + checkInt(data, "110c010c110011", 10000); // new key ic + checkAlg(data, "110c110110", PBES2); // cert alg + checkInt(data, "110c110111011", 6666); // cert ic // Check KeyStore loading multiple keystores KeyStore ks = KeyStore.getInstance("pkcs12"); @@ -201,15 +214,15 @@ public static void main(String[] args) throws Throwable { ks.store(fos, "changeit".toCharArray()); } data = Files.readAllBytes(Path.of("ksnormaldup")); - checkInt(data, "22", 100000); // Mac ic - checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg - checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg - checkInt(data, "110c010c010011", 50000); // key ic - checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // new key alg - checkInt(data, "110c010c110011", 50000); // new key ic + checkInt(data, "22", 10000); // Mac ic + checkAlg(data, "2000", SHA_256); // Mac alg + checkAlg(data, "110c010c01000", PBES2); // key alg + checkInt(data, "110c010c01001011", 10000); // key ic + checkAlg(data, "110c010c11000", PBES2); // new key alg + checkInt(data, "110c010c11001011", 10000); // new key ic checkAlg(data, "110c10", ENCRYPTED_DATA_OID); - checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg - checkInt(data, "110c1101111", 50000); // cert ic + checkAlg(data, "110c110110", PBES2); // cert alg + checkInt(data, "110c110111011", 10000); // cert ic try (FileInputStream fis = new FileInputStream("ksnopass"); FileOutputStream fos = new FileOutputStream("ksnopassdup")) { @@ -218,10 +231,10 @@ public static void main(String[] args) throws Throwable { } data = Files.readAllBytes(Path.of("ksnopassdup")); shouldNotExist(data, "2"); // no Mac - checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); - checkInt(data, "110c010c010011", 50000); - checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndDESede)); - checkInt(data, "110c010c110011", 50000); + checkAlg(data, "110c010c01000", PBEWithSHA1AndRC4_128); + checkInt(data, "110c010c010011", 10000); + checkAlg(data, "110c010c11000", PBES2); + checkInt(data, "110c010c11001011", 10000); checkAlg(data, "110c10", DATA_OID); try (FileInputStream fis = new FileInputStream("ksnewic"); @@ -231,13 +244,13 @@ public static void main(String[] args) throws Throwable { } data = Files.readAllBytes(Path.of("ksnewicdup")); checkInt(data, "22", 5555); // Mac ic - checkAlg(data, "2000", oid(KnownOIDs.SHA_1)); // Mac alg - checkAlg(data, "110c010c01000", oid(KnownOIDs.PBEWithSHA1AndDESede)); // key alg - checkInt(data, "110c010c010011", 7777); // key ic - checkAlg(data, "110c010c11000", oid(KnownOIDs.PBEWithSHA1AndRC4_128)); // new key alg - checkInt(data, "110c010c110011", 50000); // new key ic - checkAlg(data, "110c110110", oid(KnownOIDs.PBEWithSHA1AndRC2_40)); // cert alg - checkInt(data, "110c1101111", 6666); // cert ic + checkAlg(data, "2000", SHA_256); // Mac alg + checkAlg(data, "110c010c01000", PBES2); // key alg + checkInt(data, "110c010c01001011", 7777); // key ic + checkAlg(data, "110c010c11000", PBEWithSHA1AndRC4_128); // new key alg + checkInt(data, "110c010c110011", 10000); // new key ic + checkAlg(data, "110c110110", PBES2); // cert alg + checkInt(data, "110c110111011", 6666); // cert ic // Check keytool behavior @@ -434,10 +447,6 @@ private static void check( Asserts.assertEQ(expectedKey, actualKey, label + "-key"); } - private static ObjectIdentifier oid(KnownOIDs o) { - return ObjectIdentifier.of(o); - } - static OutputAnalyzer keytool(String s) throws Throwable { return SecurityTools.keytool(s); } diff --git a/test/jdk/sun/security/pkcs12/params/README b/test/jdk/sun/security/pkcs12/params/README index 0fcd17d7c05..eca9e1b8d8a 100644 --- a/test/jdk/sun/security/pkcs12/params/README +++ b/test/jdk/sun/security/pkcs12/params/README @@ -1,8 +1,10 @@ 1. Preparing data in this directory +Do not use OpenSSL 3.0.0. The default algorithms for pkcs12 are changed. +( mkdir tmp cd tmp -keytool -keystore ks -genkeypair -storepass changeit -alias a -dname CN=A +keytool -keystore ks -keyalg ec -genkeypair -storepass changeit -alias a -dname CN=A openssl pkcs12 -in ks -nodes -out kandc -passin pass:changeit openssl pkcs12 -export -in kandc -out os2 -name a -passout pass:changeit \ -certpbe NONE -nomac @@ -17,37 +19,38 @@ for a in *; do done cd .. rm -rf tmp +) 2. After running the test, we can go to the scratch directory and run the following commands to check keytool -> openssl interoperability. OpenSSL 1.1.0i is used here. Earlier versions might generate different info. ( -openssl pkcs12 -in ks2 -passin pass:changeit -info -nokeys -nocerts 2> t2 || exit 20 -grep "MAC:sha1 Iteration 100000" t2 || exit 21 -grep "Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 50000" t2 || exit 23 -grep "PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 50000" t2 || exit 24 +openssl pkcs12 -in ksnormal -passin pass:changeit -info -nokeys -nocerts 2> t2 || exit 20 +grep "MAC: sha256, Iteration 10000" t2 || exit 21 +grep "Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256" t2 || exit 23 +grep "PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256" t2 || exit 24 -openssl pkcs12 -in ks22 -passin pass:changeit -info -nokeys -nocerts 2> t22 || exit 25 +openssl pkcs12 -in ksnormaldup -passin pass:changeit -info -nokeys -nocerts 2> t22 || exit 25 diff t2 t22 || exit 26 -openssl pkcs12 -in ks3 -passin pass:changeit -info -nokeys -nocerts && exit 30 +openssl pkcs12 -in ksnopass -passin pass:changeit -info -nokeys -nocerts && exit 30 -openssl pkcs12 -in ks3 -passin pass:changeit -info -nokeys -nocerts -nomacver 2> t3 || exit 31 +openssl pkcs12 -in ksnopass -passin pass:changeit -info -nokeys -nocerts -nomacver 2> t3 || exit 31 grep "PKCS7 Encrypted data:" t3 && exit 33 -grep "Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 50000" t3 || exit 34 -grep "Shrouded Keybag: pbeWithSHA1And128BitRC4, Iteration 50000" t3 || exit 35 +grep "Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256" t3 || exit 34 +grep "Shrouded Keybag: pbeWithSHA1And128BitRC4, Iteration 10000" t3 || exit 35 -openssl pkcs12 -in ks33 -passin pass:changeit -info -nokeys -nocerts -nomacver 2> t33 || exit 36 +openssl pkcs12 -in ksnopassdup -passin pass:changeit -info -nokeys -nocerts -nomacver 2> t33 || exit 36 diff t3 t33 || exit 37 -openssl pkcs12 -in ks4 -passin pass:changeit -info -nokeys -nocerts 2> t4 || exit 40 -grep "MAC:sha1 Iteration 5555" t4 || exit 41 -grep "Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 7777" t4 || exit 43 -grep "Shrouded Keybag: pbeWithSHA1And128BitRC4, Iteration 50000" t4 || exit 44 -grep "PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 6666" t4 || exit 45 +openssl pkcs12 -in ksnewic -passin pass:changeit -info -nokeys -nocerts 2> t4 || exit 40 +grep "MAC: sha256, Iteration 5555" t4 || exit 41 +grep "Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 7777, PRF hmacWithSHA256" t4 || exit 43 +grep "Shrouded Keybag: pbeWithSHA1And128BitRC4, Iteration 10000" t4 || exit 44 +grep "PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 6666, PRF hmacWithSHA256" t4 || exit 45 -openssl pkcs12 -in ks44 -passin pass:changeit -info -nokeys -nocerts 2> t44 || exit 46 +openssl pkcs12 -in ksnewicdup -passin pass:changeit -info -nokeys -nocerts 2> t44 || exit 46 diff t4 t44 || exit 47 echo Succeed diff --git a/test/jdk/sun/security/tools/keytool/GenerateAll.java b/test/jdk/sun/security/tools/keytool/GenerateAll.java index 84fbd0e0d5d..4efc3b0ebc6 100644 --- a/test/jdk/sun/security/tools/keytool/GenerateAll.java +++ b/test/jdk/sun/security/tools/keytool/GenerateAll.java @@ -108,10 +108,9 @@ public void eddsaTest(String keyAlg, String sigAlg, String expected) oa.shouldHaveExitValue(0); kt("-alias " + alias + " -export -file " + alias + ".crt"); byte[] crt = Files.readAllBytes(Path.of(alias + ".crt")); - ObjectIdentifier oid = oid(expected); - DerUtils.checkAlg(crt, "020", oid); // tbsCertificate.signature - DerUtils.checkAlg(crt, "0600", oid); // tbsCertificate.subjectPublicKeyInfo.algorithm - DerUtils.checkAlg(crt, "10", oid); // signatureAlgorithm + DerUtils.checkAlg(crt, "020", expected); // tbsCertificate.signature + DerUtils.checkAlg(crt, "0600", expected); // tbsCertificate.subjectPublicKeyInfo.algorithm + DerUtils.checkAlg(crt, "10", expected); // signatureAlgorithm } } @@ -179,18 +178,18 @@ public void test(String alias, String keyAlg, String sigAlg, String ext, } byte[] crt = read(alias + ".self"); - DerUtils.checkAlg(crt, "020", oid(sigAlg)); // tbsCertificate.signature - DerUtils.checkAlg(crt, "0600", oid(keyAlg)); // tbsCertificate.subjectPublicKeyInfo.algorithm + DerUtils.checkAlg(crt, "020", sigAlg); // tbsCertificate.signature + DerUtils.checkAlg(crt, "0600", keyAlg); // tbsCertificate.subjectPublicKeyInfo.algorithm assertEquals( DerUtils.innerDerValue(crt, "02"), // tbsCertificate.signature DerUtils.innerDerValue(crt, "1")); // signatureAlgorithm byte[] req = read(alias + ".req"); - DerUtils.checkAlg(req, "10", oid(sigAlg)); // signatureAlgorithm - DerUtils.checkAlg(req, "0200", oid(keyAlg)); // certificationRequestInfo.subjectPKInfo.algorithm + DerUtils.checkAlg(req, "10", sigAlg); // signatureAlgorithm + DerUtils.checkAlg(req, "0200", keyAlg); // certificationRequestInfo.subjectPKInfo.algorithm byte[] crl = read(alias + ".crl"); - DerUtils.checkAlg(crl, "000", oid(sigAlg)); // tbsCertList.signature + DerUtils.checkAlg(crl, "000", sigAlg); // tbsCertList.signature assertEquals( DerUtils.innerDerValue(crl, "00"), // tbsCertList.signature DerUtils.innerDerValue(crl, "1")); // signatureAlgorithm @@ -200,13 +199,13 @@ public void test(String alias, String keyAlg, String sigAlg, String ext, "META-INF/" + alias.toUpperCase() + "." + ext); byte[] p7 = jf.getInputStream(je).readAllBytes(); // SignerInfo.digestAlgorithm - DerUtils.checkAlg(p7, "104020", oid(expDigAlg)); + DerUtils.checkAlg(p7, "104020", expDigAlg); // SignerInfo.signatureAlgorithm if (DerUtils.innerDerValue(p7, "10403").isContextSpecific()) { // SignerInfo has signedAttributes at 104030 - DerUtils.checkAlg(p7, "104040", oid(expEncAlg)); + DerUtils.checkAlg(p7, "104040", expEncAlg); } else { - DerUtils.checkAlg(p7, "104030", oid(expEncAlg)); + DerUtils.checkAlg(p7, "104030", expEncAlg); } } } @@ -216,14 +215,6 @@ public void afterTest() throws Exception { js("-verify a.jar -verbose -certs"); } - static ObjectIdentifier oid(String name) { - return ObjectIdentifier.of(KnownOIDs.findMatch(name)); - } - - static ObjectIdentifier oid(KnownOIDs ko) { - return ObjectIdentifier.of(ko); - } - static byte[] read(String f) throws IOException { try (var v = Files.lines(Path.of(f))) { return Base64.getDecoder().decode(v.filter(s -> !s.startsWith("-----")) diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java index 6aaa1375d01..2e60facc8e4 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java @@ -32,7 +32,7 @@ import java.util.Optional; import java.util.function.BiConsumer; import java.util.stream.Stream; -import jdk.incubator.jpackage.internal.ApplicationLayout; +import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.test.Functional.ThrowingBiConsumer; public final class AdditionalLauncher { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java index 732cbb9240f..ceb0dedcb6f 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java @@ -25,7 +25,7 @@ import java.nio.file.Path; import java.util.HashMap; import java.util.Map; -import jdk.incubator.jpackage.internal.IOUtils; +import jdk.jpackage.internal.IOUtils; final public class FileAssociations { 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 b8f10693f82..a164a0728ca 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -46,8 +46,8 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.incubator.jpackage.internal.AppImageFile; -import jdk.incubator.jpackage.internal.ApplicationLayout; +import jdk.jpackage.internal.AppImageFile; +import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.Functional.ThrowingFunction; import jdk.jpackage.test.Functional.ThrowingSupplier; @@ -835,15 +835,6 @@ public static String escapeAndJoin(List args) { }).collect(Collectors.joining(" ")); } - public static Stream filterOutput(Stream jpackageOutput) { - // Skip "WARNING: Using incubator ..." first line of output - return jpackageOutput.skip(1); - } - - public static List filterOutput(List jpackageOutput) { - return filterOutput(jpackageOutput.stream()).collect(Collectors.toList()); - } - @Override protected boolean isMutable() { return !immutable; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java index 4ef62b28fc0..d907a046f22 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java @@ -85,7 +85,7 @@ public static Path getDefaultIcon() { } return TKit.SRC_ROOT.resolve(Path.of(components[0], - "classes/jdk/incubator/jpackage/internal/resources", components[1])); + "classes/jdk/jpackage/internal/resources", components[1])); } private String launcherName; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java index 787f4418f1d..c54ca886567 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java @@ -38,7 +38,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.incubator.jpackage.internal.IOUtils; +import jdk.jpackage.internal.IOUtils; import jdk.jpackage.test.PackageTest.PackageHandlers; 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 0acb196c2ba..f81fb1c170c 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java @@ -43,8 +43,8 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.incubator.jpackage.internal.AppImageFile; -import jdk.incubator.jpackage.internal.ApplicationLayout; +import jdk.jpackage.internal.AppImageFile; +import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.test.Functional.ThrowingBiConsumer; import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.Functional.ThrowingRunnable; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java index 7f9eb811d6e..26a1b7786a4 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java @@ -35,15 +35,15 @@ */ public enum PackageType { WIN_MSI(".msi", - TKit.isWindows() ? "jdk.incubator.jpackage.internal.WinMsiBundler" : null), + TKit.isWindows() ? "jdk.jpackage.internal.WinMsiBundler" : null), WIN_EXE(".exe", - TKit.isWindows() ? "jdk.incubator.jpackage.internal.WinMsiBundler" : null), + TKit.isWindows() ? "jdk.jpackage.internal.WinMsiBundler" : null), LINUX_DEB(".deb", - TKit.isLinux() ? "jdk.incubator.jpackage.internal.LinuxDebBundler" : null), + TKit.isLinux() ? "jdk.jpackage.internal.LinuxDebBundler" : null), LINUX_RPM(".rpm", - TKit.isLinux() ? "jdk.incubator.jpackage.internal.LinuxRpmBundler" : null), - MAC_DMG(".dmg", TKit.isOSX() ? "jdk.incubator.jpackage.internal.MacDmgBundler" : null), - MAC_PKG(".pkg", TKit.isOSX() ? "jdk.incubator.jpackage.internal.MacPkgBundler" : null), + TKit.isLinux() ? "jdk.jpackage.internal.LinuxRpmBundler" : null), + MAC_DMG(".dmg", TKit.isOSX() ? "jdk.jpackage.internal.MacDmgBundler" : null), + MAC_PKG(".pkg", TKit.isOSX() ? "jdk.jpackage.internal.MacPkgBundler" : null), IMAGE("app-image", null, null); PackageType(String packageName, String bundleSuffix, String bundlerClass) { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java index d35539b3f50..4f97752305b 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java @@ -81,7 +81,7 @@ final public class TKit { }).get(); public static final Path SRC_ROOT = Functional.identity(() -> { - return TEST_SRC_ROOT.resolve("../../../../src/jdk.incubator.jpackage").normalize().toAbsolutePath(); + return TEST_SRC_ROOT.resolve("../../../../src/jdk.jpackage").normalize().toAbsolutePath(); }).get(); public final static String ICON_SUFFIX = Functional.identity(() -> { diff --git a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/AppImageFileTest.java b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/AppImageFileTest.java similarity index 99% rename from test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/AppImageFileTest.java rename to test/jdk/tools/jpackage/junit/jdk/jpackage/internal/AppImageFileTest.java index 8168148ef6c..e2b8116d980 100644 --- a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/AppImageFileTest.java +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/AppImageFileTest.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Files; diff --git a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/ApplicationLayoutTest.java b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/ApplicationLayoutTest.java similarity index 98% rename from test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/ApplicationLayoutTest.java rename to test/jdk/tools/jpackage/junit/jdk/jpackage/internal/ApplicationLayoutTest.java index 7ef0a4d15bd..0d8e4a1abfd 100644 --- a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/ApplicationLayoutTest.java +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/ApplicationLayoutTest.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Files; diff --git a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/CompareDottedVersionTest.java b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/CompareDottedVersionTest.java similarity index 98% rename from test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/CompareDottedVersionTest.java rename to test/jdk/tools/jpackage/junit/jdk/jpackage/internal/CompareDottedVersionTest.java index 283bbe26fea..b8057d0e2b4 100644 --- a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/CompareDottedVersionTest.java +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/CompareDottedVersionTest.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.ArrayList; import java.util.List; diff --git a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/DeployParamsTest.java b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/DeployParamsTest.java similarity index 99% rename from test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/DeployParamsTest.java rename to test/jdk/tools/jpackage/junit/jdk/jpackage/internal/DeployParamsTest.java index bfb3d359ef2..cf398a2d6b9 100644 --- a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/DeployParamsTest.java +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/DeployParamsTest.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.nio.file.Path; import java.io.IOException; diff --git a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/DottedVersionTest.java b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/DottedVersionTest.java similarity index 98% rename from test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/DottedVersionTest.java rename to test/jdk/tools/jpackage/junit/jdk/jpackage/internal/DottedVersionTest.java index d6ace3d88b1..fedf153d5dd 100644 --- a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/DottedVersionTest.java +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/DottedVersionTest.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.Collections; import java.util.List; diff --git a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/InvalidDottedVersionTest.java b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/InvalidDottedVersionTest.java similarity index 98% rename from test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/InvalidDottedVersionTest.java rename to test/jdk/tools/jpackage/junit/jdk/jpackage/internal/InvalidDottedVersionTest.java index 71054580332..674a4ac24ef 100644 --- a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/InvalidDottedVersionTest.java +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/InvalidDottedVersionTest.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.util.List; import java.util.stream.Collectors; diff --git a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/OverridableResourceTest.java b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/OverridableResourceTest.java similarity index 98% rename from test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/OverridableResourceTest.java rename to test/jdk/tools/jpackage/junit/jdk/jpackage/internal/OverridableResourceTest.java index 5a9041796b2..a4825c64150 100644 --- a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/OverridableResourceTest.java +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/OverridableResourceTest.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.io.InputStream; @@ -33,7 +33,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import jdk.incubator.jpackage.internal.resources.ResourceLocator; +import jdk.jpackage.internal.resources.ResourceLocator; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertArrayEquals; diff --git a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/PathGroupTest.java b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/PathGroupTest.java similarity index 99% rename from test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/PathGroupTest.java rename to test/jdk/tools/jpackage/junit/jdk/jpackage/internal/PathGroupTest.java index dbd0fd84b45..3a005d10234 100644 --- a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/PathGroupTest.java +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/PathGroupTest.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.io.IOException; import java.nio.file.Files; diff --git a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/PlatformVersionTest.java b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/PlatformVersionTest.java similarity index 96% rename from test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/PlatformVersionTest.java rename to test/jdk/tools/jpackage/junit/jdk/jpackage/internal/PlatformVersionTest.java index 2780d69b8b8..355dc25a2fe 100644 --- a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/PlatformVersionTest.java +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/PlatformVersionTest.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -109,9 +109,9 @@ public void testIt() { private final boolean valid; private final static Function MAC_CFBUNDLE_VERSION_PARSER = findParser( - "jdk.incubator.jpackage.internal.CFBundleVersion"); + "jdk.jpackage.internal.CFBundleVersion"); private final static Function WIN_MSI_PRODUCT_VERSION_PARSER = findParser( - "jdk.incubator.jpackage.internal.MsiVersion"); + "jdk.jpackage.internal.MsiVersion"); private static Function findParser(String className) { try { diff --git a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/ToolValidatorTest.java b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/ToolValidatorTest.java similarity index 98% rename from test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/ToolValidatorTest.java rename to test/jdk/tools/jpackage/junit/jdk/jpackage/internal/ToolValidatorTest.java index adb579b929d..3d0e2b0bb78 100644 --- a/test/jdk/tools/jpackage/junit/jdk/incubator/jpackage/internal/ToolValidatorTest.java +++ b/test/jdk/tools/jpackage/junit/jdk/jpackage/internal/ToolValidatorTest.java @@ -22,7 +22,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.incubator.jpackage.internal; +package jdk.jpackage.internal; import java.nio.file.Path; import static org.hamcrest.CoreMatchers.is; diff --git a/test/jdk/tools/jpackage/junit/junit.java b/test/jdk/tools/jpackage/junit/junit.java index ce9441baf49..1073a572078 100644 --- a/test/jdk/tools/jpackage/junit/junit.java +++ b/test/jdk/tools/jpackage/junit/junit.java @@ -27,6 +27,6 @@ * @test * @summary jpackage unit tests * @library ${jtreg.home}/lib/junit.jar - * @modules jdk.incubator.jpackage + * @modules jdk.jpackage * @run shell run_junit.sh */ diff --git a/test/jdk/tools/jpackage/junit/run_junit.sh b/test/jdk/tools/jpackage/junit/run_junit.sh index 46c588a7077..496ac71a974 100644 --- a/test/jdk/tools/jpackage/junit/run_junit.sh +++ b/test/jdk/tools/jpackage/junit/run_junit.sh @@ -17,10 +17,10 @@ for s in $(find "${TESTSRC}" -name "*.java" | grep -v junit.java); do done common_args=(\ - --add-modules jdk.incubator.jpackage \ - --patch-module jdk.incubator.jpackage="${TESTSRC}${PS}${TESTCLASSES}" \ - --add-reads jdk.incubator.jpackage=ALL-UNNAMED \ - --add-exports jdk.incubator.jpackage/jdk.incubator.jpackage.internal=ALL-UNNAMED \ + --add-modules jdk.jpackage \ + --patch-module jdk.jpackage="${TESTSRC}${PS}${TESTCLASSES}" \ + --add-reads jdk.jpackage=ALL-UNNAMED \ + --add-exports jdk.jpackage/jdk.jpackage.internal=ALL-UNNAMED \ -classpath "${TESTCLASSPATH}" \ ) diff --git a/test/jdk/tools/jpackage/linux/AppCategoryTest.java b/test/jdk/tools/jpackage/linux/AppCategoryTest.java index a4471cebfc9..978beff0c75 100644 --- a/test/jdk/tools/jpackage/linux/AppCategoryTest.java +++ b/test/jdk/tools/jpackage/linux/AppCategoryTest.java @@ -47,7 +47,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m AppCategoryTest */ public class AppCategoryTest { diff --git a/test/jdk/tools/jpackage/linux/LicenseTypeTest.java b/test/jdk/tools/jpackage/linux/LicenseTypeTest.java index 811288c33fa..7462c3d1766 100644 --- a/test/jdk/tools/jpackage/linux/LicenseTypeTest.java +++ b/test/jdk/tools/jpackage/linux/LicenseTypeTest.java @@ -42,7 +42,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m LicenseTypeTest */ public class LicenseTypeTest { diff --git a/test/jdk/tools/jpackage/linux/LinuxBundleNameTest.java b/test/jdk/tools/jpackage/linux/LinuxBundleNameTest.java index 5e3cf3a6421..be502d10a60 100644 --- a/test/jdk/tools/jpackage/linux/LinuxBundleNameTest.java +++ b/test/jdk/tools/jpackage/linux/LinuxBundleNameTest.java @@ -47,7 +47,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m LinuxBundleNameTest */ public class LinuxBundleNameTest { diff --git a/test/jdk/tools/jpackage/linux/LinuxResourceTest.java b/test/jdk/tools/jpackage/linux/LinuxResourceTest.java index 30f6e0b1203..9f4e4cfad2f 100644 --- a/test/jdk/tools/jpackage/linux/LinuxResourceTest.java +++ b/test/jdk/tools/jpackage/linux/LinuxResourceTest.java @@ -36,7 +36,7 @@ * @library ../helpers * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile LinuxResourceTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=LinuxResourceTest diff --git a/test/jdk/tools/jpackage/linux/MaintainerTest.java b/test/jdk/tools/jpackage/linux/MaintainerTest.java index 51ffb359385..82f433a6341 100644 --- a/test/jdk/tools/jpackage/linux/MaintainerTest.java +++ b/test/jdk/tools/jpackage/linux/MaintainerTest.java @@ -43,7 +43,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m MaintainerTest */ public class MaintainerTest { diff --git a/test/jdk/tools/jpackage/linux/PackageDepsTest.java b/test/jdk/tools/jpackage/linux/PackageDepsTest.java index 03066b49c12..457d8f01592 100644 --- a/test/jdk/tools/jpackage/linux/PackageDepsTest.java +++ b/test/jdk/tools/jpackage/linux/PackageDepsTest.java @@ -50,7 +50,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile PackageDepsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=PackageDepsTest diff --git a/test/jdk/tools/jpackage/linux/ReleaseTest.java b/test/jdk/tools/jpackage/linux/ReleaseTest.java index c9197874c94..ed79cd6e184 100644 --- a/test/jdk/tools/jpackage/linux/ReleaseTest.java +++ b/test/jdk/tools/jpackage/linux/ReleaseTest.java @@ -46,7 +46,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m ReleaseTest */ public class ReleaseTest { diff --git a/test/jdk/tools/jpackage/linux/ShortcutHintTest.java b/test/jdk/tools/jpackage/linux/ShortcutHintTest.java index 3715d98fc96..812a1941333 100644 --- a/test/jdk/tools/jpackage/linux/ShortcutHintTest.java +++ b/test/jdk/tools/jpackage/linux/ShortcutHintTest.java @@ -58,7 +58,7 @@ * @requires jpackage.test.SQETest == null * @build jdk.jpackage.test.* * @requires (os.family == "linux") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile ShortcutHintTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=ShortcutHintTest @@ -72,7 +72,7 @@ * @build jdk.jpackage.test.* * @requires (os.family == "linux") * @requires jpackage.test.SQETest != null - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile ShortcutHintTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=ShortcutHintTest.testBasic diff --git a/test/jdk/tools/jpackage/linux/jdk/jpackage/tests/UsrTreeTest.java b/test/jdk/tools/jpackage/linux/jdk/jpackage/tests/UsrTreeTest.java index 7a349175f0e..13237cc5aa3 100644 --- a/test/jdk/tools/jpackage/linux/jdk/jpackage/tests/UsrTreeTest.java +++ b/test/jdk/tools/jpackage/linux/jdk/jpackage/tests/UsrTreeTest.java @@ -45,7 +45,7 @@ * @requires jpackage.test.SQETest == null * @requires (os.family == "linux") * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile UsrTreeTest.java * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main * --jpt-run=UsrTreeTest diff --git a/test/jdk/tools/jpackage/macosx/MacFileAssociationsTest.java b/test/jdk/tools/jpackage/macosx/MacFileAssociationsTest.java index b2d3a7ea9a2..eb21419c3b3 100644 --- a/test/jdk/tools/jpackage/macosx/MacFileAssociationsTest.java +++ b/test/jdk/tools/jpackage/macosx/MacFileAssociationsTest.java @@ -41,7 +41,7 @@ * @summary jpackage with --file-associations and mac specific file association args * @library ../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @requires (os.family == "mac") * @run main/othervm -Xmx512m MacFileAssociationsTest */ diff --git a/test/jdk/tools/jpackage/macosx/MacPropertiesTest.java b/test/jdk/tools/jpackage/macosx/MacPropertiesTest.java index 3051a44d7a3..9d4324e2222 100644 --- a/test/jdk/tools/jpackage/macosx/MacPropertiesTest.java +++ b/test/jdk/tools/jpackage/macosx/MacPropertiesTest.java @@ -38,7 +38,7 @@ * @library ../helpers * @build jdk.jpackage.test.* * @requires (os.family == "mac") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile MacPropertiesTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=MacPropertiesTest diff --git a/test/jdk/tools/jpackage/macosx/NameWithSpaceTest.java b/test/jdk/tools/jpackage/macosx/NameWithSpaceTest.java index 3168bb24090..ac505e5ca81 100644 --- a/test/jdk/tools/jpackage/macosx/NameWithSpaceTest.java +++ b/test/jdk/tools/jpackage/macosx/NameWithSpaceTest.java @@ -40,7 +40,7 @@ * @summary jpackage test with name containing spaces * @library ../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile NameWithSpaceTest.java * @requires (os.family == "mac") * @key jpackagePlatformPackage diff --git a/test/jdk/tools/jpackage/macosx/SigningAppImageTest.java b/test/jdk/tools/jpackage/macosx/SigningAppImageTest.java index ae07d38a5fd..b0f5f6e028f 100644 --- a/test/jdk/tools/jpackage/macosx/SigningAppImageTest.java +++ b/test/jdk/tools/jpackage/macosx/SigningAppImageTest.java @@ -49,7 +49,7 @@ * @build SigningCheck * @build jtreg.SkippedException * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @requires (os.family == "mac") * @run main/othervm -Xmx512m SigningAppImageTest */ diff --git a/test/jdk/tools/jpackage/macosx/SigningPackageTest.java b/test/jdk/tools/jpackage/macosx/SigningPackageTest.java index af7981a291b..660a828a121 100644 --- a/test/jdk/tools/jpackage/macosx/SigningPackageTest.java +++ b/test/jdk/tools/jpackage/macosx/SigningPackageTest.java @@ -54,7 +54,7 @@ * @build SigningCheck * @build jtreg.SkippedException * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @requires (os.family == "mac") * @run main/othervm -Xmx512m SigningPackageTest */ diff --git a/test/jdk/tools/jpackage/macosx/base/SigningCheck.java b/test/jdk/tools/jpackage/macosx/base/SigningCheck.java index 2f247b07263..3d0b4a44e34 100644 --- a/test/jdk/tools/jpackage/macosx/base/SigningCheck.java +++ b/test/jdk/tools/jpackage/macosx/base/SigningCheck.java @@ -29,7 +29,7 @@ import jdk.jpackage.test.TKit; import jdk.jpackage.test.Executor; -import jdk.incubator.jpackage.internal.MacCertificate; +import jdk.jpackage.internal.MacCertificate; public class SigningCheck { diff --git a/test/jdk/tools/jpackage/share/AddLauncherTest.java b/test/jdk/tools/jpackage/share/AddLauncherTest.java index 2c0edc9d26c..9bd45549eef 100644 --- a/test/jdk/tools/jpackage/share/AddLauncherTest.java +++ b/test/jdk/tools/jpackage/share/AddLauncherTest.java @@ -50,7 +50,7 @@ * @requires (jpackage.test.SQETest != null) * @library ../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile AddLauncherTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=AddLauncherTest.test @@ -63,7 +63,7 @@ * @requires (jpackage.test.SQETest == null) * @library ../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile AddLauncherTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=AddLauncherTest diff --git a/test/jdk/tools/jpackage/share/AppImagePackageTest.java b/test/jdk/tools/jpackage/share/AppImagePackageTest.java index 2ee998af447..9065494e0e9 100644 --- a/test/jdk/tools/jpackage/share/AppImagePackageTest.java +++ b/test/jdk/tools/jpackage/share/AppImagePackageTest.java @@ -45,7 +45,7 @@ * @library ../helpers * @requires (jpackage.test.SQETest == null) * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile AppImagePackageTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=AppImagePackageTest diff --git a/test/jdk/tools/jpackage/share/ArgumentsTest.java b/test/jdk/tools/jpackage/share/ArgumentsTest.java index 1cc6f715317..8cb8fc93658 100644 --- a/test/jdk/tools/jpackage/share/ArgumentsTest.java +++ b/test/jdk/tools/jpackage/share/ArgumentsTest.java @@ -49,7 +49,7 @@ * @summary jpackage create image with --arguments test * @library ../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile ArgumentsTest.java * @run main/othervm -Xmx512m jdk.jpackage.test.Main * --jpt-run=ArgumentsTest diff --git a/test/jdk/tools/jpackage/share/EmptyFolderPackageTest.java b/test/jdk/tools/jpackage/share/EmptyFolderPackageTest.java index 89ef1ba7a38..90b53a478dc 100644 --- a/test/jdk/tools/jpackage/share/EmptyFolderPackageTest.java +++ b/test/jdk/tools/jpackage/share/EmptyFolderPackageTest.java @@ -22,7 +22,7 @@ */ import java.nio.file.Path; -import jdk.incubator.jpackage.internal.ApplicationLayout; +import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.TKit; @@ -39,7 +39,7 @@ * @key jpackagePlatformPackage * @build EmptyFolderBase * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=720 -Xmx512m EmptyFolderPackageTest */ public class EmptyFolderPackageTest { diff --git a/test/jdk/tools/jpackage/share/EmptyFolderTest.java b/test/jdk/tools/jpackage/share/EmptyFolderTest.java index aefaeadbddc..873f08c3fbe 100644 --- a/test/jdk/tools/jpackage/share/EmptyFolderTest.java +++ b/test/jdk/tools/jpackage/share/EmptyFolderTest.java @@ -24,7 +24,7 @@ import java.nio.file.Path; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.TKit; -import jdk.incubator.jpackage.internal.ApplicationLayout; +import jdk.jpackage.internal.ApplicationLayout; /** * Tests generation of app image with input folder containing empty folders. @@ -37,7 +37,7 @@ * @library /test/lib * @build EmptyFolderBase * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm -Xmx512m EmptyFolderTest */ public class EmptyFolderTest { diff --git a/test/jdk/tools/jpackage/share/FileAssociationsTest.java b/test/jdk/tools/jpackage/share/FileAssociationsTest.java index fcad5e7d15d..52dd20f9297 100644 --- a/test/jdk/tools/jpackage/share/FileAssociationsTest.java +++ b/test/jdk/tools/jpackage/share/FileAssociationsTest.java @@ -61,7 +61,7 @@ * @key jpackagePlatformPackage * @requires jpackage.test.SQETest == null * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile FileAssociationsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=FileAssociationsTest @@ -74,7 +74,7 @@ * @key jpackagePlatformPackage * @requires jpackage.test.SQETest != null * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile FileAssociationsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=FileAssociationsTest.test diff --git a/test/jdk/tools/jpackage/share/IconTest.java b/test/jdk/tools/jpackage/share/IconTest.java index eeb138ef5f2..cf86be917d2 100644 --- a/test/jdk/tools/jpackage/share/IconTest.java +++ b/test/jdk/tools/jpackage/share/IconTest.java @@ -51,7 +51,7 @@ * @summary jpackage create image and package with custom icons for the main and additional launcher * @library ../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile IconTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=IconTest diff --git a/test/jdk/tools/jpackage/share/InstallDirTest.java b/test/jdk/tools/jpackage/share/InstallDirTest.java index e49132d25b5..1f969149c68 100644 --- a/test/jdk/tools/jpackage/share/InstallDirTest.java +++ b/test/jdk/tools/jpackage/share/InstallDirTest.java @@ -58,7 +58,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @compile InstallDirTest.java - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=InstallDirTest.testCommon */ @@ -70,7 +70,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @compile InstallDirTest.java - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @requires (os.family == "linux") * @requires (jpackage.test.SQETest == null) * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main diff --git a/test/jdk/tools/jpackage/share/LicenseTest.java b/test/jdk/tools/jpackage/share/LicenseTest.java index ed8c86c99c7..97e9cd1bfdd 100644 --- a/test/jdk/tools/jpackage/share/LicenseTest.java +++ b/test/jdk/tools/jpackage/share/LicenseTest.java @@ -67,7 +67,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @compile LicenseTest.java - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=LicenseTest.testCommon */ @@ -81,7 +81,7 @@ * @compile LicenseTest.java * @requires (os.family == "linux") * @requires (jpackage.test.SQETest == null) - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=1440 -Xmx512m jdk.jpackage.test.Main * --jpt-run=LicenseTest.testCustomDebianCopyright * --jpt-run=LicenseTest.testCustomDebianCopyrightSubst diff --git a/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java b/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java index 423ea5b9608..5df3609e3ba 100644 --- a/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java +++ b/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java @@ -47,7 +47,7 @@ * @library /test/lib * @key jpackagePlatformPackage * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile MultiLauncherTwoPhaseTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=MultiLauncherTwoPhaseTest diff --git a/test/jdk/tools/jpackage/share/RuntimePackageTest.java b/test/jdk/tools/jpackage/share/RuntimePackageTest.java index 94ecb12c846..9c4c24e3dcb 100644 --- a/test/jdk/tools/jpackage/share/RuntimePackageTest.java +++ b/test/jdk/tools/jpackage/share/RuntimePackageTest.java @@ -56,7 +56,7 @@ * @comment Temporary disable for OSX until functionality implemented * @requires (os.family != "mac") * @requires (jpackage.test.SQETest == null) - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile RuntimePackageTest.java * @run main/othervm/timeout=1400 -Xmx512m jdk.jpackage.test.Main * --jpt-run=RuntimePackageTest @@ -71,7 +71,7 @@ * @comment Temporary disable for OSX until functionality implemented * @requires (os.family != "mac") * @requires (jpackage.test.SQETest != null) - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile RuntimePackageTest.java * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main * --jpt-run=RuntimePackageTest.test diff --git a/test/jdk/tools/jpackage/share/SimplePackageTest.java b/test/jdk/tools/jpackage/share/SimplePackageTest.java index aaf2c7e2caf..d2e8da31c03 100644 --- a/test/jdk/tools/jpackage/share/SimplePackageTest.java +++ b/test/jdk/tools/jpackage/share/SimplePackageTest.java @@ -43,7 +43,7 @@ * @library ../helpers * @key jpackagePlatformPackage * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile SimplePackageTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=SimplePackageTest diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/AppVersionTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/AppVersionTest.java index 89ae306d7a7..f137fabf3d6 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/AppVersionTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/AppVersionTest.java @@ -30,13 +30,13 @@ import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; -import jdk.incubator.jpackage.internal.AppImageFile; +import jdk.jpackage.internal.AppImageFile; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.TKit; -import jdk.incubator.jpackage.internal.AppImageFile; +import jdk.jpackage.internal.AppImageFile; import org.w3c.dom.Document; /* @@ -44,7 +44,7 @@ * @summary jpackage application version testing * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile AppVersionTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.AppVersionTest diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java index 33f476a5ddd..c93c51ab24b 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java @@ -48,7 +48,7 @@ * @summary jpackage basic testing * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile BasicTest.java * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.BasicTest diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/CookedRuntimeTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/CookedRuntimeTest.java index 382836f07a9..f61fff69fe6 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/CookedRuntimeTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/CookedRuntimeTest.java @@ -44,7 +44,7 @@ * @summary test '--runtime-image' option of jpackage * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile CookedRuntimeTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.CookedRuntimeTest diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ErrorTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ErrorTest.java index ba78f7caf07..95f7ff9a12d 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ErrorTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ErrorTest.java @@ -35,7 +35,7 @@ * @summary jpackage application version testing * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile ErrorTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.ErrorTest @@ -47,7 +47,7 @@ * @summary jpackage application version testing * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile ErrorTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.ErrorTest diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JLinkOptionsTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JLinkOptionsTest.java index 50f22fe634f..5f97df482bf 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JLinkOptionsTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JLinkOptionsTest.java @@ -35,7 +35,7 @@ * @summary jpackage application version testing * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile JLinkOptionsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.JLinkOptionsTest @@ -92,7 +92,7 @@ public static Collection input() { // should have whatever it needs new String[]{"java.base", "com.other"}, // should not have whatever it doesn't need - new String[]{"jdk.incubator.jpackage"}, + new String[]{"jdk.jpackage"}, }, // bind-services and limit-options diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsEqualsTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsEqualsTest.java index 9858ce928b5..c63892a2ca0 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsEqualsTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsEqualsTest.java @@ -37,7 +37,7 @@ * @summary jpackage create image with --java-options test * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile JavaOptionsEqualsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.JavaOptionsEqualsTest @@ -49,7 +49,7 @@ * @summary jpackage create image with --java-options test * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile JavaOptionsEqualsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.JavaOptionsEqualsTest diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsTest.java index 069ec10f3c1..ab2f7a3d15d 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsTest.java @@ -37,7 +37,7 @@ * @summary jpackage create image with --java-options test * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile JavaOptionsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.JavaOptionsTest diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java index bf0a6e34c06..c39b9d6ff6e 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java @@ -53,7 +53,7 @@ * @summary test different settings of main class name for jpackage * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile MainClassTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.MainClassTest diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest.java index 77fa37ead72..1c5ead2ad65 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest.java @@ -46,7 +46,7 @@ * @summary jpackage with --module-path testing * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile ModulePathTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.ModulePathTest diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest2.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest2.java index ef1bc9d4b1a..7bfe998014c 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest2.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest2.java @@ -38,7 +38,7 @@ * @summary jpackage with --module-path testing * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile ModulePathTest2.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.ModulePathTest2 diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest3.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest3.java index d916fe5c7de..c7c33fa8617 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest3.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest3.java @@ -32,7 +32,7 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; -import jdk.incubator.jpackage.internal.AppImageFile; +import jdk.jpackage.internal.AppImageFile; import jdk.jpackage.test.HelloApp; import jdk.jpackage.test.JavaAppDesc; import jdk.jpackage.test.Annotations.Test; @@ -51,7 +51,7 @@ * @summary jpackage for app's module linked in external runtime * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile ModulePathTest3.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.ModulePathTest3 @@ -62,7 +62,7 @@ * @summary jpackage for app's module linked in external runtime * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile ModulePathTest3.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.ModulePathTest3 diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MultipleJarAppTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MultipleJarAppTest.java index ae0901b239c..3ce9f62d8d2 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MultipleJarAppTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MultipleJarAppTest.java @@ -35,7 +35,7 @@ * @summary jpackage application packed in multiple jars * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile MultipleJarAppTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.MultipleJarAppTest diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/NonExistentTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/NonExistentTest.java index 34844fbf882..3790c9002ca 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/NonExistentTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/NonExistentTest.java @@ -35,7 +35,7 @@ * @summary jpackage application version testing * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile NonExistentTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=jdk.jpackage.tests.NonExistentTest diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java index cd37e7ae6e3..10e2e38ec5c 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java +++ b/test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java @@ -35,7 +35,7 @@ * @summary test how app launcher handles unicode command line arguments * @library ../../../../helpers * @build jdk.jpackage.test.* - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile UnicodeArgsTest.java * @requires (os.family == "windows") * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main diff --git a/test/jdk/tools/jpackage/windows/WinConsoleTest.java b/test/jdk/tools/jpackage/windows/WinConsoleTest.java index 806b6bad26c..7a4e9ccfa5a 100644 --- a/test/jdk/tools/jpackage/windows/WinConsoleTest.java +++ b/test/jdk/tools/jpackage/windows/WinConsoleTest.java @@ -37,7 +37,7 @@ * @library ../helpers * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile WinConsoleTest.java * * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main diff --git a/test/jdk/tools/jpackage/windows/WinDirChooserTest.java b/test/jdk/tools/jpackage/windows/WinDirChooserTest.java index 5b994f4cf68..f64a5b2c6e7 100644 --- a/test/jdk/tools/jpackage/windows/WinDirChooserTest.java +++ b/test/jdk/tools/jpackage/windows/WinDirChooserTest.java @@ -40,7 +40,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @run main/othervm/timeout=360 -Xmx512m WinDirChooserTest */ diff --git a/test/jdk/tools/jpackage/windows/WinL10nTest.java b/test/jdk/tools/jpackage/windows/WinL10nTest.java index 72496b9b6d5..4171da208a4 100644 --- a/test/jdk/tools/jpackage/windows/WinL10nTest.java +++ b/test/jdk/tools/jpackage/windows/WinL10nTest.java @@ -42,7 +42,7 @@ * @requires (jpackage.test.SQETest == null) * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile WinL10nTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinL10nTest diff --git a/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java b/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java index 13691f94424..b8b748a6ca1 100644 --- a/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java +++ b/test/jdk/tools/jpackage/windows/WinMenuGroupTest.java @@ -43,7 +43,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile WinMenuGroupTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinMenuGroupTest diff --git a/test/jdk/tools/jpackage/windows/WinMenuTest.java b/test/jdk/tools/jpackage/windows/WinMenuTest.java index 15a3bf8734a..e39a16465fe 100644 --- a/test/jdk/tools/jpackage/windows/WinMenuTest.java +++ b/test/jdk/tools/jpackage/windows/WinMenuTest.java @@ -40,7 +40,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile WinMenuTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinMenuTest diff --git a/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java b/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java index 6667ba401de..2020c27975b 100644 --- a/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java +++ b/test/jdk/tools/jpackage/windows/WinPerUserInstallTest.java @@ -41,7 +41,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile WinPerUserInstallTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinPerUserInstallTest diff --git a/test/jdk/tools/jpackage/windows/WinResourceTest.java b/test/jdk/tools/jpackage/windows/WinResourceTest.java index 8200241a468..c7610aafa33 100644 --- a/test/jdk/tools/jpackage/windows/WinResourceTest.java +++ b/test/jdk/tools/jpackage/windows/WinResourceTest.java @@ -42,7 +42,7 @@ * @library ../helpers * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile WinResourceTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinResourceTest diff --git a/test/jdk/tools/jpackage/windows/WinScriptTest.java b/test/jdk/tools/jpackage/windows/WinScriptTest.java index d807977375d..3a2f095152b 100644 --- a/test/jdk/tools/jpackage/windows/WinScriptTest.java +++ b/test/jdk/tools/jpackage/windows/WinScriptTest.java @@ -25,7 +25,7 @@ import java.nio.file.Path; import java.util.List; import java.util.ArrayList; -import jdk.incubator.jpackage.internal.IOUtils; +import jdk.jpackage.internal.IOUtils; import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -40,7 +40,7 @@ * @library ../helpers * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile WinScriptTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinScriptTest diff --git a/test/jdk/tools/jpackage/windows/WinShortcutTest.java b/test/jdk/tools/jpackage/windows/WinShortcutTest.java index dbd2447b857..f50f07a8905 100644 --- a/test/jdk/tools/jpackage/windows/WinShortcutTest.java +++ b/test/jdk/tools/jpackage/windows/WinShortcutTest.java @@ -41,7 +41,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile WinShortcutTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinShortcutTest diff --git a/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java b/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java index f1effb3f07b..0c233b0e652 100644 --- a/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java +++ b/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java @@ -51,7 +51,7 @@ * @requires (jpackage.test.SQETest != null) * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile WinUpgradeUUIDTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinUpgradeUUIDTest.test @@ -65,7 +65,7 @@ * @requires (jpackage.test.SQETest == null) * @build jdk.jpackage.test.* * @requires (os.family == "windows") - * @modules jdk.incubator.jpackage/jdk.incubator.jpackage.internal + * @modules jdk.jpackage/jdk.jpackage.internal * @compile WinUpgradeUUIDTest.java * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main * --jpt-run=WinUpgradeUUIDTest diff --git a/test/langtools/jdk/javadoc/doclet/AccessSkipNav/AccessSkipNav.java b/test/langtools/jdk/javadoc/doclet/AccessSkipNav/AccessSkipNav.java index 73bed39266e..e96d63cc869 100644 --- a/test/langtools/jdk/javadoc/doclet/AccessSkipNav/AccessSkipNav.java +++ b/test/langtools/jdk/javadoc/doclet/AccessSkipNav/AccessSkipNav.java @@ -56,14 +56,6 @@ public void test() { """ - """, - // Bottom navbar - """ - Skip navigation links""", - // Bottom navbar - """ - - """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java b/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java index 437792bd805..a8844065bfe 100644 --- a/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java +++ b/test/langtools/jdk/javadoc/doclet/testCopyFiles/TestCopyFiles.java @@ -71,18 +71,7 @@ public void testDocFilesInModulePackages() { In a named module acme.module and named package p.""", "
    Since:Module""", - """ - Package""", - """ - Tree""", - """ - Deprecated""", - """ - Index""", - "phi-FOOTER-phi", + // check footer "phi-BOTTOM-phi" ); } @@ -119,18 +108,7 @@ public void testDocFilesInMultiModulePackagesWithRecursiveCopy() { In a named module acme.module and named package p.""", "
    Since:Module""", - """ - Package""", - """ - Tree""", - """ - Deprecated""", - """ - Index""", - "phi-FOOTER-phi", + // check footer "phi-BOTTOM-phi" ); @@ -151,18 +129,7 @@ public void testDocFilesInMultiModulePackagesWithRecursiveCopy() { Index""", "phi-HEADER-phi", "SubSubReadme.html at third level of doc-file directory.", - // check bottom navbar - """ - Module""", - """ - Package""", - """ - Tree""", - """ - Deprecated""", - """ - Index""", - "phi-FOOTER-phi", + // check footer "phi-BOTTOM-phi" ); } diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlLandmarkRegions/TestHtmlLandmarkRegions.java b/test/langtools/jdk/javadoc/doclet/testHtmlLandmarkRegions/TestHtmlLandmarkRegions.java index f48cba0ebe7..1577d6d563f 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlLandmarkRegions/TestHtmlLandmarkRegions.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlLandmarkRegions/TestHtmlLandmarkRegions.java @@ -68,6 +68,7 @@ public void testModules(Path base) throws Exception { javadoc("-d", outDir.toString(), "-doctitle", "Document Title", "-header", "Test Header", + "-bottom", "bottom text", "--module-source-path", srcDir.toString(), "--module", "m1,m2"); @@ -82,8 +83,10 @@ public void testModules(Path base) throws Exception {

    Document Title

    """, """ -