# HG changeset patch # User mgronlun # Date 1572431035 -3600 # Node ID 4c036608ca8b903919849a8ffdc5a3ca2db046bc # Parent 12b4063e357f260bd67f8964c2cc34678af82522# Parent 674131501e98738721dd9ef8ddaca8358262db18 Merge diff -r 12b4063e357f -r 4c036608ca8b make/Bundles.gmk --- a/make/Bundles.gmk Tue Oct 29 15:16:45 2019 +0100 +++ b/make/Bundles.gmk Wed Oct 30 11:23:55 2019 +0100 @@ -314,6 +314,27 @@ ################################################################################ +ifneq ($(filter static-libs-bundles, $(MAKECMDGOALS)), ) + STATIC_LIBS_BUNDLE_FILES := $(call FindFiles, $(STATIC_LIBS_IMAGE_DIR)) + + ifeq ($(OPENJDK_TARGET_OS)-$(DEBUG_LEVEL), macosx-release) + STATIC_LIBS_BUNDLE_SUBDIR := $(JDK_MACOSX_CONTENTS_SUBDIR)/Home + else + STATIC_LIBS_BUNDLE_SUBDIR := $(JDK_BUNDLE_SUBDIR) + endif + + $(eval $(call SetupBundleFile, BUILD_STATIC_LIBS_BUNDLE, \ + BUNDLE_NAME := $(STATIC_LIBS_BUNDLE_NAME), \ + FILES := $(STATIC_LIBS_BUNDLE_FILES), \ + BASE_DIRS := $(STATIC_LIBS_IMAGE_DIR), \ + SUBDIR := $(STATIC_LIBS_BUNDLE_SUBDIR), \ + )) + + STATIC_LIBS_TARGETS += $(BUILD_STATIC_LIBS_BUNDLE) +endif + +################################################################################ + # Hook to include the corresponding custom file, if present. $(eval $(call IncludeCustomExtension, Bundles.gmk)) @@ -323,6 +344,8 @@ legacy-bundles: $(LEGACY_TARGETS) test-bundles: $(TEST_TARGETS) docs-bundles: $(DOCS_TARGETS) +static-libs-bundles: $(STATIC_LIBS_TARGETS) jcov-bundles: $(JCOV_TARGETS) -.PHONY: all default product-bundles test-bundles docs-bundles jcov-bundles +.PHONY: all default product-bundles test-bundles docs-bundles \ + static-libs-bundles jcov-bundles diff -r 12b4063e357f -r 4c036608ca8b make/Help.gmk --- a/make/Help.gmk Tue Oct 29 15:16:45 2019 +0100 +++ b/make/Help.gmk Wed Oct 30 11:23:55 2019 +0100 @@ -43,7 +43,7 @@ $(info $(_) make images # Create a complete jdk image) $(info $(_) # (alias for product-images)) $(info $(_) make -image # Build just the image for any of: ) - $(info $(_) # jdk, test, docs, symbols, legacy-jre) + $(info $(_) # jdk, test, docs, symbols, legacy-jre, static-libs) $(info $(_) make # Build the specified phase and everything it depends on) $(info $(_) # (gensrc, java, copy, libs, launchers, gendata, rmic)) $(info $(_) make *-only # Applies to most targets and disables building the) diff -r 12b4063e357f -r 4c036608ca8b make/Main.gmk --- a/make/Main.gmk Tue Oct 29 15:16:45 2019 +0100 +++ b/make/Main.gmk Wed Oct 30 11:23:55 2019 +0100 @@ -218,6 +218,21 @@ ALL_TARGETS += $(LIBS_TARGETS) ################################################################################ +# Targets for compiling static versions of certain native libraries. These do +# not end up in the jmods or the normal JDK image, but are instead bundled into +# a special deliverable. +$(eval $(call DeclareRecipesForPhase, STATIC_LIBS, \ + TARGET_SUFFIX := static-libs, \ + FILE_PREFIX := Lib, \ + MAKE_SUBDIR := lib, \ + CHECK_MODULES := $(STATIC_LIBS_MODULES), \ + USE_WRAPPER := true, \ + EXTRA_ARGS := STATIC_LIBS=true, \ +)) + +ALL_TARGETS += $(STATIC_LIBS_TARGETS) + +################################################################################ # Targets for compiling native executables $(eval $(call DeclareRecipesForPhase, LAUNCHER, \ TARGET_SUFFIX := launchers, \ @@ -377,6 +392,9 @@ symbols-image: +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Images.gmk symbols) +static-libs-image: + +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f StaticLibsImage.gmk) + mac-jdk-bundle: +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f MacBundles.gmk jdk-bundle) @@ -396,7 +414,7 @@ ALL_TARGETS += store-source-revision create-source-revision-tracker bootcycle-images zip-security \ zip-source jrtfs-jar jdk-image legacy-jre-image \ - symbols-image mac-jdk-bundle mac-legacy-jre-bundle \ + symbols-image static-libs-image mac-jdk-bundle mac-legacy-jre-bundle \ release-file exploded-image-optimize jcov-image ################################################################################ @@ -614,12 +632,16 @@ docs-bundles: +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Bundles.gmk docs-bundles) +static-libs-bundles: + +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Bundles.gmk static-libs-bundles) + ifeq ($(JCOV_ENABLED), true) jcov-bundles: +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Bundles.gmk jcov-bundles) endif -ALL_TARGETS += product-bundles legacy-bundles test-bundles docs-bundles jcov-bundles +ALL_TARGETS += product-bundles legacy-bundles test-bundles docs-bundles \ + static-libs-bundles jcov-bundles ################################################################################ # Install targets @@ -796,6 +818,10 @@ vscode-project-rtags: compile-commands vscode-project-ccls: compile-commands + # The -static-libs targets depend on -java as well as java.base-copy. + $(foreach m, $(filter $(JAVA_MODULES), $(STATIC_LIBS_MODULES)), \ + $(eval $m-static-libs: $m-java java.base-copy)) + # Jmods cannot be created until we have the jmod tool ready to run. During # a normal build we run it from the exploded image, but when cross compiling # it's run from the buildjdk, which is either created at build time or user @@ -858,6 +884,8 @@ legacy-jre-image: jmods release-file symbols-image: $(LIBS_TARGETS) $(LAUNCHER_TARGETS) + static-libs-image: $(STATIC_LIBS_TARGETS) + mac-jdk-bundle: jdk-image mac-legacy-jre-bundle: legacy-jre-image @@ -946,6 +974,8 @@ jcov-bundles: jcov-image + static-libs-bundles: static-libs-image + generate-summary: jmods buildtools-modules update-x11wrappers: java.base-copy buildtools-jdk @@ -984,6 +1014,8 @@ libs: $(LIBS_TARGETS) +static-libs: $(STATIC_LIBS_TARGETS) + launchers: $(LAUNCHER_TARGETS) jmods: $(JMOD_TARGETS) @@ -1094,10 +1126,10 @@ all-images: product-images test-image docs-image # all-bundles packages all our deliverables as tar.gz bundles. -all-bundles: product-bundles test-bundles docs-bundles +all-bundles: product-bundles test-bundles docs-bundles static-libs-bundles ALL_TARGETS += buildtools hotspot hotspot-libs hotspot-gensrc gensrc gendata \ - copy java rmic libs launchers jmods \ + copy java rmic libs static-libs launchers jmods \ jdk.jdwp.agent-gensrc $(ALL_MODULES) demos \ exploded-image-base exploded-image \ create-buildjdk docs-jdk-api docs-javase-api docs-reference-api docs-jdk \ diff -r 12b4063e357f -r 4c036608ca8b make/MainSupport.gmk --- a/make/MainSupport.gmk Tue Oct 29 15:16:45 2019 +0100 +++ b/make/MainSupport.gmk Wed Oct 30 11:23:55 2019 +0100 @@ -133,7 +133,7 @@ $$(addprefix -I, $$(PHASE_MAKEDIRS) \ $$(addsuffix /$$($1_MAKE_SUBDIR), $$(PHASE_MAKEDIRS)) \ ) \ - MODULE=$2 MAKEFILE_PREFIX=$$($1_FILE_PREFIX)) + MODULE=$2 MAKEFILE_PREFIX=$$($1_FILE_PREFIX) $$($1_EXTRA_ARGS)) else +($(CD) $$(dir $$(firstword $$(wildcard $$(addsuffix \ /$$($1_MAKE_SUBDIR)/$$($1_FILE_PREFIX)-$2.gmk, $$(PHASE_MAKEDIRS))))) \ @@ -142,7 +142,7 @@ $$(addprefix -I, $$(PHASE_MAKEDIRS) \ $$(addsuffix /$$($1_MAKE_SUBDIR), $$(PHASE_MAKEDIRS)) \ ) \ - MODULE=$2 \ + MODULE=$2 $$($1_EXTRA_ARGS) \ ) endif @@ -182,12 +182,13 @@ # CHECK_MODULES : List of modules to try # MULTIPLE_MAKEFILES : Set to true to handle makefiles for the same module and # phase in multiple repos +# EXTRA_ARGS : Add extra make args to each makefile call # Exported variables: # $1_MODULES : All modules that had rules generated # $1_TARGETS : All targets generated define DeclareRecipesForPhase - $(foreach i,2 3 4 5 6 7, $(if $(strip $($i)),$(strip $1)_$(strip $($i)))$(NEWLINE)) - $(if $(8),$(error Internal makefile error: Too many arguments to \ + $(foreach i,2 3 4 5 6 7 8, $(if $(strip $($i)),$(strip $1)_$(strip $($i)))$(NEWLINE)) + $(if $(9),$(error Internal makefile error: Too many arguments to \ DeclareRecipesForPhase, please update MakeHelper.gmk)) $$(foreach m, $$($(strip $1)_CHECK_MODULES), \ diff -r 12b4063e357f -r 4c036608ca8b make/StaticLibsImage.gmk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/StaticLibsImage.gmk Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,54 @@ +# +# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# This makefile creates an image of the optional static versions of certain JDK +# libraries. + +default: all + +include $(SPEC) +include MakeBase.gmk +include Modules.gmk + +################################################################################ + +TARGETS := + +$(foreach m, $(STATIC_LIBS_MODULES), \ + $(eval $(call SetupCopyFiles, COPY_STATIC_LIBS_$m, \ + FLATTEN := true, \ + SRC := $(SUPPORT_OUTPUTDIR)/native/$m, \ + DEST := $(STATIC_LIBS_IMAGE_DIR)/lib, \ + FILES := $(filter %$(STATIC_LIBRARY_SUFFIX), \ + $(call FindFiles, $(SUPPORT_OUTPUTDIR)/native/$m/*/static)), \ + )) \ + $(eval TARGETS += $$(COPY_STATIC_LIBS_$m)) \ +) + +################################################################################ + +all: $(TARGETS) + +.PHONY: all diff -r 12b4063e357f -r 4c036608ca8b make/autoconf/flags-cflags.m4 --- a/make/autoconf/flags-cflags.m4 Tue Oct 29 15:16:45 2019 +0100 +++ b/make/autoconf/flags-cflags.m4 Wed Oct 30 11:23:55 2019 +0100 @@ -694,6 +694,20 @@ OS_CFLAGS_JVM="$OS_CFLAGS_JVM -DNEEDS_LIBRT" fi fi + + # Extra flags needed when building optional static versions of certain + # JDK libraries. + STATIC_LIBS_CFLAGS="-DSTATIC_BUILD=1" + if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then + STATIC_LIBS_CFLAGS="$STATIC_LIBS_CFLAGS -ffunction-sections -fdata-sections" + fi + if test "x$TOOLCHAIN_TYPE" = xgcc; then + # Disable relax-relocation to enable compatibility with older linkers + RELAX_RELOCATIONS_FLAG="-Xassembler -mrelax-relocations=no" + FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${RELAX_RELOCATIONS_FLAG}], + IF_TRUE: [STATIC_LIBS_CFLAGS="$STATIC_LIBS_CFLAGS ${RELAX_RELOCATIONS_FLAG}"]) + fi + AC_SUBST(STATIC_LIBS_CFLAGS) ]) ################################################################################ diff -r 12b4063e357f -r 4c036608ca8b make/autoconf/jdk-version.m4 --- a/make/autoconf/jdk-version.m4 Tue Oct 29 15:16:45 2019 +0100 +++ b/make/autoconf/jdk-version.m4 Wed Oct 30 11:23:55 2019 +0100 @@ -162,7 +162,9 @@ AC_MSG_ERROR([--with-vendor-vm-bug-url must have a value]) elif [ ! [[ $with_vendor_vm_bug_url =~ ^[[:print:]]*$ ]] ]; then AC_MSG_ERROR([--with-vendor-vm-bug-url contains non-printing characters: $with_vendor_vm_bug_url]) - else + elif test "x$with_vendor_vm_bug_url" != x; then + # Only set VENDOR_URL_VM_BUG if '--with-vendor-vm-bug-url' was used and is not empty. + # Otherwise we will use the value from "version-numbers" included above. VENDOR_URL_VM_BUG="$with_vendor_vm_bug_url" fi AC_SUBST(VENDOR_URL_VM_BUG) diff -r 12b4063e357f -r 4c036608ca8b make/autoconf/spec.gmk.in --- a/make/autoconf/spec.gmk.in Tue Oct 29 15:16:45 2019 +0100 +++ b/make/autoconf/spec.gmk.in Wed Oct 30 11:23:55 2019 +0100 @@ -376,6 +376,8 @@ LIBFFI_LIB_FILE:=@LIBFFI_LIB_FILE@ GRAALUNIT_LIB := @GRAALUNIT_LIB@ +STATIC_LIBS_CFLAGS := @STATIC_LIBS_CFLAGS@ + JMH_CORE_JAR := @JMH_CORE_JAR@ JMH_GENERATOR_JAR := @JMH_GENERATOR_JAR@ JMH_JOPT_SIMPLE_JAR := @JMH_JOPT_SIMPLE_JAR@ @@ -892,6 +894,10 @@ # Output docs directly into image DOCS_OUTPUTDIR := $(DOCS_IMAGE_DIR) +# Static libs image +STATIC_LIBS_IMAGE_SUBDIR := static-libs +STATIC_LIBS_IMAGE_DIR := $(IMAGES_OUTPUTDIR)/$(STATIC_LIBS_IMAGE_SUBDIR) + # Macosx bundles directory definitions JDK_MACOSX_BUNDLE_SUBDIR=jdk-bundle JRE_MACOSX_BUNDLE_SUBDIR=jre-bundle @@ -920,6 +926,7 @@ TEST_DEMOS_BUNDLE_NAME := jdk-$(BASE_NAME)_bin-tests-demos$(DEBUG_PART).tar.gz TEST_BUNDLE_NAME := jdk-$(BASE_NAME)_bin-tests$(DEBUG_PART).tar.gz DOCS_BUNDLE_NAME := jdk-$(BASE_NAME)_doc-api-spec$(DEBUG_PART).tar.gz +STATIC_LIBS_BUNDLE_NAME := jdk-$(BASE_NAME)_bin-static-libs$(DEBUG_PART).tar.gz JCOV_BUNDLE_NAME := jdk-jcov-$(BASE_NAME)_bin$(DEBUG_PART).$(JDK_BUNDLE_EXTENSION) JDK_BUNDLE := $(BUNDLES_OUTPUTDIR)/$(JDK_BUNDLE_NAME) diff -r 12b4063e357f -r 4c036608ca8b make/autoconf/version-numbers --- a/make/autoconf/version-numbers Tue Oct 29 15:16:45 2019 +0100 +++ b/make/autoconf/version-numbers Wed Oct 30 11:23:55 2019 +0100 @@ -23,7 +23,8 @@ # questions. # -# Default version numbers to use unless overridden by configure +# Default version, product, and vendor information to use, +# unless overridden by configure DEFAULT_VERSION_FEATURE=14 DEFAULT_VERSION_INTERIM=0 @@ -47,6 +48,7 @@ HOTSPOT_VM_DISTRO="OpenJDK" VENDOR_URL=https://openjdk.java.net/ VENDOR_URL_BUG=https://bugreport.java.com/bugreport/ +VENDOR_URL_VM_BUG=https://bugreport.java.com/bugreport/crash.jsp # Might need better names for these MACOSX_BUNDLE_NAME_BASE="OpenJDK" diff -r 12b4063e357f -r 4c036608ca8b make/common/JdkNativeCompilation.gmk --- a/make/common/JdkNativeCompilation.gmk Tue Oct 29 15:16:45 2019 +0100 +++ b/make/common/JdkNativeCompilation.gmk Wed Oct 30 11:23:55 2019 +0100 @@ -47,7 +47,8 @@ $(TOPDIR)/src/$(strip $1)/$(OPENJDK_TARGET_OS_TYPE)/native/$(strip $2) \ $(TOPDIR)/src/$(strip $1)/share/native/$(strip $2))) -# Find a library +# Find a library. Used for declaring dependencies on libraries in different +# modules. # Param 1 - module name # Param 2 - library name # Param 3 - optional subdir for library @@ -69,6 +70,12 @@ FindLib = FindStaticLib = endif +# If building static versions of libraries, make these return empty to avoid +# declaring dependencies. +ifeq ($(STATIC_LIBS), true) + FindLib = + FindStaticLib = +endif GetJavaHeaderDir = \ $(wildcard $(SUPPORT_OUTPUTDIR)/headers/$(strip $1)) diff -r 12b4063e357f -r 4c036608ca8b make/common/Modules.gmk --- a/make/common/Modules.gmk Tue Oct 29 15:16:45 2019 +0100 +++ b/make/common/Modules.gmk Wed Oct 30 11:23:55 2019 +0100 @@ -198,6 +198,21 @@ jdk.internal.vm.compiler.management \ # +# The native dynamic libraries in these modules will also get built into static +# libraries for consumption by downstream projects that need to statically link +# the JDK libraries. Those static libraries are not part of the main JDK +# distribution. +STATIC_LIBS_MODULES := \ + java.base \ + jdk.crypto.ec \ + jdk.security.auth \ + java.prefs \ + java.security.jgss \ + java.smartcardio \ + jdk.crypto.cryptoki \ + jdk.net \ + # + ################################################################################ # Some platforms don't have the serviceability agent diff -r 12b4063e357f -r 4c036608ca8b make/common/NativeCompilation.gmk --- a/make/common/NativeCompilation.gmk Tue Oct 29 15:16:45 2019 +0100 +++ b/make/common/NativeCompilation.gmk Wed Oct 30 11:23:55 2019 +0100 @@ -453,6 +453,28 @@ endif endif + $$(call SetIfEmpty, $1_COMPILE_WITH_DEBUG_SYMBOLS, $$(COMPILE_WITH_DEBUG_SYMBOLS)) + + # STATIC_LIBS is set from Main.gmk when building static versions of certain + # native libraries. + ifeq ($(STATIC_LIBS), true) + $1_TYPE := STATIC_LIBRARY + # The static versions need to be redirected to different output dirs, both + # to not interfere with the main build as well as to not end up inside the + # jmods. + $1_OBJECT_DIR := $$($1_OBJECT_DIR)/static + $1_OUTPUT_DIR := $$($1_OBJECT_DIR) + # For release builds where debug symbols are configured to be moved to + # separate debuginfo files, disable debug symbols for static libs instead. + # We don't currently support this configuration and we don't want symbol + # information in release builds unless explicitly asked to provide it. + ifeq ($(DEBUG_LEVEL), release) + ifeq ($(COPY_DEBUG_SYMBOLS), true) + $1_COMPILE_WITH_DEBUG_SYMBOLS := false + endif + endif + endif + ifeq ($$($1_TYPE), EXECUTABLE) $1_PREFIX := ifeq ($$($1_SUFFIX), ) @@ -592,6 +614,9 @@ $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS)_release) $1_EXTRA_CFLAGS += $$($1_CFLAGS_$(OPENJDK_TARGET_OS)_$(OPENJDK_TARGET_CPU)_release) endif + ifeq ($(STATIC_LIBS), true) + $1_EXTRA_CFLAGS += $$(STATIC_LIBS_CFLAGS) + endif # Pickup extra OPENJDK_TARGET_OS_TYPE and/or OPENJDK_TARGET_OS dependent variables for CXXFLAGS. $1_EXTRA_CXXFLAGS := $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS_TYPE)) $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS)) @@ -605,6 +630,9 @@ $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS_TYPE)_release) $1_EXTRA_CXXFLAGS += $$($1_CXXFLAGS_$(OPENJDK_TARGET_OS)_release) endif + ifeq ($(STATIC_LIBS), true) + $1_EXTRA_CXXFLAGS += $$(STATIC_LIB_CFLAGS) + endif # If no C++ flags are explicitly set, default to using the C flags. # After that, we can set additional C++ flags that should not interfere @@ -616,7 +644,7 @@ $1_EXTRA_CXXFLAGS := $$($1_EXTRA_CFLAGS) endif - ifeq ($(COMPILE_WITH_DEBUG_SYMBOLS), true) + ifeq ($$($1_COMPILE_WITH_DEBUG_SYMBOLS), true) $1_EXTRA_CFLAGS += $$(CFLAGS_DEBUG_SYMBOLS) $1_EXTRA_CXXFLAGS += $$(CFLAGS_DEBUG_SYMBOLS) $1_EXTRA_ASFLAGS += $$(ASFLAGS_DEBUG_SYMBOLS) diff -r 12b4063e357f -r 4c036608ca8b make/conf/jib-profiles.js --- a/make/conf/jib-profiles.js Tue Oct 29 15:16:45 2019 +0100 +++ b/make/conf/jib-profiles.js Wed Oct 30 11:23:55 2019 +0100 @@ -247,7 +247,7 @@ // These are the base setttings for all the main build profiles. common.main_profile_base = { dependencies: ["boot_jdk", "gnumake", "jtreg", "jib", "autoconf", "jmh", "jcov"], - default_make_targets: ["product-bundles", "test-bundles"], + default_make_targets: ["product-bundles", "test-bundles", "static-libs-bundles"], 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", @@ -320,6 +320,14 @@ subdir: jdk_subdir, exploded: "images/jdk" }, + static_libs: { + local: "bundles/\\(jdk.*bin-static-libs.tar.gz\\)", + remote: [ + "bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-static-libs.tar.gz", + "bundles/" + pf + "/\\1" + ], + subdir: jdk_subdir, + }, } }; }; @@ -361,6 +369,14 @@ subdir: jdk_subdir, exploded: "images/jdk" }, + static_libs: { + local: "bundles/\\(jdk.*bin-static-libs-debug.tar.gz\\)", + remote: [ + "bundles/" + pf + "/jdk-" + data.version + "_" + pf + "_bin-static-libs-debug.tar.gz", + "bundles/" + pf + "/\\1" + ], + subdir: jdk_subdir, + }, } }; }; diff -r 12b4063e357f -r 4c036608ca8b make/gensrc/GensrcMisc.gmk --- a/make/gensrc/GensrcMisc.gmk Tue Oct 29 15:16:45 2019 +0100 +++ b/make/gensrc/GensrcMisc.gmk Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,8 @@ @@VENDOR_VERSION_STRING@@ => $(VENDOR_VERSION_STRING) ; \ @@VENDOR@@ => $(COMPANY_NAME) ; \ @@VENDOR_URL@@ => $(VENDOR_URL) ; \ - @@VENDOR_URL_BUG@@ => $(VENDOR_URL_BUG), \ + @@VENDOR_URL_BUG@@ => $(VENDOR_URL_BUG) ; \ + @@VENDOR_URL_VM_BUG@@ => $(VENDOR_URL_VM_BUG), \ )) GENSRC_JAVA_BASE += $(BUILD_VERSION_JAVA) diff -r 12b4063e357f -r 4c036608ca8b make/lib/Lib-java.base.gmk --- a/make/lib/Lib-java.base.gmk Tue Oct 29 15:16:45 2019 +0100 +++ b/make/lib/Lib-java.base.gmk Wed Oct 30 11:23:55 2019 +0100 @@ -148,26 +148,27 @@ ############################################################################ # Create symlinks to libjsig in each JVM variant sub dir - LIB_OUTPUTDIR := $(call FindLibDirForModule, java.base) + ifneq ($(STATIC_LIBS), true) + LIB_OUTPUTDIR := $(call FindLibDirForModule, java.base) - # $1 variant subdir - define CreateSymlinks - # Always symlink from libdir/variant/libjsig.so -> ../libjsig.so. - $(LIB_OUTPUTDIR)/$1/$(call SHARED_LIBRARY,jsig): \ - $(LIB_OUTPUTDIR)/$(call SHARED_LIBRARY,jsig) + # $1 variant subdir + define CreateSymlinks + # Always symlink from libdir/variant/libjsig.so -> ../libjsig.so. + $(LIB_OUTPUTDIR)/$1/$(call SHARED_LIBRARY,jsig): \ + $(LIB_OUTPUTDIR)/$(call SHARED_LIBRARY,jsig) $$(call MakeDir, $$(@D)) $(RM) $$@ $(LN) -s ../$$(@F) $$@ - TARGETS += $(LIB_OUTPUTDIR)/$1/$(call SHARED_LIBRARY,jsig) - endef + TARGETS += $(LIB_OUTPUTDIR)/$1/$(call SHARED_LIBRARY,jsig) + endef - # The subdir is the same as the variant for client and minimal, for all - # others it's server. - VARIANT_SUBDIRS := $(filter client minimal, $(JVM_VARIANTS)) \ - $(if $(filter-out client minimal, $(JVM_VARIANTS)), server) - $(foreach v, $(VARIANT_SUBDIRS), $(eval $(call CreateSymlinks,$v))) - + # The subdir is the same as the variant for client and minimal, for all + # others it's server. + VARIANT_SUBDIRS := $(filter client minimal, $(JVM_VARIANTS)) \ + $(if $(filter-out client minimal, $(JVM_VARIANTS)), server) + $(foreach v, $(VARIANT_SUBDIRS), $(eval $(call CreateSymlinks,$v))) + endif ############################################################################ endif diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/.mx.jvmci/suite.py --- a/src/hotspot/.mx.jvmci/suite.py Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/.mx.jvmci/suite.py Wed Oct 30 11:23:55 2019 +0100 @@ -171,7 +171,9 @@ "subDir" : "../../test/hotspot/jtreg/compiler/jvmci", "sourceDirs" : ["src"], "dependencies" : [ + "mx:JUNIT", "TESTNG", + "jdk.vm.ci.code.test", "jdk.vm.ci.hotspot", ], "checkstyle" : "jdk.vm.ci.services", diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/cpu/aarch64/aarch64.ad --- a/src/hotspot/cpu/aarch64/aarch64.ad Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/cpu/aarch64/aarch64.ad Wed Oct 30 11:23:55 2019 +0100 @@ -10413,6 +10413,56 @@ ins_pipe(lmac_reg_reg); %} +// Combine Integer Signed Multiply & Add/Sub/Neg Long + +instruct smaddL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ + match(Set dst (AddL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); + + ins_cost(INSN_COST * 3); + format %{ "smaddl $dst, $src1, $src2, $src3" %} + + ins_encode %{ + __ smaddl(as_Register($dst$$reg), + as_Register($src1$$reg), + as_Register($src2$$reg), + as_Register($src3$$reg)); + %} + + ins_pipe(imac_reg_reg); +%} + +instruct smsubL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, iRegLNoSp src3) %{ + match(Set dst (SubL src3 (MulL (ConvI2L src1) (ConvI2L src2)))); + + ins_cost(INSN_COST * 3); + format %{ "smsubl $dst, $src1, $src2, $src3" %} + + ins_encode %{ + __ smsubl(as_Register($dst$$reg), + as_Register($src1$$reg), + as_Register($src2$$reg), + as_Register($src3$$reg)); + %} + + ins_pipe(imac_reg_reg); +%} + +instruct smnegL(iRegLNoSp dst, iRegIorL2I src1, iRegIorL2I src2, immL0 zero) %{ + match(Set dst (MulL (SubL zero (ConvI2L src1)) (ConvI2L src2))); + match(Set dst (MulL (ConvI2L src1) (SubL zero (ConvI2L src2)))); + + ins_cost(INSN_COST * 3); + format %{ "smnegl $dst, $src1, $src2" %} + + ins_encode %{ + __ smnegl(as_Register($dst$$reg), + as_Register($src1$$reg), + as_Register($src2$$reg)); + %} + + ins_pipe(imac_reg_reg); +%} + // Integer Divide instruct divI(iRegINoSp dst, iRegIorL2I src1, iRegIorL2I src2) %{ diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/classfile/classLoader.cpp --- a/src/hotspot/share/classfile/classLoader.cpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/classfile/classLoader.cpp Wed Oct 30 11:23:55 2019 +0100 @@ -1529,9 +1529,41 @@ // lookup zip library entry points load_zip_library(); - // lookup jimage library entry points + // jimage library entry points are loaded below, in lookup_vm_options + setup_bootstrap_search_path(); +} + +char* lookup_vm_resource(JImageFile *jimage, const char *jimage_version, const char *path) { + jlong size; + JImageLocationRef location = (*JImageFindResource)(jimage, "java.base", jimage_version, path, &size); + if (location == 0) + return NULL; + char *val = NEW_C_HEAP_ARRAY(char, size+1, mtClass); + (*JImageGetResource)(jimage, location, val, size); + val[size] = '\0'; + return val; +} + +// Lookup VM options embedded in the modules jimage file +char* ClassLoader::lookup_vm_options() { + jint error; + char modules_path[JVM_MAXPATHLEN]; + const char* fileSep = os::file_separator(); + + // Initialize jimage library entry points load_jimage_library(); - setup_bootstrap_search_path(); + + jio_snprintf(modules_path, JVM_MAXPATHLEN, "%s%slib%smodules", Arguments::get_java_home(), fileSep, fileSep); + JImageFile* jimage =(*JImageOpen)(modules_path, &error); + if (jimage == NULL) { + return NULL; + } + + const char *jimage_version = get_jimage_version_string(); + char *options = lookup_vm_resource(jimage, jimage_version, "jdk/internal/vm/options"); + + (*JImageClose)(jimage); + return options; } #if INCLUDE_CDS diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/classfile/classLoader.hpp --- a/src/hotspot/share/classfile/classLoader.hpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/classfile/classLoader.hpp Wed Oct 30 11:23:55 2019 +0100 @@ -411,6 +411,9 @@ static char* skip_uri_protocol(char* source); static void record_result(InstanceKlass* ik, const ClassFileStream* stream, TRAPS); #endif + + static char* lookup_vm_options(); + static JImageLocationRef jimage_find_resource(JImageFile* jf, const char* module_name, const char* file_name, jlong &size); diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/classfile/vmSymbols.hpp --- a/src/hotspot/share/classfile/vmSymbols.hpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/classfile/vmSymbols.hpp Wed Oct 30 11:23:55 2019 +0100 @@ -135,6 +135,8 @@ template(java_lang_VersionProps, "java/lang/VersionProps") \ template(java_runtime_name_name, "java_runtime_name") \ template(java_runtime_version_name, "java_runtime_version") \ + template(java_runtime_vendor_version_name, "VENDOR_VERSION") \ + template(java_runtime_vendor_vm_bug_url_name, "VENDOR_URL_VM_BUG") \ \ /* system initialization */ \ template(initPhase1_name, "initPhase1") \ diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/jfr/metadata/metadata.xml --- a/src/hotspot/share/jfr/metadata/metadata.xml Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/jfr/metadata/metadata.xml Wed Oct 30 11:23:55 2019 +0100 @@ -810,8 +810,8 @@ - - + + diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/jfr/periodic/jfrPeriodic.cpp --- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp Wed Oct 30 11:23:55 2019 +0100 @@ -557,8 +557,8 @@ event.set_standardCompileCount(CompileBroker::get_total_standard_compile_count()); event.set_osrBytesCompiled(CompileBroker::get_sum_osr_bytes_compiled()); event.set_standardBytesCompiled(CompileBroker::get_sum_standard_bytes_compiled()); - event.set_nmetodsSize(CompileBroker::get_sum_nmethod_size()); - event.set_nmetodCodeSize(CompileBroker::get_sum_nmethod_code_size()); + event.set_nmethodsSize(CompileBroker::get_sum_nmethod_size()); + event.set_nmethodCodeSize(CompileBroker::get_sum_nmethod_code_size()); event.set_peakTimeSpent(CompileBroker::get_peak_compilation_time()); event.set_totalTimeSpent(CompileBroker::get_total_compilation_time()); event.commit(); diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp Wed Oct 30 11:23:55 2019 +0100 @@ -130,6 +130,7 @@ 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"; default: ShouldNotReachHere(); return ""; } } diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/jvmci/jvmciCompilerToVM.cpp --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Wed Oct 30 11:23:55 2019 +0100 @@ -22,6 +22,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.inline.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" @@ -2032,7 +2033,7 @@ JVMCI_THROW_0(NullPointerException); } InstanceKlass* ik = InstanceKlass::cast(JVMCIENV->asKlass(JVMCIENV->wrap(holder))); - if (ik->class_loader_data()->is_builtin_class_loader_data()) { + if (ik->class_loader_data()->is_boot_class_loader_data() || ik->class_loader_data()->is_platform_class_loader_data()) { return true; } return false; diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/runtime/arguments.cpp --- a/src/hotspot/share/runtime/arguments.cpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/runtime/arguments.cpp Wed Oct 30 11:23:55 2019 +0100 @@ -60,12 +60,6 @@ #include "jfr/jfr.hpp" #endif -// Note: This is a special bug reporting site for the JVM -#ifdef VENDOR_URL_VM_BUG -# define DEFAULT_VENDOR_URL_BUG VENDOR_URL_VM_BUG -#else -# define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp" -#endif #define DEFAULT_JAVA_LAUNCHER "generic" char* Arguments::_jvm_flags_file = NULL; @@ -80,7 +74,7 @@ Arguments::Mode Arguments::_mode = _mixed; bool Arguments::_java_compiler = false; bool Arguments::_xdebug_mode = false; -const char* Arguments::_java_vendor_url_bug = DEFAULT_VENDOR_URL_BUG; +const char* Arguments::_java_vendor_url_bug = NULL; const char* Arguments::_sun_java_launcher = DEFAULT_JAVA_LAUNCHER; bool Arguments::_sun_java_launcher_is_altjvm = false; @@ -1422,12 +1416,16 @@ os::free(old_java_command); } } else if (strcmp(key, "java.vendor.url.bug") == 0) { + // If this property is set on the command line then its value will be + // displayed in VM error logs as the URL at which to submit such logs. + // Normally the URL displayed in error logs is different from the value + // of this system property, so a different property should have been + // used here, but we leave this as-is in case someone depends upon it. const char* old_java_vendor_url_bug = _java_vendor_url_bug; // save it in _java_vendor_url_bug, so JVM fatal error handler can access // its value without going through the property list or making a Java call. _java_vendor_url_bug = os::strdup_check_oom(value, mtArguments); - if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) { - assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL"); + if (old_java_vendor_url_bug != NULL) { os::free((void *)old_java_vendor_url_bug); } } @@ -2185,7 +2183,8 @@ // Parse JavaVMInitArgs structure -jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args, +jint Arguments::parse_vm_init_args(const JavaVMInitArgs *vm_options_args, + const JavaVMInitArgs *java_tool_options_args, const JavaVMInitArgs *java_options_args, const JavaVMInitArgs *cmd_line_args) { bool patch_mod_javabase = false; @@ -2203,9 +2202,15 @@ // Setup flags for mixed which is the default 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); + if (result != JNI_OK) { + return result; + } + // Parse args structure generated from JAVA_TOOL_OPTIONS environment // variable (if present). - jint 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, JVMFlag::ENVIRON_VAR); if (result != JNI_OK) { return result; } @@ -2711,7 +2716,6 @@ needs_module_property_warning = true; continue; } - if (!add_property(tail)) { return JNI_ENOMEM; } @@ -3832,16 +3836,19 @@ const char* hotspotrc = ".hotspotrc"; bool settings_file_specified = false; bool needs_hotspotrc_warning = false; + ScopedVMInitArgs initial_vm_options_args(""); ScopedVMInitArgs initial_java_tool_options_args("env_var='JAVA_TOOL_OPTIONS'"); ScopedVMInitArgs initial_java_options_args("env_var='_JAVA_OPTIONS'"); // Pointers to current working set of containers JavaVMInitArgs* cur_cmd_args; + JavaVMInitArgs* cur_vm_options_args; JavaVMInitArgs* cur_java_options_args; JavaVMInitArgs* cur_java_tool_options_args; // Containers for modified/expanded options ScopedVMInitArgs mod_cmd_args("cmd_line_args"); + ScopedVMInitArgs mod_vm_options_args("vm_options_args"); ScopedVMInitArgs mod_java_tool_options_args("env_var='JAVA_TOOL_OPTIONS'"); ScopedVMInitArgs mod_java_options_args("env_var='_JAVA_OPTIONS'"); @@ -3857,6 +3864,16 @@ return code; } + // Parse the options in the /java.base/jdk/internal/vm/options resource, if present + char *vmoptions = ClassLoader::lookup_vm_options(); + if (vmoptions != NULL) { + code = parse_options_buffer("vm options resource", vmoptions, strlen(vmoptions), &initial_vm_options_args); + FREE_C_HEAP_ARRAY(char, vmoptions); + if (code != JNI_OK) { + return code; + } + } + code = expand_vm_options_as_needed(initial_java_tool_options_args.get(), &mod_java_tool_options_args, &cur_java_tool_options_args); @@ -3878,6 +3895,13 @@ return code; } + code = expand_vm_options_as_needed(initial_vm_options_args.get(), + &mod_vm_options_args, + &cur_vm_options_args); + if (code != JNI_OK) { + return code; + } + const char* flags_file = Arguments::get_jvm_flags_file(); settings_file_specified = (flags_file != NULL); @@ -3915,7 +3939,8 @@ } // Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS - jint result = parse_vm_init_args(cur_java_tool_options_args, + jint result = parse_vm_init_args(cur_vm_options_args, + cur_java_tool_options_args, cur_java_options_args, cur_cmd_args); diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/runtime/arguments.hpp --- a/src/hotspot/share/runtime/arguments.hpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/runtime/arguments.hpp Wed Oct 30 11:23:55 2019 +0100 @@ -427,7 +427,8 @@ static void handle_extra_cms_flags(const char* msg); - static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args, + static jint parse_vm_init_args(const JavaVMInitArgs *vm_options_args, + 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); diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/runtime/flags/jvmFlag.cpp --- a/src/hotspot/share/runtime/flags/jvmFlag.cpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/runtime/flags/jvmFlag.cpp Wed Oct 30 11:23:55 2019 +0100 @@ -709,6 +709,8 @@ st->print("attach"); break; case INTERNAL: st->print("internal"); break; + case JIMAGE_RESOURCE: + st->print("jimage"); break; } st->print("}"); } diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/runtime/flags/jvmFlag.hpp --- a/src/hotspot/share/runtime/flags/jvmFlag.hpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/runtime/flags/jvmFlag.hpp Wed Oct 30 11:23:55 2019 +0100 @@ -44,8 +44,9 @@ ERGONOMIC = 5, ATTACH_ON_DEMAND = 6, INTERNAL = 7, + JIMAGE_RESOURCE = 8, - LAST_VALUE_ORIGIN = INTERNAL, + LAST_VALUE_ORIGIN = JIMAGE_RESOURCE, VALUE_ORIGIN_BITS = 4, VALUE_ORIGIN_MASK = right_n_bits(VALUE_ORIGIN_BITS), diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/runtime/java.cpp --- a/src/hotspot/share/runtime/java.cpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/runtime/java.cpp Wed Oct 30 11:23:55 2019 +0100 @@ -690,6 +690,8 @@ JDK_Version JDK_Version::_current; const char* JDK_Version::_runtime_name; const char* JDK_Version::_runtime_version; +const char* JDK_Version::_runtime_vendor_version; +const char* JDK_Version::_runtime_vendor_vm_bug_url; void JDK_Version::initialize() { jdk_version_info info; diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/runtime/java.hpp --- a/src/hotspot/share/runtime/java.hpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/runtime/java.hpp Wed Oct 30 11:23:55 2019 +0100 @@ -67,6 +67,8 @@ static JDK_Version _current; static const char* _runtime_name; static const char* _runtime_version; + static const char* _runtime_vendor_version; + static const char* _runtime_vendor_vm_bug_url; uint8_t _major; uint8_t _minor; @@ -142,6 +144,20 @@ _runtime_version = version; } + static const char* runtime_vendor_version() { + return _runtime_vendor_version; + } + static void set_runtime_vendor_version(const char* vendor_version) { + _runtime_vendor_version = vendor_version; + } + + static const char* runtime_vendor_vm_bug_url() { + return _runtime_vendor_vm_bug_url; + } + static void set_runtime_vendor_vm_bug_url(const char* vendor_vm_bug_url) { + _runtime_vendor_vm_bug_url = vendor_vm_bug_url; + } + }; #endif // SHARE_RUNTIME_JAVA_HPP diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/runtime/thread.cpp --- a/src/hotspot/share/runtime/thread.cpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/runtime/thread.cpp Wed Oct 30 11:23:55 2019 +0100 @@ -1090,6 +1090,8 @@ char java_runtime_name[128] = ""; char java_runtime_version[128] = ""; +char java_runtime_vendor_version[128] = ""; +char java_runtime_vendor_vm_bug_url[128] = ""; // extract the JRE name from java.lang.VersionProps.java_runtime_name static const char* get_java_runtime_name(TRAPS) { @@ -1135,6 +1137,50 @@ } } +// extract the JRE vendor version from java.lang.VersionProps.VENDOR_VERSION +static const char* get_java_runtime_vendor_version(TRAPS) { + Klass* k = SystemDictionary::find(vmSymbols::java_lang_VersionProps(), + Handle(), Handle(), CHECK_AND_CLEAR_NULL); + fieldDescriptor fd; + bool found = k != NULL && + InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_vendor_version_name(), + vmSymbols::string_signature(), &fd); + if (found) { + oop name_oop = k->java_mirror()->obj_field(fd.offset()); + if (name_oop == NULL) { + return NULL; + } + const char* name = java_lang_String::as_utf8_string(name_oop, + java_runtime_vendor_version, + sizeof(java_runtime_vendor_version)); + return name; + } else { + return NULL; + } +} + +// extract the JRE vendor VM bug URL from java.lang.VersionProps.VENDOR_URL_VM_BUG +static const char* get_java_runtime_vendor_vm_bug_url(TRAPS) { + Klass* k = SystemDictionary::find(vmSymbols::java_lang_VersionProps(), + Handle(), Handle(), CHECK_AND_CLEAR_NULL); + fieldDescriptor fd; + bool found = k != NULL && + InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_vendor_vm_bug_url_name(), + vmSymbols::string_signature(), &fd); + if (found) { + oop name_oop = k->java_mirror()->obj_field(fd.offset()); + if (name_oop == NULL) { + return NULL; + } + const char* name = java_lang_String::as_utf8_string(name_oop, + java_runtime_vendor_vm_bug_url, + sizeof(java_runtime_vendor_vm_bug_url)); + return name; + } else { + return NULL; + } +} + // General purpose hook into Java code, run once when the VM is initialized. // The Java library method itself may be changed independently from the VM. static void call_postVMInitHook(TRAPS) { @@ -3656,9 +3702,11 @@ // Phase 1 of the system initialization in the library, java.lang.System class initialization call_initPhase1(CHECK); - // get the Java runtime name after java.lang.System is initialized + // get the Java runtime name, version, and vendor info after java.lang.System is initialized JDK_Version::set_runtime_name(get_java_runtime_name(THREAD)); JDK_Version::set_runtime_version(get_java_runtime_version(THREAD)); + JDK_Version::set_runtime_vendor_version(get_java_runtime_vendor_version(THREAD)); + JDK_Version::set_runtime_vendor_vm_bug_url(get_java_runtime_vendor_vm_bug_url(THREAD)); // an instance of OutOfMemory exception has been allocated earlier initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK); diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/runtime/vmStructs.cpp --- a/src/hotspot/share/runtime/vmStructs.cpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/runtime/vmStructs.cpp Wed Oct 30 11:23:55 2019 +0100 @@ -2612,6 +2612,7 @@ declare_constant(JVMFlag::ERGONOMIC) \ declare_constant(JVMFlag::ATTACH_ON_DEMAND) \ declare_constant(JVMFlag::INTERNAL) \ + declare_constant(JVMFlag::JIMAGE_RESOURCE) \ declare_constant(JVMFlag::VALUE_ORIGIN_MASK) \ declare_constant(JVMFlag::ORIG_COMMAND_LINE) diff -r 12b4063e357f -r 4c036608ca8b src/hotspot/share/utilities/vmError.cpp --- a/src/hotspot/share/utilities/vmError.cpp Tue Oct 29 15:16:45 2019 +0100 +++ b/src/hotspot/share/utilities/vmError.cpp Wed Oct 30 11:23:55 2019 +0100 @@ -128,9 +128,14 @@ static void print_bug_submit_message(outputStream *out, Thread *thread) { if (out == NULL) return; - out->print_raw_cr("# If you would like to submit a bug report, please visit:"); - out->print_raw ("# "); - out->print_raw_cr(Arguments::java_vendor_url_bug()); + const char *url = Arguments::java_vendor_url_bug(); + if (url == NULL || *url == '\0') + url = JDK_Version::runtime_vendor_vm_bug_url(); + if (url != NULL && *url != '\0') { + out->print_raw_cr("# If you would like to submit a bug report, please visit:"); + out->print_raw ("# "); + out->print_raw_cr(url); + } // If the crash is in native code, encourage user to submit a bug to the // provider of that code. if (thread && thread->is_Java_thread() && @@ -321,15 +326,19 @@ JDK_Version::runtime_name() : ""; const char* runtime_version = JDK_Version::runtime_version() != NULL ? JDK_Version::runtime_version() : ""; + const char* vendor_version = JDK_Version::runtime_vendor_version() != NULL ? + JDK_Version::runtime_vendor_version() : ""; const char* jdk_debug_level = VM_Version::printable_jdk_debug_level() != NULL ? VM_Version::printable_jdk_debug_level() : ""; - st->print_cr("# JRE version: %s (%s) (%sbuild %s)", runtime_name, buf, - jdk_debug_level, runtime_version); + st->print_cr("# JRE version: %s%s%s (%s) (%sbuild %s)", runtime_name, + (*vendor_version != '\0') ? " " : "", vendor_version, + buf, jdk_debug_level, runtime_version); // This is the long version with some default settings added - st->print_cr("# Java VM: %s (%s%s, %s%s%s%s%s, %s, %s)", + st->print_cr("# Java VM: %s%s%s (%s%s, %s%s%s%s%s, %s, %s)", VM_Version::vm_name(), + (*vendor_version != '\0') ? " " : "", vendor_version, jdk_debug_level, VM_Version::vm_release(), VM_Version::vm_info_string(), diff -r 12b4063e357f -r 4c036608ca8b src/java.base/share/classes/java/lang/VersionProps.java.template --- a/src/java.base/share/classes/java/lang/VersionProps.java.template Tue Oct 29 15:16:45 2019 +0100 +++ b/src/java.base/share/classes/java/lang/VersionProps.java.template Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,9 +42,11 @@ private static final String java_version_date = "@@VERSION_DATE@@"; + // This field is read by HotSpot private static final String java_runtime_name = "@@RUNTIME_NAME@@"; + // This field is read by HotSpot private static final String java_runtime_version = "@@VERSION_STRING@@"; @@ -69,22 +71,26 @@ private static final String CLASSFILE_MAJOR_MINOR = "@@VERSION_CLASSFILE_MAJOR@@.@@VERSION_CLASSFILE_MINOR@@"; - private static final String VENDOR_VERSION_STRING = - "@@VENDOR_VERSION_STRING@@"; - - private static final String vendor_version = - (!VENDOR_VERSION_STRING.isEmpty() - ? " " + VENDOR_VERSION_STRING : ""); - private static final String VENDOR = "@@VENDOR@@"; private static final String VENDOR_URL = "@@VENDOR_URL@@"; - private static final String VENDOR_URL_BUG = + // The remaining VENDOR_* fields must not be final, + // so that they can be redefined by jlink plugins + + // This field is read by HotSpot + private static String VENDOR_VERSION = + "@@VENDOR_VERSION_STRING@@"; + + private static String VENDOR_URL_BUG = "@@VENDOR_URL_BUG@@"; + // This field is read by HotSpot + private static String VENDOR_URL_VM_BUG = + "@@VENDOR_URL_VM_BUG@@"; + /** * Initialize system properties using build provided values. * @@ -95,8 +101,8 @@ props.put("java.version.date", java_version_date); props.put("java.runtime.version", java_runtime_version); props.put("java.runtime.name", java_runtime_name); - if (!VENDOR_VERSION_STRING.isEmpty()) - props.put("java.vendor.version", VENDOR_VERSION_STRING); + if (!VENDOR_VERSION.isEmpty()) + props.put("java.vendor.version", VENDOR_VERSION); props.put("java.class.version", CLASSFILE_MAJOR_MINOR); @@ -216,6 +222,9 @@ jdk_debug_level = jdk_debug_level + " "; } + String vendor_version = (VENDOR_VERSION.isEmpty() + ? "" : " " + VENDOR_VERSION); + ps.println(java_runtime_name + vendor_version + " (" + jdk_debug_level + "build " + java_runtime_version + ")"); diff -r 12b4063e357f -r 4c036608ca8b src/java.base/share/classes/java/lang/invoke/MethodHandles.java --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Wed Oct 30 11:23:55 2019 +0100 @@ -203,7 +203,7 @@ * @param targetClass the target class * @param caller the caller lookup object * @return a lookup object for the target class, with private access - * @throws IllegalArgumentException if {@code targetClass} is a primitive type or array class + * @throws IllegalArgumentException if {@code targetClass} is a primitive type or void or array class * @throws NullPointerException if {@code targetClass} or {@code caller} is {@code null} * @throws SecurityException if denied by the security manager * @throws IllegalAccessException if any of the other access checks specified above fails @@ -1385,7 +1385,7 @@ private Lookup(Class lookupClass, Class prevLookupClass, int allowedModes) { assert prevLookupClass == null || ((allowedModes & MODULE) == 0 && prevLookupClass.getModule() != lookupClass.getModule()); - + assert !lookupClass.isArray() && !lookupClass.isPrimitive(); this.lookupClass = lookupClass; this.prevLookupClass = prevLookupClass; this.allowedModes = allowedModes; @@ -1443,6 +1443,7 @@ * @param requestedLookupClass the desired lookup class for the new lookup object * @return a lookup object which reports the desired lookup class, or the same object * if there is no change + * @throws IllegalArgumentException if {@code requestedLookupClass} is a primitive type or void or array class * @throws NullPointerException if the argument is null * * @revised 9 @@ -1452,6 +1453,11 @@ */ public Lookup in(Class requestedLookupClass) { Objects.requireNonNull(requestedLookupClass); + if (requestedLookupClass.isPrimitive()) + throw new IllegalArgumentException(requestedLookupClass + " is a primitive class"); + if (requestedLookupClass.isArray()) + throw new IllegalArgumentException(requestedLookupClass + " is an array class"); + if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all return new Lookup(requestedLookupClass, null, FULL_POWER_MODES); if (requestedLookupClass == this.lookupClass) diff -r 12b4063e357f -r 4c036608ca8b src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Flags.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Flags.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Flags.java Wed Oct 30 11:23:55 2019 +0100 @@ -35,7 +35,8 @@ MANAGEMENT ("Management"), ERGONOMIC ("Ergonomic"), ATTACH_ON_DEMAND ("Attach on demand"), - INTERNAL ("Internal"); + INTERNAL ("Internal"), + JIMAGE_RESOURCE ("JImage"); private final String value; diff -r 12b4063e357f -r 4c036608ca8b src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java Wed Oct 30 11:23:55 2019 +0100 @@ -114,6 +114,7 @@ public static int Flags_ERGONOMIC; public static int Flags_ATTACH_ON_DEMAND; 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; /** This is only present in a non-core build */ @@ -200,6 +201,8 @@ return "attach"; } else if (origin == Flags_INTERNAL) { return "internal"; + } else if (origin == Flags_JIMAGE_RESOURCE) { + return "jimage"; } else { throw new IllegalStateException( "Unknown flag origin " + origin + " is detected in " + name); @@ -484,6 +487,7 @@ 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_VALUE_ORIGIN_MASK = db.lookupIntConstant("JVMFlag::VALUE_ORIGIN_MASK").intValue(); Flags_ORIG_COMMAND_LINE = db.lookupIntConstant("JVMFlag::ORIG_COMMAND_LINE").intValue(); oopSize = db.lookupIntConstant("oopSize").intValue(); diff -r 12b4063e357f -r 4c036608ca8b src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualObject.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualObject.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualObject.java Wed Oct 30 11:23:55 2019 +0100 @@ -22,11 +22,11 @@ */ package jdk.vm.ci.code; -import java.util.Arrays; import java.util.Collections; import java.util.IdentityHashMap; import java.util.Set; +import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaValue; import jdk.vm.ci.meta.ResolvedJavaField; @@ -74,8 +74,8 @@ * @param id a unique id that identifies the object within the debug information for one * position in the compiled code. * @param isAutoBox a flag that tells the runtime that the object may be a boxed primitive and - * that it possibly needs to be obtained for the box cache instead of creating - * a new instance. + * that it possibly needs to be obtained for the box cache instead of creating a new + * instance. * @return a new {@link VirtualObject} instance. */ public static VirtualObject get(ResolvedJavaType type, int id, boolean isAutoBox) { @@ -108,14 +108,32 @@ } } else { ResolvedJavaField[] fields = vo.type.getInstanceFields(true); - assert fields.length == vo.values.length : vo.type + ", fields=" + Arrays.toString(fields) + ", values=" + Arrays.toString(vo.values); - for (int i = 0; i < vo.values.length; i++) { + int fieldIndex = 0; + for (int i = 0; i < vo.values.length; i++, fieldIndex++) { if (i != 0) { buf.append(','); } - buf.append(fields[i].getName()).append('='); + if (fieldIndex >= fields.length) { + buf.append(""); + } else { + ResolvedJavaField field = fields[fieldIndex]; + buf.append(field.getName()); + if (vo.slotKinds[i].getSlotCount() == 2 && field.getType().getJavaKind().getSlotCount() == 1) { + if (fieldIndex + 1 >= fields.length) { + buf.append("/"); + } else { + ResolvedJavaField field2 = fields[++fieldIndex]; + buf.append('/').append(field2.getName()); + } + } + } + buf.append('='); appendValue(buf, vo.values[i], visited); } + // Extra fields + for (; fieldIndex < fields.length; fieldIndex++) { + buf.append(fields[fieldIndex].getName()).append("="); + } } } buf.append('}'); @@ -126,6 +144,55 @@ return buf; } + public interface LayoutVerifier { + int getOffset(ResolvedJavaField field); + + default JavaKind getStorageKind(ResolvedJavaField field) { + return field.getType().getJavaKind(); + } + } + + public void verifyLayout(LayoutVerifier verifier) { + if (!type.isArray()) { + ResolvedJavaField[] fields = type.getInstanceFields(true); + int fieldIndex = 0; + for (int i = 0; i < values.length; i++, fieldIndex++) { + JavaKind slotKind = slotKinds[i]; + if (fieldIndex >= fields.length) { + throw new JVMCIError("Not enough fields for the values provided for %s", toString()); + } else { + ResolvedJavaField field = fields[fieldIndex]; + JavaKind fieldKind = verifier.getStorageKind(field); + if (slotKind.getSlotCount() == 2 && fieldKind == JavaKind.Int) { + int offset = verifier.getOffset(field); + if (offset % 8 != 0) { + throw new JVMCIError("Double word value stored across two ints must be aligned %s", toString()); + } + + if (fieldIndex + 1 >= fields.length) { + throw new JVMCIError("Missing second field for double word value stored in two ints %s", toString()); + } + ResolvedJavaField field2 = fields[fieldIndex + 1]; + if (field2.getType().getJavaKind() != JavaKind.Int) { + throw new JVMCIError("Second field for double word value stored in two ints must be int but got %s in %s", field2.getType().getJavaKind(), toString()); + } + int offset2 = verifier.getOffset(field2); + if (offset + 4 != offset2) { + throw new JVMCIError("Double word value stored across two ints must be sequential %s", toString()); + } + fieldIndex++; + } else if (fieldKind.getStackKind() != slotKind.getStackKind()) { + throw new JVMCIError("Expected value of kind %s but got %s for field %s in %s", fieldKind, slotKind, field, toString()); + } + } + } + // Extra fields + if (fieldIndex < fields.length) { + throw new JVMCIError("Not enough values provided for fields in %s", this); + } + } + } + @Override public String toString() { Set visited = Collections.newSetFromMap(new IdentityHashMap()); @@ -170,16 +237,18 @@ * the box is in the cache range and try to return a cached object. */ public boolean isAutoBox() { - return isAutoBox; + return isAutoBox; } /** * Sets the value of the box flag. - * @param isAutoBox a flag that tells the runtime that the object may be a boxed primitive and that - * it possibly needs to be obtained for the box cache instead of creating a new instance. + * + * @param isAutoBox a flag that tells the runtime that the object may be a boxed primitive and + * that it possibly needs to be obtained for the box cache instead of creating a new + * instance. */ public void setIsAutoBox(boolean isAutoBox) { - this.isAutoBox = isAutoBox; + this.isAutoBox = isAutoBox; } /** diff -r 12b4063e357f -r 4c036608ca8b src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java Wed Oct 30 11:23:55 2019 +0100 @@ -32,7 +32,7 @@ * A cleaner tracks a referent object and includes some {@linkplain #doCleanup() cleanup code} that * is run some time after the referent object has become weakly-reachable. * - * This is like {@link sun.misc.Cleaner} but with weak semantics instead of phantom. Objects + * This is like {@link java.lang.ref.Cleaner} but with weak semantics instead of phantom. Objects * referenced by this might be referenced by {@link ResolvedJavaType} which is kept alive by a * {@link WeakReference} so we need equivalent reference strength. */ diff -r 12b4063e357f -r 4c036608ca8b src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Oct 30 11:23:55 2019 +0100 @@ -56,7 +56,7 @@ private static native void registerNatives(); /** - * These values mirror the equivalent values from {@link Unsafe} but are approriate for the JVM + * These values mirror the equivalent values from {@code Unsafe} but are appropriate for the JVM * being compiled against. */ // Checkstyle: stop @@ -514,10 +514,10 @@ /** * Reads an object pointer within a VM data structure. That is, any {@link VMField} whose - * {@link VMField#type type} is {@code "oop"} (e.g., - * {@code Klass::_java_mirror}, {@code JavaThread::_threadObj}). + * {@link VMField#type type} is {@code "oop"} (e.g., {@code Klass::_java_mirror}, + * {@code JavaThread::_threadObj}). * - * Note that {@link Unsafe#getObject(Object, long)} cannot be used for this since it does a + * Note that {@code Unsafe.getObject(Object, long)} cannot be used for this since it does a * {@code narrowOop} read if the VM is using compressed oops whereas oops within VM data * structures are (currently) always uncompressed. * diff -r 12b4063e357f -r 4c036608ca8b src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,12 @@ import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.code.CompiledCode; import jdk.vm.ci.code.StackSlot; +import jdk.vm.ci.code.VirtualObject; import jdk.vm.ci.code.site.DataPatch; import jdk.vm.ci.code.site.Infopoint; import jdk.vm.ci.code.site.Site; import jdk.vm.ci.meta.Assumptions.Assumption; +import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; /** @@ -156,9 +158,23 @@ if (info.debugInfo != null) { BytecodeFrame frame = info.debugInfo.frame(); assert frame == null || frame.validateFormat(); + if (info.debugInfo.getVirtualObjectMapping() != null) { + for (VirtualObject v : info.debugInfo.getVirtualObjectMapping()) { + verifyVirtualObject(v); + } + } } } } return true; } + + public static void verifyVirtualObject(VirtualObject v) { + v.verifyLayout(new VirtualObject.LayoutVerifier() { + @Override + public int getOffset(ResolvedJavaField field) { + return field.getOffset(); + } + }); + } } diff -r 12b4063e357f -r 4c036608ca8b src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Wed Oct 30 11:23:55 2019 +0100 @@ -31,25 +31,19 @@ import java.io.OutputStream; import java.io.PrintStream; import java.io.Serializable; - import java.lang.invoke.CallSite; import java.lang.invoke.ConstantCallSite; import java.lang.invoke.MethodHandle; -import java.lang.module.ModuleDescriptor.Requires; import java.lang.ref.WeakReference; - import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.ServiceLoader; import java.util.function.Predicate; -import jdk.internal.misc.Unsafe; - import jdk.vm.ci.code.Architecture; import jdk.vm.ci.code.CompilationRequestResult; import jdk.vm.ci.code.CompiledCode; @@ -187,9 +181,15 @@ // initialized. JVMCI.getRuntime(); } - // Make sure all the primitive box caches are populated (required to properly materialize boxed primitives + // Make sure all the primitive box caches are populated (required to properly + // materialize boxed primitives // during deoptimization). - Object[] boxCaches = { Boolean.valueOf(false), Byte.valueOf((byte)0), Short.valueOf((short) 0), Character.valueOf((char) 0), Integer.valueOf(0), Long.valueOf(0) }; + Boolean.valueOf(false); + Byte.valueOf((byte) 0); + Short.valueOf((short) 0); + Character.valueOf((char) 0); + Integer.valueOf(0); + Long.valueOf(0); } } return result; @@ -338,7 +338,7 @@ private static HotSpotJVMCIBackendFactory findFactory(String architecture) { Iterable factories = getHotSpotJVMCIBackendFactories(); -assert factories != null : "sanity"; + assert factories != null : "sanity"; for (HotSpotJVMCIBackendFactory factory : factories) { if (factory.getArchitecture().equalsIgnoreCase(architecture)) { return factory; @@ -391,33 +391,35 @@ @NativeImageReinitialize private volatile ClassValue> resolvedJavaType; /** - * To avoid calling ClassValue.remove to refresh the weak reference, which - * under certain circumstances can lead to an infinite loop, we use a - * permanent holder with a mutable field that we refresh. + * To avoid calling ClassValue.remove to refresh the weak reference, which under certain + * circumstances can lead to an infinite loop, we use a permanent holder with a mutable field + * that we refresh. */ private static class WeakReferenceHolder { private volatile WeakReference ref; + WeakReferenceHolder(T value) { set(value); } + void set(T value) { - ref = new WeakReference(value); + ref = new WeakReference<>(value); } + T get() { return ref.get(); } - }; + } @NativeImageReinitialize private HashMap> resolvedJavaTypes; /** - * Stores the value set by {@link #excludeFromJVMCICompilation(Module...)} so that it can - * be read from the VM. + * Stores the value set by {@link #excludeFromJVMCICompilation(Module...)} so that it can be + * read from the VM. */ @SuppressWarnings("unused")// @NativeImageReinitialize private Module[] excludeFromJVMCICompilation; - private final Map, JVMCIBackend> backends = new HashMap<>(); private volatile List vmEventListeners; @@ -508,7 +510,7 @@ if (resolvedJavaType == null) { synchronized (this) { if (resolvedJavaType == null) { - resolvedJavaType = new ClassValue>() { + resolvedJavaType = new ClassValue<>() { @Override protected WeakReferenceHolder computeValue(Class type) { return new WeakReferenceHolder<>(createClass(type)); @@ -522,8 +524,7 @@ HotSpotResolvedJavaType javaType = ref.get(); if (javaType == null) { /* - * If the referent has become null, create a new value and - * update cached weak reference. + * If the referent has become null, create a new value and update cached weak reference. */ javaType = createClass(javaClass); ref.set(javaType); @@ -591,7 +592,7 @@ * compiler. */ public Predicate getIntrinsificationTrustPredicate(Class... compilerLeafClasses) { - return new Predicate() { + return new Predicate<>() { @Override public boolean test(ResolvedJavaType type) { if (type instanceof HotSpotResolvedObjectTypeImpl) { diff -r 12b4063e357f -r 4c036608ca8b src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Wed Oct 30 11:23:55 2019 +0100 @@ -563,6 +563,10 @@ * a deopt instead since they can't really be used if they aren't linked yet. */ if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder) || !isLinked() || isInterface()) { + if (hmethod.canBeStaticallyBound()) { + // No assumptions are required. + return new AssumptionResult<>(hmethod); + } ResolvedJavaMethod result = hmethod.uniqueConcreteMethod(declaredHolder); if (result != null) { return new AssumptionResult<>(result, new ConcreteMethod(method, declaredHolder, result)); diff -r 12b4063e357f -r 4c036608ca8b src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ package jdk.vm.ci.services; import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE; -import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; import java.util.ArrayList; import java.util.List; @@ -81,7 +80,7 @@ result = ServiceLoader.load(JVMCIServiceLocator.class, ClassLoader.getSystemClassLoader()); if (IS_BUILDING_NATIVE_IMAGE) { ArrayList l = new ArrayList<>(); - for (JVMCIServiceLocator locator: result) { + for (JVMCIServiceLocator locator : result) { l.add(locator); } l.trimToSize(); diff -r 12b4063e357f -r 4c036608ca8b src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java Wed Oct 30 11:23:55 2019 +0100 @@ -33,7 +33,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Properties; import java.util.ServiceLoader; import java.util.Set; @@ -45,9 +44,6 @@ */ public final class Services { - // This class must be compilable and executable on JDK 8 since it's used in annotation - // processors while building JDK 9 so use of API added in JDK 9 is made via reflection. - /** * Guards code that should be run when building an JVMCI shared library but should be excluded * from (being compiled into) the library. Such code must be directly guarded by an {@code if} @@ -73,8 +69,12 @@ private Services() { } - private static volatile Map savedProperties = VM.getSavedProperties(); - static final boolean JVMCI_ENABLED = Boolean.parseBoolean(savedProperties.get("jdk.internal.vm.ci.enabled")); + /** + * In a native image, this field is initialized by {@link #initializeSavedProperties(byte[])}. + */ + private static volatile Map savedProperties; + + static final boolean JVMCI_ENABLED = Boolean.parseBoolean(VM.getSavedProperties().get("jdk.internal.vm.ci.enabled")); /** * Checks that JVMCI is enabled in the VM and throws an error if it isn't. @@ -90,9 +90,22 @@ */ public static Map getSavedProperties() { checkJVMCIEnabled(); - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new JVMCIPermission()); + if (IS_IN_NATIVE_IMAGE) { + if (savedProperties == null) { + throw new InternalError("Saved properties not initialized"); + } + } else { + if (savedProperties == null) { + synchronized (Services.class) { + if (savedProperties == null) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new JVMCIPermission()); + } + savedProperties = VM.getSavedProperties(); + } + } + } } return savedProperties; } diff -r 12b4063e357f -r 4c036608ca8b src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/SuppressFBWarnings.java --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/SuppressFBWarnings.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/SuppressFBWarnings.java Wed Oct 30 11:23:55 2019 +0100 @@ -4,9 +4,7 @@ * * This code is free software; you can redistribute 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. + * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Wed Oct 30 11:23:55 2019 +0100 @@ -50,6 +50,7 @@ static { CATEGORIES_ORDER.add(Category.FILTER); + CATEGORIES_ORDER.add(Category.ADDER); CATEGORIES_ORDER.add(Category.TRANSFORMER); CATEGORIES_ORDER.add(Category.MODULEINFO_TRANSFORMER); CATEGORIES_ORDER.add(Category.SORTER); diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -325,7 +325,7 @@ Map m = addArgumentMap(plugin); // handle one or more arguments - if (arg.indexOf(':') == -1) { + if (plugin.hasRawArgument() || arg.indexOf(':') == -1) { // single argument case m.put(option, arg); } else { diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddOptionsPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddOptionsPlugin.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.tools.jlink.internal.plugins; + +import java.io.*; +import java.nio.charset.*; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import jdk.tools.jlink.plugin.*; + +/** + * Plugin to add VM command-line options, by storing them in a resource + * that's read by the VM at startup + */ +public final class AddOptionsPlugin extends AddResourcePlugin { + + public AddOptionsPlugin() { + super("add-options", "/java.base/jdk/internal/vm/options"); + } + +} diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddResourcePlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/AddResourcePlugin.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.tools.jlink.internal.plugins; + +import java.io.*; +import java.nio.charset.*; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import jdk.tools.jlink.plugin.*; + +/** + * Base plugin to add a resource + */ +abstract class AddResourcePlugin implements Plugin { + + private final String name; + private final String path; + private String value; + + protected AddResourcePlugin(String n, String p) { + name = n; + path = p; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return PluginsResourceBundle.getDescription(name); + } + + @Override + public Category getType() { + return Category.ADDER; + } + + @Override + public boolean hasArguments() { + return true; + } + + @Override + public boolean hasRawArgument() { + return true; + } + + @Override + public String getArgumentsDescription() { + return PluginsResourceBundle.getArgument(name); + } + + @Override + public void configure(Map config) { + var v = config.get(name); + if (v == null) + throw new AssertionError(); + value = v; + } + + @Override + public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) { + in.transformAndCopy(Function.identity(), out); + out.add(ResourcePoolEntry.create(path, + value.getBytes(StandardCharsets.UTF_8))); + return out.build(); + } + +} diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java Wed Oct 30 11:23:55 2019 +0100 @@ -36,7 +36,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; -import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.internal.access.SharedSecrets; import jdk.internal.access.JavaLangInvokeAccess; @@ -75,13 +74,13 @@ private static final JavaLangInvokeAccess JLIA = SharedSecrets.getJavaLangInvokeAccess(); - Set speciesTypes = Set.of(); + private final TreeSet speciesTypes = new TreeSet<>(); - Set invokerTypes = Set.of(); + private final TreeSet invokerTypes = new TreeSet<>(); - Set callSiteTypes = Set.of(); + private final TreeSet callSiteTypes = new TreeSet<>(); - Map> dmhMethods = Map.of(); + private final Map> dmhMethods = new TreeMap<>(); String mainArgument; @@ -187,21 +186,31 @@ mainArgument = config.get(NAME); } + private void addSpeciesType(String type) { + speciesTypes.add(expandSignature(type)); + } + + private void addInvokerType(String methodType) { + validateMethodType(methodType); + invokerTypes.add(methodType); + } + + private void addCallSiteType(String csType) { + validateMethodType(csType); + callSiteTypes.add(csType); + } + public void initialize(ResourcePool in) { // Start with the default configuration - speciesTypes = defaultSpecies().stream() - .map(type -> expandSignature(type)) - .collect(Collectors.toSet()); + defaultSpecies().stream().forEach(this::addSpeciesType); - invokerTypes = defaultInvokers(); - validateMethodTypes(invokerTypes); + defaultInvokers().stream().forEach(this::validateMethodType); - callSiteTypes = defaultCallSiteTypes(); + defaultCallSiteTypes().stream().forEach(this::addCallSiteType); - dmhMethods = defaultDMHMethods(); - for (Set dmhMethodTypes : dmhMethods.values()) { - validateMethodTypes(dmhMethodTypes); - } + defaultDMHMethods().entrySet().stream().forEach(e -> { + e.getValue().stream().forEach(type -> addDMHMethodType(e.getKey(), type)); + }); // Extend the default configuration with the contents in the supplied // input file - if none was supplied we look for the default file @@ -225,18 +234,6 @@ } private void readTraceConfig(Stream lines) { - // Use TreeSet/TreeMap to keep things sorted in a deterministic - // order to avoid scrambling the layout on small changes and to - // ease finding methods in the generated code - speciesTypes = new TreeSet<>(speciesTypes); - invokerTypes = new TreeSet<>(invokerTypes); - callSiteTypes = new TreeSet<>(callSiteTypes); - - TreeMap> newDMHMethods = new TreeMap<>(); - for (Map.Entry> entry : dmhMethods.entrySet()) { - newDMHMethods.put(entry.getKey(), new TreeSet<>(entry.getValue())); - } - dmhMethods = newDMHMethods; lines.map(line -> line.split(" ")) .forEach(parts -> { switch (parts[0]) { @@ -245,19 +242,18 @@ if (parts.length == 3 && parts[1].startsWith("java.lang.invoke.BoundMethodHandle$Species_")) { String species = parts[1].substring("java.lang.invoke.BoundMethodHandle$Species_".length()); if (!"L".equals(species)) { - speciesTypes.add(expandSignature(species)); + addSpeciesType(species); } } break; case "[LF_RESOLVE]": String methodType = parts[3]; - validateMethodType(methodType); if (parts[1].equals(INVOKERS_HOLDER_NAME)) { if ("linkToTargetMethod".equals(parts[2]) || "linkToCallSite".equals(parts[2])) { - callSiteTypes.add(methodType); + addCallSiteType(methodType); } else { - invokerTypes.add(methodType); + addInvokerType(methodType); } } else if (parts[1].contains("DirectMethodHandle")) { String dmh = parts[2]; @@ -291,12 +287,6 @@ } } - private void validateMethodTypes(Set dmhMethodTypes) { - for (String type : dmhMethodTypes) { - validateMethodType(type); - } - } - private void validateMethodType(String type) { String[] typeParts = type.split("_"); // check return type (second part) @@ -340,9 +330,10 @@ generateHolderClasses(out); // Let it go - speciesTypes = null; - invokerTypes = null; - dmhMethods = null; + speciesTypes.clear(); + invokerTypes.clear(); + callSiteTypes.clear(); + dmhMethods.clear(); return out.build(); } diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VendorBugURLPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VendorBugURLPlugin.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.tools.jlink.internal.plugins; + +/** + * Plugin to set the vendor bug URL, by redefining the static field + * java.lang.VersionProps.VENDOR_URL_BUG + */ +public final class VendorBugURLPlugin extends VersionPropsPlugin { + + public VendorBugURLPlugin() { + super("VENDOR_URL_BUG", "vendor-bug-url"); + } + +} diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VendorVMBugURLPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VendorVMBugURLPlugin.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.tools.jlink.internal.plugins; + +/** + * Plugin to set the vendor VM bug URL, by redefining the static field + * java.lang.VersionProps.VENDOR_URL_VM_BUG + */ +public final class VendorVMBugURLPlugin extends VersionPropsPlugin { + + public VendorVMBugURLPlugin() { + super("VENDOR_URL_VM_BUG", "vendor-vm-bug-url"); + } + +} diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VendorVersionPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VendorVersionPlugin.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.tools.jlink.internal.plugins; + +/** + * Plugin to set the vendor version string, by redefining the static field + * java.lang.VersionProps.VENDOR_VERSION + */ +public final class VendorVersionPlugin extends VersionPropsPlugin { + + public VendorVersionPlugin() { + super("VENDOR_VERSION"); + } + +} diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VersionPropsPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/VersionPropsPlugin.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.tools.jlink.internal.plugins; + +import java.io.*; +import java.nio.charset.*; +import java.util.*; +import java.util.function.*; +import java.util.stream.*; +import jdk.tools.jlink.plugin.*; +import jdk.internal.org.objectweb.asm.*; + +import static java.lang.System.out; + +/** + * Base plugin to update a static field in java.lang.VersionProps + */ +abstract class VersionPropsPlugin implements Plugin { + + private static final String VERSION_PROPS_CLASS + = "/java.base/java/lang/VersionProps.class"; + + private final String name; + private final String field; + private String value; + + /** + * @param field The name of the java.lang.VersionProps field to be redefined + * @param option The option name + */ + protected VersionPropsPlugin(String field, String option) { + this.field = field; + this.name = option; + } + + /** + * Shorthand constructor for when the option name can be derived from the + * name of the field. + * + * @param field The name of the java.lang.VersionProps field to be redefined + */ + protected VersionPropsPlugin(String field) { + this(field, field.toLowerCase().replace('_', '-')); + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return PluginsResourceBundle.getDescription(name); + } + + @Override + public Category getType() { + return Category.TRANSFORMER; + } + + @Override + public boolean hasArguments() { + return true; + } + + @Override + public boolean hasRawArgument() { + return true; + } + + @Override + public String getArgumentsDescription() { + return PluginsResourceBundle.getArgument(name); + } + + @Override + public void configure(Map config) { + var v = config.get(name); + if (v == null) + throw new AssertionError(); + value = v; + } + + private boolean redefined = false; + + private byte[] redefine(byte[] classFile) { + + var cr = new ClassReader(classFile); + var cw = new ClassWriter(0); + + cr.accept(new ClassVisitor(Opcodes.ASM7, cw) { + + public MethodVisitor visitMethod(int access, + String name, + String desc, + String sig, + String[] xs) + { + if (name.equals("")) + return new MethodVisitor(Opcodes.ASM7, + super.visitMethod(access, + name, + desc, + sig, + xs)) + { + + public void visitFieldInsn(int opcode, + String owner, + String name, + String desc) + { + if (opcode == Opcodes.PUTSTATIC + && name.equals(field)) + { + // Discard the original value + super.visitInsn(Opcodes.POP); + // Load the value that we want + super.visitLdcInsn(value); + redefined = true; + } + super.visitFieldInsn(opcode, owner, + name, desc); + } + + }; + else + return super.visitMethod(access, name, desc, sig, xs); + } + + }, 0); + + return cw.toByteArray(); + + } + + @Override + public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) { + in.transformAndCopy(res -> { + if (res.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) { + if (res.path().equals(VERSION_PROPS_CLASS)) { + return res.copyWithContent(redefine(res.contentBytes())); + } + } + return res; + }, out); + if (!redefined) + throw new AssertionError(field); + return out.build(); + } + +} diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ * Order of categories matches the plugin sort order. *
    *
  1. FILTER: Filter in/out resources or files.
  2. + *
  3. ADDER: Add resources or files.
  4. *
  5. TRANSFORMER: Transform resources or files(eg: refactoring, bytecode * manipulation).
  6. *
  7. MODULEINFO_TRANSFORMER: Transform only module-info.class
  8. @@ -52,6 +53,7 @@ */ public enum Category { FILTER("FILTER"), + ADDER("ADDER"), TRANSFORMER("TRANSFORMER"), MODULEINFO_TRANSFORMER("MODULEINFO_TRANSFORMER"), SORTER("SORTER"), @@ -152,6 +154,10 @@ return false; } + public default boolean hasRawArgument() { + return false; + } + /** * The plugin argument(s) description. * @return The argument(s) description. diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,13 @@ # questions. # +add-options.argument= + +add-options.description=\ +Prepend the specified string, which may include\n\ +whitespace, before any other options when invoking the virtual machine\n\ +in the resulting image. + release-info.argument=|add:=:=:...|del: release-info.description=\ @@ -105,6 +112,24 @@ strip-native-commands.description=\ Exclude native commands (such as java/java.exe) from the image +vendor-version.argument= + +vendor-version.description=\ +Override the vendor version string baked into the build, if any.\n\ +The value of the system property "java.vendor.version" will be . + +vendor-bug-url.argument= + +vendor-bug-url.description=\ +Override the vendor bug URL baked into the build. The value\n\ +of the system property "java.vendor.url.bug" will be . + +vendor-vm-bug-url.argument= + +vendor-vm-bug-url.description=\ +Override the vendor VM bug URL baked into the build. The URL\n\ +displayed in VM error logs will be . + vm.argument= vm.description=\ diff -r 12b4063e357f -r 4c036608ca8b src/jdk.jlink/share/classes/module-info.java --- a/src/jdk.jlink/share/classes/module-info.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.jlink/share/classes/module-info.java Wed Oct 30 11:23:55 2019 +0100 @@ -72,5 +72,10 @@ jdk.tools.jlink.internal.plugins.ExcludeVMPlugin, jdk.tools.jlink.internal.plugins.IncludeLocalesPlugin, jdk.tools.jlink.internal.plugins.GenerateJLIClassesPlugin, - jdk.tools.jlink.internal.plugins.ReleaseInfoPlugin; - } + jdk.tools.jlink.internal.plugins.ReleaseInfoPlugin, + jdk.tools.jlink.internal.plugins.AddOptionsPlugin, + jdk.tools.jlink.internal.plugins.VendorBugURLPlugin, + jdk.tools.jlink.internal.plugins.VendorVMBugURLPlugin, + jdk.tools.jlink.internal.plugins.VendorVersionPlugin; + +} diff -r 12b4063e357f -r 4c036608ca8b src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Tue Oct 29 15:16:45 2019 +0100 +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java Wed Oct 30 11:23:55 2019 +0100 @@ -739,7 +739,20 @@ Files.copy(eSrc.file, u.file, REPLACE_EXISTING); } } + } else if (eSrc.type == Entry.CEN && eSrc.method != defaultCompressionMethod) { + + /** + * We are copying a file within the same Zip file using a + * different compression method. + */ + try (InputStream in = newInputStream(src); + OutputStream out = newOutputStream(dst, + CREATE, TRUNCATE_EXISTING, WRITE)) { + in.transferTo(out); + } + u = getEntry(dst); } + if (!hasCopyAttrs) u.mtime = u.atime= u.ctime = System.currentTimeMillis(); update(u); @@ -789,7 +802,8 @@ return os; } return getOutputStream(supportPosix ? - new PosixEntry((PosixEntry)e, Entry.NEW) : new Entry(e, Entry.NEW)); + new PosixEntry((PosixEntry)e, Entry.NEW, defaultCompressionMethod) + : new Entry(e, Entry.NEW, defaultCompressionMethod)); } else { if (!hasCreate && !hasCreateNew) throw new NoSuchFileException(getString(path)); @@ -2338,6 +2352,11 @@ this.file = file; } + Entry(Entry e, int type, int compressionMethod) { + this(e, type); + this.method = compressionMethod; + } + Entry(Entry e, int type) { name(e.name); this.isdir = e.isdir; @@ -2905,6 +2924,11 @@ super(name, file, type, attrs); } + PosixEntry(PosixEntry e, int type, int compressionMethod) { + super(e, type); + this.method = compressionMethod; + } + PosixEntry(PosixEntry e, int type) { super(e, type); this.owner = e.owner; diff -r 12b4063e357f -r 4c036608ca8b test/hotspot/jtreg/compiler/codegen/TestSignedMultiplyLong.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/compiler/codegen/TestSignedMultiplyLong.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 + * @bug 8232591 + * @summary Test some cases of combined signed multiply long operation + * @library /test/lib + * @run main/othervm -XX:+UnlockDiagnosticVMOptions + * -Xcomp -XX:-TieredCompilation -XX:-Inline + * compiler.codegen.TestSignedMultiplyLong + */ + +package compiler.codegen; + +import jdk.test.lib.Asserts; + +public class TestSignedMultiplyLong { + + private static final int minInt = Integer.MIN_VALUE; // -2147483648 + private static final int maxInt = Integer.MAX_VALUE; // 2147483647 + private static final long minLong = Long.MIN_VALUE; // -9223372036854775808 + private static final long maxLong = Long.MAX_VALUE; // 9223372036854775807 + + private static Case[] testCases = { + // case: a b c resSmaddl resSmsubl resSmnegl + new Case( 1000, -200, 500000L, 300000L, 700000L, 200000L), + new Case(maxInt, 1, 1L, (long)maxInt + 1L, (long)minInt + 2L, (long)minInt + 1L), + new Case(minInt, -1, 1L, (long)maxInt + 2L, (long)minInt + 1L, (long)minInt), + new Case( -10, minInt, 1L, 21474836481L, -21474836479L, -21474836480L), + new Case( 1, 1, maxLong, minLong, maxLong - 1L, -1L), + new Case( 1, -1, minLong, maxLong, minLong + 1L, 1L), + new Case( -1, -1, 0xffffffffeL << 32, 0xfffffffe00000001L, 0xfffffffdffffffffL, -1L) + }; + + private static class Case { + + private int a; + private int b; + private long c; + private long resSmaddl; + private long resSmsubl; + private long resSmnegl; + + public Case(int a, int b, long c, long resSmaddl, long resSmsubl, long resSmnegl) { + this.a = a; + this.b = b; + this.c = c; + this.resSmaddl = resSmaddl; + this.resSmsubl = resSmsubl; + this.resSmnegl = resSmnegl; + } + + public void verify() { + Asserts.assertEQ(smaddl(a, b, c), resSmaddl, + "Unexpected result from signed multiply-add long."); + Asserts.assertEQ(smsubl(a, b, c), resSmsubl, + "Unexpected result from signed multiply-sub long."); + Asserts.assertEQ(smnegl(a, b), resSmnegl, + "Unexpected result from signed multiply-neg long."); + } + } + + private static long smaddl(int a, int b, long c) { + return c + a * (long) b; + } + + private static long smsubl(int a, int b, long c) { + return c - a * (long) b; + } + + private static long smnegl(int a, int b) { + return a * (-(long) b); + } + + public static void main(String[] args) { + for (Case c : testCases) { + c.verify(); + } + } +} diff -r 12b4063e357f -r 4c036608ca8b test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DebugInfoTest.java --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DebugInfoTest.java Tue Oct 29 15:16:45 2019 +0100 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DebugInfoTest.java Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,32 +62,32 @@ /* * Ensure that any objects mentioned in the VirtualObjects are also in the OopMap. */ - List newLocations = new ArrayList(Arrays.asList(objects)); - List newDerived = new ArrayList(Arrays.asList(derivedBase)); + List newLocations = new ArrayList<>(Arrays.asList(objects)); + List newDerived = new ArrayList<>(Arrays.asList(derivedBase)); int[] newSizeInBytes = sizeInBytes; VirtualObject[] vobjs = compiler.compile(asm, values); if (vobjs != null) { for (VirtualObject obj : vobjs) { JavaValue[] objValues = obj.getValues(); for (int i = 0; i < objValues.length; i++) { - if (obj.getSlotKind(i) == JavaKind.Object) { - Location oopLocation = null; - int bytes = -1; - if (objValues[i] instanceof RegisterValue) { - RegisterValue reg = (RegisterValue) objValues[i]; - oopLocation = Location.register(reg.getRegister()); - bytes = reg.getValueKind().getPlatformKind().getSizeInBytes(); - } else if (objValues[i] instanceof StackSlot) { - StackSlot slot = (StackSlot) objValues[i]; - oopLocation = Location.stack(asm.getOffset(slot)); - bytes = slot.getValueKind().getPlatformKind().getSizeInBytes(); - } - if (oopLocation != null && !newLocations.contains(oopLocation)) { - newLocations.add(oopLocation); - newDerived.add(null); - newSizeInBytes = Arrays.copyOf(newSizeInBytes, newSizeInBytes.length + 1); - newSizeInBytes[newSizeInBytes.length - 1] = bytes; - } + if (obj.getSlotKind(i) == JavaKind.Object) { + Location oopLocation = null; + int bytes = -1; + if (objValues[i] instanceof RegisterValue) { + RegisterValue reg = (RegisterValue) objValues[i]; + oopLocation = Location.register(reg.getRegister()); + bytes = reg.getValueKind().getPlatformKind().getSizeInBytes(); + } else if (objValues[i] instanceof StackSlot) { + StackSlot slot = (StackSlot) objValues[i]; + oopLocation = Location.stack(asm.getOffset(slot)); + bytes = slot.getValueKind().getPlatformKind().getSizeInBytes(); + } + if (oopLocation != null && !newLocations.contains(oopLocation)) { + newLocations.add(oopLocation); + newDerived.add(null); + newSizeInBytes = Arrays.copyOf(newSizeInBytes, newSizeInBytes.length + 1); + newSizeInBytes[newSizeInBytes.length - 1] = bytes; + } } } } diff -r 12b4063e357f -r 4c036608ca8b test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java Tue Oct 29 15:16:45 2019 +0100 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/NativeCallTest.java Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,8 @@ @Test public void testF32SDILDS() { int sCount = 32; - Object[] remainingArgs = new Object[]{ // Pairs of , + // Pairs of , + Object[] remainingArgs = new Object[]{ 1.2345678F, float.class, 3.212434D, double.class, 43921652, int.class, @@ -101,7 +102,8 @@ @Test public void testI32SDILDS() { int sCount = 32; - Object[] remainingArgs = new Object[]{ // Pairs of , + // Pairs of , + Object[] remainingArgs = new Object[]{ 1.2345678F, float.class, 3.212434D, double.class, 43921652, int.class, @@ -143,6 +145,8 @@ } } + // Checkstyle: stop + public static native long getFF(); public static native float _FF(float a, float b); @@ -187,6 +191,7 @@ double d18, double d19, double d1a, double d1b, double d1c, double d1d, double d1e, double d1f, float a, double b, int c, long d, double e, float f); + @SuppressWarnings("unused") public static float D32SDILDS(double d00, double d01, double d02, double d03, double d04, double d05, double d06, double d07, double d08, double d09, double d0a, double d0b, double d0c, double d0d, double d0e, double d0f, double d10, double d11, double d12, double d13, double d14, double d15, double d16, double d17, diff -r 12b4063e357f -r 4c036608ca8b test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java Tue Oct 29 15:16:45 2019 +0100 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -206,7 +206,7 @@ private StackSlot deoptRescue; - public ValueKindFactory valueKindFactory = new ValueKindFactory() { + public ValueKindFactory valueKindFactory = new ValueKindFactory<>() { public TestValueKind getValueKind(JavaKind javaKind) { return (TestValueKind) TestAssembler.this.getValueKind(javaKind); } @@ -389,7 +389,7 @@ public abstract void emitLoad(AllocatableValue av, Object prim); /** - * Emit a call to a fixed address addr + * Emit a call to a fixed address addr. */ public abstract void emitCall(long addr); diff -r 12b4063e357f -r 4c036608ca8b test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestHotSpotVMConfig.java --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestHotSpotVMConfig.java Tue Oct 29 15:16:45 2019 +0100 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestHotSpotVMConfig.java Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,6 +42,7 @@ public final int classMirrorHandleOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "OopHandle"); + // Checkstyle: stop public final int MARKID_DEOPT_HANDLER_ENTRY = getConstant("CodeInstaller::DEOPT_HANDLER_ENTRY", Integer.class); public final long handleDeoptStub = getFieldValue("CompilerToVM::Data::SharedRuntime_deopt_blob_unpack", Long.class, "address"); diff -r 12b4063e357f -r 4c036608ca8b test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectFormattingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectFormattingTest.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.test; + +import org.junit.Assert; +import org.junit.Test; + +import jdk.vm.ci.code.VirtualObject; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaValue; +import jdk.vm.ci.meta.ResolvedJavaType; + +public class VirtualObjectFormattingTest extends VirtualObjectTestBase { + + @Test + public void testFormat() { + testBase(); + } + + @Override + protected void test(ResolvedJavaType klass, JavaValue[] kinds, JavaKind[] values, boolean malformed) { + // Verify that VirtualObject.toString will produce output without throwing exceptions or + // asserting. + VirtualObject virtual = VirtualObject.get(klass, 0); + virtual.setValues(kinds, values); + Assert.assertTrue(!virtual.toString().equals("")); + } +} diff -r 12b4063e357f -r 4c036608ca8b test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectTestBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectTestBase.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.code.test; + +import java.util.Arrays; + +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaValue; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.runtime.JVMCI; + +public abstract class VirtualObjectTestBase { + + public static class SimpleObject { + int i1; + int i2; + int i3; + int i4; + int i5; + int i6; + } + + public static JavaConstant getValue(JavaKind kind) { + long dummyValue = kind.ordinal(); + dummyValue = dummyValue | dummyValue << 8; + dummyValue = dummyValue | dummyValue << 16; + dummyValue = dummyValue | dummyValue << 32; + if (kind.isNumericInteger()) { + return JavaConstant.forIntegerKind(kind, dummyValue); + } else if (kind == JavaKind.Float) { + return JavaConstant.forDouble(Double.longBitsToDouble(dummyValue)); + } else if (kind == JavaKind.Float) { + return JavaConstant.forFloat(Float.intBitsToFloat((int) dummyValue)); + } else { + return JavaConstant.NULL_POINTER; + } + } + + public static JavaValue[] getJavaValues(JavaKind[] kinds) { + JavaValue[] values = new JavaValue[kinds.length]; + for (int i = 0; i < kinds.length; i++) { + values[i] = getValue(kinds[i]); + } + return values; + } + + /** + * Subclasses are expected to override this method to provide their own verification logic using + * the normal JUnit {@link org.junit.Assert} methods. + * + * @param klass class for the {@link jdk.vm.ci.code.VirtualObject} + * @param kinds {@link JavaKind Javakinds} for values + * @param values {@link JavaValue values} for materializing the + * {@link jdk.vm.ci.code.VirtualObject} + * @param malformed indicates whether the resulting virtual object is considered to be properly + * formed relative to the fields of {@code klass} + * @throws AssertionError if a problem is detected + */ + protected abstract void test(ResolvedJavaType klass, JavaValue[] kinds, JavaKind[] values, boolean malformed); + + public void testBase() { + MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); + + ResolvedJavaType simple = metaAccess.lookupJavaType(SimpleObject.class); + ResolvedJavaField[] fields = simple.getInstanceFields(true); + + JavaKind[] fieldKinds = new JavaKind[fields.length]; + for (int i = 0; i < fields.length; i++) { + fieldKinds[i] = fields[i].getType().getJavaKind(); + } + + // Generate a straightforward VirtualObject with values that match to declared field types. + JavaKind[] kinds = fieldKinds.clone(); + JavaValue[] values = getJavaValues(kinds); + test(simple, values, kinds, false); + + // Spread a long value across two int fields + kinds = Arrays.copyOf(fieldKinds, fieldKinds.length - 1); + kinds[1] = JavaKind.Long; + test(simple, getJavaValues(kinds), kinds, false); + + // Produce a long value for the final int field so there is no matching int field for the + // second half of the long + kinds = fieldKinds.clone(); + kinds[kinds.length - 1] = JavaKind.Long; + test(simple, getJavaValues(kinds), kinds, true); + + // Not enough values for the fields. + kinds = Arrays.copyOf(fieldKinds, fieldKinds.length - 1); + test(simple, getJavaValues(kinds), kinds, true); + + // Too many values for the fields. + kinds = Arrays.copyOf(fieldKinds, fieldKinds.length + 1); + kinds[kinds.length - 1] = JavaKind.Int; + test(simple, getJavaValues(kinds), kinds, true); + } +} diff -r 12b4063e357f -r 4c036608ca8b test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderData.java --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderData.java Tue Oct 29 15:16:45 2019 +0100 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderData.java Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -173,6 +173,7 @@ } // can't use nested classes for storing these test methods. see JDK-8010319 + @SuppressWarnings("unused") private void privateMethod() { // empty } diff -r 12b4063e357f -r 4c036608ca8b test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/VirtualObjectLayoutTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/VirtualObjectLayoutTest.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.vm.ci.hotspot.test; + +import org.junit.Assert; +import org.junit.Test; + +import jdk.vm.ci.code.VirtualObject; +import jdk.vm.ci.code.test.VirtualObjectTestBase; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.hotspot.HotSpotCompiledCode; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.JavaValue; +import jdk.vm.ci.meta.ResolvedJavaType; + +public class VirtualObjectLayoutTest extends VirtualObjectTestBase { + + @Override + protected void test(ResolvedJavaType klass, JavaValue[] values, JavaKind[] kinds, boolean error) { + // Verify that the layout checking will correctly report errors + VirtualObject virtual = VirtualObject.get(klass, 0); + virtual.setValues(values, kinds); + try { + HotSpotCompiledCode.verifyVirtualObject(virtual); + } catch (JVMCIError e) { + Assert.assertTrue("Unexpected error verifying " + virtual, error); + return; + } + Assert.assertFalse("Expected error but passed verifying " + virtual, error); + } + + @Test + public void testFormat() { + testBase(); + } +} diff -r 12b4063e357f -r 4c036608ca8b test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestSpeculationLog.java --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestSpeculationLog.java Tue Oct 29 15:16:45 2019 +0100 +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestSpeculationLog.java Wed Oct 30 11:23:55 2019 +0100 @@ -4,9 +4,7 @@ * * This code is free software; you can redistribute 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. + * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff -r 12b4063e357f -r 4c036608ca8b test/jdk/java/lang/invoke/lookup/LookupClassTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/java/lang/invoke/lookup/LookupClassTest.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8173975 + * @summary Lookup::in throws IAE if the target class is a primitive class or array class + * @run testng/othervm LookupClassTest + */ + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; + +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; +import static org.testng.Assert.*; + +public class LookupClassTest { + private static final LookupClassTest[] ARRAY = new LookupClassTest[0]; + @BeforeTest + public void test() { + assertTrue(ARRAY.getClass().isArray()); + assertSamePackage(MethodHandles.lookup(), ARRAY.getClass()); + assertSamePackage(MethodHandles.publicLookup(), int.class); + } + + private void assertSamePackage(Lookup lookup, Class targetClass) { + assertEquals(lookup.lookupClass().getPackageName(), targetClass.getPackageName()); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void arrayLookupClass() { + Lookup lookup = MethodHandles.lookup(); + lookup.in(ARRAY.getClass()); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void primitiveLookupClass() { + Lookup lookup = MethodHandles.publicLookup(); + lookup.in(int.class); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void voidLookupClass() { + Lookup lookup = MethodHandles.publicLookup(); + lookup.in(void.class); + } +} diff -r 12b4063e357f -r 4c036608ca8b test/jdk/jdk/jfr/event/compiler/TestCompilerStats.java --- a/test/jdk/jdk/jfr/event/compiler/TestCompilerStats.java Tue Oct 29 15:16:45 2019 +0100 +++ b/test/jdk/jdk/jfr/event/compiler/TestCompilerStats.java Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,8 +59,8 @@ Events.assertField(event, "standardCompileCount").atLeast(0); Events.assertField(event, "osrBytesCompiled").atLeast(0L); Events.assertField(event, "standardBytesCompiled").atLeast(0L); - Events.assertField(event, "nmetodsSize").atLeast(0L); - Events.assertField(event, "nmetodCodeSize").atLeast(0L); + Events.assertField(event, "nmethodsSize").atLeast(0L); + Events.assertField(event, "nmethodCodeSize").atLeast(0L); Events.assertField(event, "peakTimeSpent").atLeast(0L); Events.assertField(event, "totalTimeSpent").atLeast(0L); } diff -r 12b4063e357f -r 4c036608ca8b test/jdk/jdk/nio/zipfs/CopyMoveTests.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/jdk/nio/zipfs/CopyMoveTests.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.*; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import static java.lang.String.format; +import static java.util.stream.Collectors.joining; +import static org.testng.Assert.*; + +/** + * @test + * @bug 8223771 + * @summary Test Files::copy and Files::move with Zip FS + * @modules jdk.zipfs + * @run testng/othervm CopyMoveTests + */ +public class CopyMoveTests { + // Enable debugging output + private static final boolean DEBUG = false; + // Path to current directory + private static final Path HERE = Path.of("."); + // Value to use when creating Zip Entries + private static final String ZIP_FILE_VALUE = "US Open 2019"; + // Value used to create the OS file to be copied into/from a Zip File + private static final String OS_FILE_VALUE = "Hello World!"; + private static final SecureRandom random = new SecureRandom(); + + /* + * DataProvider used to verify that a FileAlreadyExistsException is + * thrown with copying a file without the REPLACE_EXISTING option + */ + @DataProvider(name = "zipfsMap") + private Object[][] zipfsMap() { + return new Object[][]{ + {Map.of("create", "true"), ZipEntry.DEFLATED}, + {Map.of("create", "true", "noCompression", "true"), + ZipEntry.STORED}, + {Map.of("create", "true", "noCompression", "false"), + ZipEntry.DEFLATED} + }; + } + + /* + * DataProvider used to verify that an entry may be copied or moved within + * a Zip file system with the correct compression method + */ + @DataProvider(name = "copyMoveMap") + private Object[][] copyMoveMap() { + return new Object[][]{ + {Map.of("create", "true"), ZipEntry.DEFLATED, ZipEntry.STORED}, + {Map.of("create", "true", "noCompression", "true"), + ZipEntry.STORED, ZipEntry.DEFLATED}, + {Map.of("create", "true", "noCompression", "false"), + ZipEntry.DEFLATED, ZipEntry.STORED} + }; + } + + /** + * Validate that an entry that is copied within a Zip file is copied with + * the correct compression + * + * @param createMap Zip FS properties to use when creating the Zip File + * @param compression The compression used when writing the initial entries + * @param expectedCompression The compression to be used when copying the entry + * @throws Exception If an error occurs + */ + @Test(dataProvider = "copyMoveMap", enabled = true) + public void copyTest(Map createMap, int compression, + int expectedCompression) throws Exception { + Entry e0 = Entry.of("Entry-0", compression, ZIP_FILE_VALUE); + Entry e1 = Entry.of("Entry-1", compression, ZIP_FILE_VALUE); + Entry e00 = Entry.of("Entry-00", expectedCompression, ZIP_FILE_VALUE); + + Path zipFile = generatePath(HERE, "test", ".zip"); + Files.deleteIfExists(zipFile); + + // Create the Zip File with the initial entries + createZipFile(zipFile, createMap, e0, e1); + try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, + Map.of("noCompression", expectedCompression == ZipEntry.STORED))) { + Files.copy(zipfs.getPath(e0.name), zipfs.getPath(e00.name)); + } + // Verify entries e0, e1 and e00 exist + verify(zipFile, e0, e1, e00); + Files.deleteIfExists(zipFile); + + } + + /** + * Validate that an entry that is copied from one Zip file to another, + * is copied with the correct compression + * + * @param createMap Zip FS properties to use when creating the Zip File + * @param compression The compression used when writing the initial entries + * @param expectedCompression The compression to be used when copying the entry + * @throws Exception If an error occurs + */ + @Test(dataProvider = "copyMoveMap", enabled = true) + public void copyZipToZipTest(Map createMap, int compression, + int expectedCompression) throws Exception { + Entry e0 = Entry.of("Entry-0", compression, ZIP_FILE_VALUE); + Entry e1 = Entry.of("Entry-1", compression, ZIP_FILE_VALUE); + Entry e00 = Entry.of("Entry-00", expectedCompression, ZIP_FILE_VALUE); + + Path zipFile = generatePath(HERE, "test", ".zip"); + Path zipFile2 = generatePath(HERE, "test", ".zip"); + Files.deleteIfExists(zipFile); + Files.deleteIfExists(zipFile2); + + createZipFile(zipFile, createMap, e0, e1); + try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, createMap); + FileSystem zipfsTarget = FileSystems.newFileSystem(zipFile2, + Map.of("create", "true", "noCompression", + expectedCompression == ZipEntry.STORED))) { + Files.copy(zipfs.getPath(e0.name), zipfsTarget.getPath(e00.name)); + } + // Only 1 entry copied to the secondary Zip file + verify(zipFile2, e00); + // Verify entries e0 and e1 remain in the original Zip file + verify(zipFile, e0, e1); + Files.deleteIfExists(zipFile); + Files.deleteIfExists(zipFile2); + } + + /** + * Validate that an external file copied to a Zip file is copied with + * the correct compression + * + * @param createMap Zip FS properties to use when creating the Zip File + * @param compression The compression used when writing the initial entries + * @param expectedCompression The compression to be used when copying the entry + * @throws Exception If an error occurs + */ + @Test(dataProvider = "copyMoveMap", enabled = true) + public void copyFromOsTest(Map createMap, int compression, + int expectedCompression) throws Exception { + + Path osFile = generatePath(HERE, "test", ".txt"); + Files.deleteIfExists(osFile); + Files.writeString(osFile, OS_FILE_VALUE); + Entry e0 = Entry.of("Entry-0", compression, ZIP_FILE_VALUE); + Entry e1 = Entry.of("Entry-1", compression, ZIP_FILE_VALUE); + Entry e00 = Entry.of("Entry-00", expectedCompression, OS_FILE_VALUE); + + Path zipFile = generatePath(HERE, "test", ".zip"); + Files.deleteIfExists(zipFile); + + createZipFile(zipFile, createMap, e0, e1); + try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, + Map.of("noCompression", expectedCompression == ZipEntry.STORED))) { + Files.copy(osFile, zipfs.getPath(e00.name)); + } + verify(zipFile, e0, e1, e00); + Files.deleteIfExists(osFile); + Files.deleteIfExists(zipFile); + } + + /** + * Validate that an entry that is copied from a Zip file to an OS file contains + * the correct bytes and the file remains in the Zip file + * + * @param createMap Zip FS properties to use when creating the Zip File + * @param compression The compression used when writing the initial entries + * @param expectedCompression The compression to be used when moving the entry + * @throws Exception If an error occurs + */ + @Test(dataProvider = "copyMoveMap", enabled = true) + public void CopyFromZipTest(Map createMap, int compression, + int expectedCompression) throws Exception { + + Entry e0 = Entry.of("Entry-0", compression, ZIP_FILE_VALUE); + Entry e1 = Entry.of("Entry-1", compression, ZIP_FILE_VALUE); + + Path zipFile = generatePath(HERE, "test", ".zip"); + Path osFile = generatePath(HERE, "test", ".txt"); + Files.deleteIfExists(zipFile); + Files.deleteIfExists(osFile); + + createZipFile(zipFile, createMap, e0, e1); + try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, Map.of())) { + Files.copy(zipfs.getPath(e0.name), osFile); + } + + // Entries e0 and e1 should exist + verify(zipFile, e0, e1); + // Check to see if the file exists and the bytes match + assertTrue(Files.isRegularFile(osFile)); + assertEquals(Files.readAllBytes(osFile), e0.bytes); + Files.deleteIfExists(zipFile); + Files.deleteIfExists(osFile); + } + + /** + * Validate that an entry that is moved within a Zip file is moved with + * the correct compression + * + * @param createMap Zip FS properties to use when creating the Zip File + * @param compression The compression used when writing the initial entries + * @param expectedCompression The compression to be used when moving the entry + * @throws Exception If an error occurs + */ + @Test(dataProvider = "copyMoveMap", enabled = true) + public void moveTest(Map createMap, int compression, + int expectedCompression) throws Exception { + + Entry e0 = Entry.of("Entry-0", compression, ZIP_FILE_VALUE); + Entry e1 = Entry.of("Entry-1", compression, ZIP_FILE_VALUE); + Entry e00 = Entry.of("Entry-00", expectedCompression, ZIP_FILE_VALUE); + + Path zipFile = generatePath(HERE, "test", ".zip"); + Files.deleteIfExists(zipFile); + + createZipFile(zipFile, createMap, e0, e1); + try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, + Map.of("noCompression", expectedCompression == ZipEntry.STORED))) { + Files.move(zipfs.getPath(e0.name), zipfs.getPath(e00.name)); + } + // Entry e0 should not exist but Entry e00 should + verify(zipFile, e1, e00); + Files.deleteIfExists(zipFile); + } + + /** + * Validate that an entry that is moved one Zip file to another is moved with + * the correct compression + * + * @param createMap Zip FS properties to use when creating the Zip File + * @param compression The compression used when writing the initial entries + * @param expectedCompression The compression to be used when moving the entry + * @throws Exception If an error occurs + */ + @Test(dataProvider = "copyMoveMap", enabled = true) + public void moveZipToZipTest(Map createMap, int compression, + int expectedCompression) throws Exception { + + Entry e0 = Entry.of("Entry-0", compression, ZIP_FILE_VALUE); + Entry e1 = Entry.of("Entry-1", compression, ZIP_FILE_VALUE); + Entry e00 = Entry.of("Entry-00", expectedCompression, ZIP_FILE_VALUE); + + Path zipFile = generatePath(HERE, "test", ".zip"); + Path zipFile2 = generatePath(HERE, "test", ".zip"); + Files.deleteIfExists(zipFile); + Files.deleteIfExists(zipFile2); + + createZipFile(zipFile, createMap, e0, e1); + try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, + Map.of("noCompression", expectedCompression == ZipEntry.STORED)); + FileSystem zipfsTarget = FileSystems.newFileSystem(zipFile2, + Map.of("create", "true", "noCompression", + expectedCompression == ZipEntry.STORED))) { + Files.move(zipfs.getPath(e0.name), zipfsTarget.getPath(e00.name)); + } + // Only Entry e00 should exist + verify(zipFile2, e00); + // Only Entry e1 should exist + verify(zipFile, e1); + Files.deleteIfExists(zipFile); + Files.deleteIfExists(zipFile2); + } + + /** + * Validate that an entry that is moved from a Zip file to an OS file contains + * the correct bytes and is removed from the Zip file + * + * @param createMap Zip FS properties to use when creating the Zip File + * @param compression The compression used when writing the initial entries + * @param expectedCompression The compression to be used when moving the entry + * @throws Exception If an error occurs + */ + @Test(dataProvider = "copyMoveMap", enabled = true) + public void moveFromZipTest(Map createMap, int compression, + int expectedCompression) throws Exception { + + Entry e0 = Entry.of("Entry-0", compression, ZIP_FILE_VALUE); + Entry e1 = Entry.of("Entry-1", compression, ZIP_FILE_VALUE); + + Path zipFile = generatePath(HERE, "test", ".zip"); + Path osFile = generatePath(HERE, "test", ".txt"); + Files.deleteIfExists(zipFile); + Files.deleteIfExists(osFile); + + createZipFile(zipFile, createMap, e0, e1); + try (FileSystem zipfs = FileSystems.newFileSystem(zipFile, Map.of())) { + Files.move(zipfs.getPath(e0.name), osFile); + } + + // Only Entry e1 should exist + verify(zipFile, e1); + // Check to see if the file exists and the bytes match + assertTrue(Files.isRegularFile(osFile)); + assertEquals(Files.readAllBytes(osFile), e0.bytes); + Files.deleteIfExists(zipFile); + Files.deleteIfExists(osFile); + } + + /** + * Validate that a FileAlreadyExistsException is thrown when copying a + * file and not specifying the REPLACE_EXISTING option. + * + * @param createMap Properties used for creating the ZIP Filesystem + * @throws Exception if an error occurs + */ + @Test(dataProvider = "zipfsMap", enabled = true) + public void testFAEWithCopy(Map createMap, + int compression) throws Exception { + if (DEBUG) { + System.out.printf("ZIP FS Map = %s%n ", formatMap(createMap)); + } + Entry e0 = Entry.of("Entry-0", compression, ZIP_FILE_VALUE); + Entry e1 = Entry.of("Entry-1", compression, ZIP_FILE_VALUE); + + Path zipFile = generatePath(HERE, "test", ".zip"); + Files.deleteIfExists(zipFile); + + createZipFile(zipFile, createMap, e0, e1); + try (FileSystem zipfs = + FileSystems.newFileSystem(zipFile, createMap)) { + assertThrows(FileAlreadyExistsException.class, () -> + Files.copy(zipfs.getPath(e0.name), + zipfs.getPath(e1.name))); + } + Files.deleteIfExists(zipFile); + } + + /** + * Generate a temporary file Path + * + * @param dir Directory used to create the path + * @param prefix The prefix string used to create the path + * @param suffix The suffix string used to create the path + * @return Path that was generated + */ + private static Path generatePath(Path dir, String prefix, String suffix) { + long n = random.nextLong(); + String s = prefix + Long.toUnsignedString(n) + suffix; + Path name = dir.getFileSystem().getPath(s); + // the generated name should be a simple file name + if (name.getParent() != null) + throw new IllegalArgumentException("Invalid prefix or suffix"); + return dir.resolve(name); + } + + /** + * Utility method to return a formatted String of the key:value entries for + * a Map + * + * @param env Map to format + * @return Formatted string of the Map entries + */ + private static String formatMap(Map env) { + return env.entrySet().stream() + .map(e -> format("(%s:%s)", e.getKey(), e.getValue())) + .collect(joining(", ")); + } + + /** + * Create a Zip file using the Zip File System with the specified + * Zip File System properties + * + * @param zipFile Path to the Zip File to create + * @param env Properties used for creating the Zip Filesystem + * @param entries The entries to add to the Zip File + * @throws IOException If an error occurs while creating the Zip file + */ + private void createZipFile(Path zipFile, Map env, + Entry... entries) throws IOException { + if (DEBUG) { + System.out.printf("Creating Zip file: %s with the Properties: %s%n", + zipFile, formatMap(env)); + } + try (FileSystem zipfs = + FileSystems.newFileSystem(zipFile, env)) { + for (Entry e : entries) { + Files.writeString(zipfs.getPath(e.name), new String(e.bytes)); + } + } + } + + /** + * Represents an entry in a Zip file. An entry encapsulates a name, a + * compression method, and its contents/data. + */ + static class Entry { + private final String name; + private final int method; + private final byte[] bytes; + + Entry(String name, int method, String contents) { + this.name = name; + this.method = method; + this.bytes = contents.getBytes(StandardCharsets.UTF_8); + } + + static Entry of(String name, int method, String contents) { + return new Entry(name, method, contents); + } + + /** + * Returns a new Entry with the same name and compression method as this + * Entry but with the given content. + */ + Entry content(String contents) { + return new Entry(name, method, contents); + } + } + + /** + * Verify that the given path is a Zip file containing exactly the + * given entries. + */ + private static void verify(Path zipfile, Entry... entries) throws IOException { + // check entries with zip API + try (ZipFile zf = new ZipFile(zipfile.toFile())) { + // check entry count + assertEquals(entries.length, zf.size()); + + // check compression method and content of each entry + for (Entry e : entries) { + ZipEntry ze = zf.getEntry(e.name); + //System.out.printf("Name: %s, method: %s, Expected Method: %s%n", e.name, ze.getMethod(), e.method); + assertNotNull(ze); + assertEquals(e.method, ze.getMethod()); + try (InputStream in = zf.getInputStream(ze)) { + byte[] bytes = in.readAllBytes(); + assertTrue(Arrays.equals(bytes, e.bytes)); + } + } + } + + // check entries with FileSystem API + try (FileSystem fs = FileSystems.newFileSystem(zipfile)) { + // check entry count + Path top = fs.getPath("/"); + long count = Files.find(top, Integer.MAX_VALUE, + (path, attrs) -> attrs.isRegularFile()).count(); + assertEquals(entries.length, count); + + // check content of each entry + for (Entry e : entries) { + Path file = fs.getPath(e.name); + byte[] bytes = Files.readAllBytes(file); + assertTrue(Arrays.equals(bytes, e.bytes)); + } + } + } +} diff -r 12b4063e357f -r 4c036608ca8b test/jdk/jdk/nio/zipfs/UpdateEntryTest.java --- a/test/jdk/jdk/nio/zipfs/UpdateEntryTest.java Tue Oct 29 15:16:45 2019 +0100 +++ b/test/jdk/jdk/nio/zipfs/UpdateEntryTest.java Wed Oct 30 11:23:55 2019 +0100 @@ -33,6 +33,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; +import java.util.Map; import java.util.spi.ToolProvider; import java.util.zip.CRC32; import java.util.zip.ZipEntry; @@ -116,14 +117,15 @@ // Create JAR file with a STORED(non-compressed) entry Files.writeString(Path.of(storedFileName), "foobar"); - int rc = JAR_TOOL.run(System.out, System.err, + JAR_TOOL.run(System.out, System.err, "cM0vf", jarFileName, storedFileName); - // Replace the STORED entry + // Replace the STORED entry using the default(DEFLATED) compression + // method. try (FileSystem fs = FileSystems.newFileSystem(zipFile)) { Files.writeString(fs.getPath(storedFileName), replacedValue); } - Entry e1 = Entry.of(storedFileName, ZipEntry.STORED, replacedValue); + Entry e1 = Entry.of(storedFileName, ZipEntry.DEFLATED, replacedValue); verify(zipFile, e1); } @@ -159,8 +161,12 @@ String newContents = "hi"; + // Set the required compression method + Map map = Map.of("noCompression", + e1.method != ZipEntry.DEFLATED); + // replace contents of e1 - try (FileSystem fs = FileSystems.newFileSystem(zipfile)) { + try (FileSystem fs = FileSystems.newFileSystem(zipfile, map)) { Path foo = fs.getPath(e1.name); Files.writeString(foo, newContents); } diff -r 12b4063e357f -r 4c036608ca8b test/jdk/tools/jlink/JLinkReproducibleTest.java --- a/test/jdk/tools/jlink/JLinkReproducibleTest.java Tue Oct 29 15:16:45 2019 +0100 +++ b/test/jdk/tools/jlink/JLinkReproducibleTest.java Wed Oct 30 11:23:55 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 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 @@ -43,7 +43,7 @@ res.shouldHaveExitValue(0); } - private static void jlink(Path image) throws Exception { + private static void jlink(Path image, boolean with_default_trace_file) throws Exception { var cmd = new ArrayList(); cmd.add(JDKToolFinder.getJDKTool("jlink")); cmd.addAll(List.of( @@ -52,6 +52,9 @@ "--compress=2", "--output", image.toString() )); + if (!with_default_trace_file) { + cmd.add("--generate-jli-classes=@file-not-exists"); + } run(cmd); } @@ -98,17 +101,31 @@ // Link the first image var firstImage = Path.of("image-first"); - jlink(firstImage); + jlink(firstImage, true); var firstModulesFile = firstImage.resolve("lib") .resolve("modules"); // Link the second image var secondImage = Path.of("image-second"); - jlink(secondImage); + jlink(secondImage, true); var secondModulesFile = secondImage.resolve("lib") .resolve("modules"); // Ensure module files are identical assertEquals(-1L, Files.mismatch(firstModulesFile, secondModulesFile)); + + // Link the third image + var thirdImage = Path.of("image-third"); + jlink(thirdImage, false); + var thirdModulesFile = thirdImage.resolve("lib") + .resolve("modules"); + // Link the fourth image + var fourthImage = Path.of("image-fourth"); + jlink(fourthImage, false); + var fourthModulesFile = fourthImage.resolve("lib") + .resolve("modules"); + + // Ensure module files are identical + assertEquals(-1L, Files.mismatch(thirdModulesFile, fourthModulesFile)); } } diff -r 12b4063e357f -r 4c036608ca8b test/jdk/tools/jlink/plugins/AddOptionsPluginTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jlink/plugins/AddOptionsPluginTest.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.process.*; + +import tests.Helper; + +/* @test + * @bug 8232080 + * @summary Test the --add-options plugin + * @library ../../lib + * @library /test/lib + * @modules java.base/jdk.internal.jimage + * jdk.jdeps/com.sun.tools.classfile + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jmod + * jdk.jlink/jdk.tools.jimage + * jdk.compiler + * @build tests.* + * @run main AddOptionsPluginTest + */ + +public class AddOptionsPluginTest { + + private static final String PROP = "add.options.plugin.test"; + private static final String VALUE = "xyzzy"; + private static final String OPTS = "-D" + PROP + "=" + VALUE; + + public static void main(String[] args) throws Throwable { + + Helper helper = Helper.newHelper(); + if (helper == null) { + System.err.println("Test not run"); + return; + } + + var module = "addoptions"; + helper.generateDefaultJModule(module); + var image = helper.generateDefaultImage(new String[] { "--add-options", OPTS }, + module) + .assertSuccess(); + helper.checkImage(image, module, null, null); + + var launcher = image.resolve("bin/java" + + (System.getProperty("os.name").startsWith("Windows") + ? ".exe" : "")); + var oa = ProcessTools.executeProcess(launcher.toString(), + "-XshowSettings:properties", "--version"); + oa.stderrShouldMatch("^ +" + PROP + " = " + VALUE + "$"); + + } + +} diff -r 12b4063e357f -r 4c036608ca8b test/jdk/tools/jlink/plugins/VendorInfoPluginsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/tools/jlink/plugins/VendorInfoPluginsTest.java Wed Oct 30 11:23:55 2019 +0100 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.process.*; + +import tests.Helper; + +/* @test + * @bug 8232080 + * @summary Test the --vendor-version --vendor-url-bug plugins + * @library ../../lib + * @library /test/lib + * @modules java.base/jdk.internal.jimage + * jdk.jdeps/com.sun.tools.classfile + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jmod + * jdk.jlink/jdk.tools.jimage + * jdk.compiler + * @build tests.* + * @run main VendorInfoPluginsTest + */ + +public class VendorInfoPluginsTest { + + public static class Crasher { + + public static void main(String ... args) throws Exception { + var uc = Class.forName("sun.misc.Unsafe"); + var f = uc.getDeclaredField("theUnsafe"); + f.setAccessible(true); + var u = (sun.misc.Unsafe)f.get(null); + for (long a = 0; a < Long.MAX_VALUE; a += 8) + u.putLong(a, -1L); + } + + } + + private static final String VERSION = "XyzzyVM 3.14.15"; + private static final String BUG_URL = "https://bugs.xyzzy.com/"; + private static final String VM_BUG_URL = "https://bugs.xyzzy.com/crash/"; + + public static void main(String[] args) throws Throwable { + + Helper helper = Helper.newHelper(); + if (helper == null) { + System.err.println("Test not run"); + return; + } + + var module = "vendorinfo"; + helper.generateDefaultJModule(module); + var image = helper.generateDefaultImage(new String[] { + "--add-modules", "jdk.unsupported", + "--vendor-version", VERSION, + "--vendor-bug-url", BUG_URL, + "--vendor-vm-bug-url", VM_BUG_URL }, + module).assertSuccess(); + helper.checkImage(image, module, null, null); + + // Properties and --version + var launcher + = image.resolve("bin/java" + + (System.getProperty("os.name").startsWith("Windows") + ? ".exe" : "")).toString(); + var oa = ProcessTools.executeProcess(launcher, + "-XshowSettings:properties", + "--version"); + oa.stderrShouldMatch("^ +java.vendor.url.bug = " + BUG_URL + "$"); + oa.stderrShouldMatch("^ +java.vendor.version = " + VERSION + "$"); + oa.stdoutShouldMatch("^.*Runtime Environment " + VERSION + " \\(build.*$"); + oa.stdoutShouldMatch("^.*Server VM " + VERSION + " \\(build.*$"); + + // VM error log + oa = ProcessTools.executeProcess(launcher, + "--class-path", + System.getProperty("test.classes"), + "VendorInfoPluginsTest$Crasher"); + oa.stdoutShouldMatch("^# +" + VM_BUG_URL + "$"); + oa.stdoutShouldMatch("^.*Runtime Environment " + VERSION + " \\(.*$"); + oa.stdoutShouldMatch("^.*Server VM " + VERSION + " \\(.*$"); + + } + +} diff -r 12b4063e357f -r 4c036608ca8b test/lib/jdk/test/lib/cds/CDSTestUtils.java --- a/test/lib/jdk/test/lib/cds/CDSTestUtils.java Tue Oct 29 15:16:45 2019 +0100 +++ b/test/lib/jdk/test/lib/cds/CDSTestUtils.java Wed Oct 30 11:23:55 2019 +0100 @@ -309,7 +309,7 @@ // exceptions match. Pass null if you wish not to re-throw any exception. public static void checkCommonExecExceptions(OutputAnalyzer output, Exception e) throws Exception { - if (output.getStdout().contains("http://bugreport.java.com/bugreport/crash.jsp")) { + if (output.getStdout().contains("https://bugreport.java.com/bugreport/crash.jsp")) { throw new RuntimeException("Hotspot crashed"); } if (output.getStdout().contains("TEST FAILED")) {