# HG changeset patch # User stuefe # Date 1573056806 -3600 # Node ID 18659e040c641f37506f8f40cfe2def1692a8849 # Parent 08102295011dbd6a2f6f384b0580f76f2acdf981# Parent 83810b7d12e7ff761ad3dd91f323a22dad96f108 Merge diff -r 08102295011d -r 18659e040c64 .hgtags --- a/.hgtags Fri Nov 01 14:18:40 2019 +0100 +++ b/.hgtags Wed Nov 06 17:13:26 2019 +0100 @@ -593,3 +593,4 @@ e84d8379815ba0d3e50fb096d28c25894cb50b8c jdk-14+18 9b67dd88a9313e982ec5f710a7747161bc8f0c23 jdk-14+19 54ffb15c48399dd59922ee22bb592d815307e77c jdk-14+20 +c16ac7a2eba4e73cb4f7ee9294dd647860eebff0 jdk-14+21 diff -r 08102295011d -r 18659e040c64 doc/building.html --- a/doc/building.html Fri Nov 01 14:18:40 2019 +0100 +++ b/doc/building.html Wed Nov 06 17:13:26 2019 +0100 @@ -385,10 +385,10 @@

On Linux you can also get a JDK from the Linux distribution. On apt-based distros (like Debian and Ubuntu), sudo apt-get install openjdk-<VERSION>-jdk is typically enough to install a JDK <VERSION>. On rpm-based distros (like Fedora and Red Hat), try sudo yum install java-<VERSION>-openjdk-devel.

External Library Requirements

Different platforms require different external libraries. In general, libraries are not optional - that is, they are either required or not used.

-

If a required library is not detected by configure, you need to provide the path to it. There are two forms of the configure arguments to point to an external library: --with-<LIB>=<path> or --with-<LIB>-include=<path to include> --with-<LIB>-lib=<path to lib>. The first variant is more concise, but require the include files an library files to reside in a default hierarchy under this directory. In most cases, it works fine.

+

If a required library is not detected by configure, you need to provide the path to it. There are two forms of the configure arguments to point to an external library: --with-<LIB>=<path> or --with-<LIB>-include=<path to include> --with-<LIB>-lib=<path to lib>. The first variant is more concise, but require the include files and library files to reside in a default hierarchy under this directory. In most cases, it works fine.

As a fallback, the second version allows you to point to the include directory and the lib directory separately.

FreeType

-

FreeType2 from The FreeType Project is not required on any platform. The exception is on Unix-based platforms when configuring such that the build artifacts will reference a system installed library, rather than bundling the JDK’s own copy.

+

FreeType2 from The FreeType Project is not required on any platform. The exception is on Unix-based platforms when configuring such that the build artifacts will reference a system installed library, rather than bundling the JDK's own copy.

@@ -207,5 +208,15 @@

It is highly recommended to use the latest NSS version when running PKCS11 tests. Improper NSS version may lead to unexpected failures which are hard to diagnose. For example, sun/security/pkcs11/Secmod/AddTrustedCert.java may fail on Ubuntu 18.04 with the default NSS version in the system. To run these tests correctly, the system property test.nss.lib.paths is required on Ubuntu 18.04 to specify the alternative NSS lib directories. For example:

$ make test TEST="jtreg:sun/security/pkcs11/Secmod/AddTrustedCert.java" JTREG="JAVA_OPTIONS=-Dtest.nss.lib.paths=/path/to/your/latest/NSS-libs"

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

+

Client UI Tests

+

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

+

MacOS

+

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

+

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

+

Linux

+

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

+

Windows

+

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

+

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

diff -r 08102295011d -r 18659e040c64 doc/testing.md --- a/doc/testing.md Fri Nov 01 14:18:40 2019 +0100 +++ b/doc/testing.md Wed Nov 06 17:13:26 2019 +0100 @@ -421,6 +421,35 @@ For more notes about the PKCS11 tests, please refer to test/jdk/sun/security/pkcs11/README. +### Client UI Tests + +Some Client UI tests use key sequences which may be reserved by the operating +system. Usually that causes the test failure. So it is highly recommended to disable +system key shortcuts prior testing. The steps to access and disable system key shortcuts +for various platforms are provided below. + +#### MacOS +Choose Apple menu; System Preferences, click Keyboard, then click Shortcuts; +select or deselect desired shortcut. + +For example, test/jdk/javax/swing/TooltipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java fails +on MacOS because it uses `CTRL + F1` key sequence to show or hide tooltip message +but the key combination is reserved by the operating system. To run the test correctly +the default global key shortcut should be disabled using the steps described above, and then deselect +"Turn keyboard access on or off" option which is responsible for `CTRL + F1` combination. + +#### Linux +Open the Activities overview and start typing Settings; Choose Settings, click Devices, +then click Keyboard; set or override desired shortcut. + +#### Windows +Type `gpedit` in the Search and then click Edit group policy; navigate to +User Configuration -> Administrative Templates -> Windows Components -> File Explorer; +in the right-side pane look for "Turn off Windows key hotkeys" and double click on it; +enable or disable hotkeys. + +Note: restart is required to make the settings take effect. + --- # Override some definitions in the global css file that are not optimal for # this document. diff -r 08102295011d -r 18659e040c64 make/Bundles.gmk --- a/make/Bundles.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/Bundles.gmk Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 make/CompileToolsJdk.gmk --- a/make/CompileToolsJdk.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/CompileToolsJdk.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/Coverage.gmk --- a/make/Coverage.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/Coverage.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/Docs.gmk --- a/make/Docs.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/Docs.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -138,9 +138,9 @@ ifeq ($(IS_DRAFT), true) DRAFT_MARKER_STR :=
DRAFT $(VERSION_STRING) ifeq ($(VERSION_BUILD), 0) - DRAFT_MARKER_TITLE := [ad-hoc build] + DRAFT_MARKER_TITLE := $(SPACE)[ad-hoc build] else - DRAFT_MARKER_TITLE := [build $(VERSION_BUILD)] + DRAFT_MARKER_TITLE := $(SPACE)[build $(VERSION_BUILD)] endif DRAFT_TEXT := This specification is not final and is subject to change. \ Use is subject to license terms. @@ -304,7 +304,7 @@ $1_DOC_TITLE := $$($1_LONG_NAME)
Version $$(VERSION_SPECIFICATION) API \ Specification - $1_WINDOW_TITLE := $$(subst &,&,$$($1_SHORT_NAME)) $$(DRAFT_MARKER_TITLE) + $1_WINDOW_TITLE := $$(subst &,&,$$($1_SHORT_NAME))$$(DRAFT_MARKER_TITLE) $1_HEADER_TITLE :=
$$($1_SHORT_NAME) \ $$(DRAFT_MARKER_STR)
diff -r 08102295011d -r 18659e040c64 make/GenerateLinkOptData.gmk --- a/make/GenerateLinkOptData.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/GenerateLinkOptData.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/GensrcModuleInfo.gmk --- a/make/GensrcModuleInfo.gmk Fri Nov 01 14:18:40 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -# -# Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. Oracle designates this -# particular file as subject to the "Classpath" exception as provided -# by Oracle in the LICENSE file that accompanied this code. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -################################################################################ -# This file makes modifications to module-info.java files based on the build -# configuration. -# -# Depending on build platform, imported modules and optional parts of the build -# being active, some modules need to have extra exports, provides or uses -# declarations added to them. These optional extras are defined in .extra files: -# -# src///classes/module-info.java.extra -# -# The contents of the .extra files are simply extra lines that could fit into -# the module-info file. -# -# This makefile is called once for each from-module with the variable -# MODULE naming the from-module. -# -# The modified module-info.java files are put in the gensrc directory where -# they will automatically override the static versions in the src tree. -# -################################################################################ - -default: all - -include $(SPEC) -include MakeBase.gmk -include Modules.gmk - -################################################################################ -# Define this here since jdk/make/Tools.gmk cannot be included from the top -# make directory. Should probably move some tools away from the jdk repo. -TOOL_GENMODULEINFOSOURCE = $(JAVA_SMALL) \ - $(INTERIM_LANGTOOLS_ARGS) \ - -cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes" \ - build.tools.module.GenModuleInfoSource - -################################################################################ - -# Name of modification file. -MOD_FILENAME := module-info.java.extra - -# Construct all possible src directories for the module. -MODULE_CLASSES_DIRS := $(call FindModuleSrcDirs, $(MODULE)) - -# Find all the .extra files in the src dirs. -MOD_FILES := $(wildcard $(foreach f, $(MOD_FILENAME), $(addsuffix /$(f), \ - $(MODULE_CLASSES_DIRS)))) - -ifneq ($(MOD_FILES), ) - # Only make this call if modification files are found for this module - ALL_MODULES := $(call FindAllModules) - - $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/module-info.java: \ - $(firstword $(call FindAllModuleInfos, $(MODULE))) \ - $(BUILD_TOOLS_JDK) \ - $(MOD_FILES) \ - $(call DependOnVariable, ALL_MODULES) - $(call MakeTargetDir) - $(RM) $@ $@.tmp - $(TOOL_GENMODULEINFOSOURCE) -o $@.tmp \ - --source-file $< \ - --modules $(call CommaList, $(ALL_MODULES)) \ - $(MOD_FILES) - $(MV) $@.tmp $@ - - TARGETS += $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/module-info.java - -else - # If no modifications are found for this module, remove any module-info.java - # created by a previous build since that is no longer valid. - ifneq ($(wildcard $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/module-info.java), ) - $(shell $(RM) $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/module-info.java) - endif -endif - -################################################################################ - -all: $(TARGETS) diff -r 08102295011d -r 18659e040c64 make/Help.gmk --- a/make/Help.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/Help.gmk Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 make/Main.gmk --- a/make/Main.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/Main.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -77,7 +77,7 @@ interim-cldrconverter: +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CopyInterimCLDRConverter.gmk) - + interim-tzdb: +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CopyInterimTZDB.gmk) @@ -133,7 +133,7 @@ define DeclareModuleInfoRecipe $1-gensrc-moduleinfo: +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) \ - -f GensrcModuleInfo.gmk MODULE=$1) + -f gensrc/GensrcModuleInfo.gmk MODULE=$1) $1-gensrc: $1-gensrc-moduleinfo endef @@ -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 08102295011d -r 18659e040c64 make/MainSupport.gmk --- a/make/MainSupport.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/MainSupport.gmk Wed Nov 06 17:13:26 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 @@ -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 08102295011d -r 18659e040c64 make/ModuleWrapper.gmk --- a/make/ModuleWrapper.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/ModuleWrapper.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/RunTestsPrebuiltSpec.gmk --- a/make/RunTestsPrebuiltSpec.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/RunTestsPrebuiltSpec.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/StaticLibsImage.gmk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/StaticLibsImage.gmk Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 make/TestImage.gmk --- a/make/TestImage.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/TestImage.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/UpdateBuildDocs.gmk --- a/make/UpdateBuildDocs.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/UpdateBuildDocs.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -45,29 +45,13 @@ DOCS_DIR := $(TOPDIR)/doc -$(eval $(call SetupProcessMarkdown, building, \ - FILES := $(DOCS_DIR)/building.md, \ +$(eval $(call SetupProcessMarkdown, md_docs, \ + FILES := $(call FindFiles, $(DOCS_DIR), *.md), \ DEST := $(DOCS_DIR), \ CSS := $(GLOBAL_SPECS_DEFAULT_CSS_FILE), \ OPTIONS := --toc, \ )) -TARGETS += $(building) - -$(eval $(call SetupProcessMarkdown, testing, \ - FILES := $(DOCS_DIR)/testing.md, \ - DEST := $(DOCS_DIR), \ - CSS := $(GLOBAL_SPECS_DEFAULT_CSS_FILE), \ - OPTIONS := --toc, \ -)) -TARGETS += $(testing) - -$(eval $(call SetupProcessMarkdown, ide, \ - FILES := $(DOCS_DIR)/ide.md, \ - DEST := $(DOCS_DIR), \ - CSS := $(GLOBAL_SPECS_DEFAULT_CSS_FILE), \ - OPTIONS := --toc, \ -)) -TARGETS += $(ide) +TARGETS += $(md_docs) ################################################################################ diff -r 08102295011d -r 18659e040c64 make/ZipSecurity.gmk --- a/make/ZipSecurity.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/ZipSecurity.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/autoconf/configure.ac --- a/make/autoconf/configure.ac Fri Nov 01 14:18:40 2019 +0100 +++ b/make/autoconf/configure.ac Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ -SRC# -# 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 diff -r 08102295011d -r 18659e040c64 make/autoconf/flags-cflags.m4 --- a/make/autoconf/flags-cflags.m4 Fri Nov 01 14:18:40 2019 +0100 +++ b/make/autoconf/flags-cflags.m4 Wed Nov 06 17:13:26 2019 +0100 @@ -597,7 +597,7 @@ LANGSTD_CFLAGS="-xc99=all,no_lib" elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then # MSVC doesn't support C99/C11 explicitly, unless you compile as C++: - # LANGSTD_CFLAGS="/TP" + # LANGSTD_CFLAGS="-TP" # but that requires numerous changes to the sources files. So we are limited # to C89/C90 plus whatever extensions Visual Studio has decided to implement. # This is the lowest bar for shared code. @@ -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 08102295011d -r 18659e040c64 make/autoconf/jdk-version.m4 --- a/make/autoconf/jdk-version.m4 Fri Nov 01 14:18:40 2019 +0100 +++ b/make/autoconf/jdk-version.m4 Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 make/autoconf/spec.gmk.in --- a/make/autoconf/spec.gmk.in Fri Nov 01 14:18:40 2019 +0100 +++ b/make/autoconf/spec.gmk.in Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 make/autoconf/version-numbers --- a/make/autoconf/version-numbers Fri Nov 01 14:18:40 2019 +0100 +++ b/make/autoconf/version-numbers Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 make/common/JavaCompilation.gmk --- a/make/common/JavaCompilation.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/common/JavaCompilation.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -222,7 +222,7 @@ ) \ ) $$(call MakeDir,$$($1_BIN)) - # Order src files according to the order of the src dirs. Correct odering is + # Order src files according to the order of the src dirs. Correct ordering is # needed for correct overriding between different source roots. $1_ALL_SRC_RAW := $$(call FindFiles, $$($1_SRC)) $1_ALL_SRCS := $$($1_EXTRA_FILES) \ diff -r 08102295011d -r 18659e040c64 make/common/JdkNativeCompilation.gmk --- a/make/common/JdkNativeCompilation.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/common/JdkNativeCompilation.gmk Wed Nov 06 17:13:26 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 @@ -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 08102295011d -r 18659e040c64 make/common/Modules.gmk --- a/make/common/Modules.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/common/Modules.gmk Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 make/common/NativeCompilation.gmk --- a/make/common/NativeCompilation.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/common/NativeCompilation.gmk Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 make/common/ProcessMarkdown.gmk --- a/make/common/ProcessMarkdown.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/common/ProcessMarkdown.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,4 +1,4 @@ -# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/common/RMICompilation.gmk --- a/make/common/RMICompilation.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/common/RMICompilation.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, 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 diff -r 08102295011d -r 18659e040c64 make/common/SetupJavaCompilers.gmk --- a/make/common/SetupJavaCompilers.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/common/SetupJavaCompilers.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/conf/jib-profiles.js --- a/make/conf/jib-profiles.js Fri Nov 01 14:18:40 2019 +0100 +++ b/make/conf/jib-profiles.js Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 make/copy/Copy-jdk.crypto.cryptoki.gmk --- a/make/copy/Copy-jdk.crypto.cryptoki.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/copy/Copy-jdk.crypto.cryptoki.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/copy/Copy-jdk.crypto.ucrypto.gmk --- a/make/copy/Copy-jdk.crypto.ucrypto.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/copy/Copy-jdk.crypto.ucrypto.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/devkit/Tools.gmk --- a/make/devkit/Tools.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/devkit/Tools.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/gendata/GendataBlacklistedCerts.gmk --- a/make/gendata/GendataBlacklistedCerts.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gendata/GendataBlacklistedCerts.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/gendata/GendataBreakIterator.gmk --- a/make/gendata/GendataBreakIterator.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gendata/GendataBreakIterator.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/gendata/GendataPublicSuffixList.gmk --- a/make/gendata/GendataPublicSuffixList.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gendata/GendataPublicSuffixList.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/gensrc/Gensrc-java.desktop.gmk --- a/make/gensrc/Gensrc-java.desktop.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gensrc/Gensrc-java.desktop.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/gensrc/Gensrc-jdk.hotspot.agent.gmk --- a/make/gensrc/Gensrc-jdk.hotspot.agent.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gensrc/Gensrc-jdk.hotspot.agent.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/gensrc/Gensrc-jdk.jlink.gmk --- a/make/gensrc/Gensrc-jdk.jlink.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gensrc/Gensrc-jdk.jlink.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/gensrc/GensrcBuffer.gmk --- a/make/gensrc/GensrcBuffer.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gensrc/GensrcBuffer.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, 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 diff -r 08102295011d -r 18659e040c64 make/gensrc/GensrcCharacterData.gmk --- a/make/gensrc/GensrcCharacterData.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gensrc/GensrcCharacterData.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2017, 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 diff -r 08102295011d -r 18659e040c64 make/gensrc/GensrcCharsetCoder.gmk --- a/make/gensrc/GensrcCharsetCoder.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gensrc/GensrcCharsetCoder.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/gensrc/GensrcIcons.gmk --- a/make/gensrc/GensrcIcons.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gensrc/GensrcIcons.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/gensrc/GensrcMisc.gmk --- a/make/gensrc/GensrcMisc.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gensrc/GensrcMisc.gmk Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 make/gensrc/GensrcModuleInfo.gmk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/gensrc/GensrcModuleInfo.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -0,0 +1,102 @@ +# +# Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +################################################################################ +# This file makes modifications to module-info.java files based on the build +# configuration. +# +# Depending on build platform, imported modules and optional parts of the build +# being active, some modules need to have extra exports, provides or uses +# declarations added to them. These optional extras are defined in .extra files: +# +# src///classes/module-info.java.extra +# +# The contents of the .extra files are simply extra lines that could fit into +# the module-info file. +# +# This makefile is called once for each from-module with the variable +# MODULE naming the from-module. +# +# The modified module-info.java files are put in the gensrc directory where +# they will automatically override the static versions in the src tree. +# +################################################################################ + +default: all + +include $(SPEC) +include MakeBase.gmk +include Modules.gmk + +################################################################################ +# Define this here since jdk/make/Tools.gmk cannot be included from the top +# make directory. Should probably move some tools away from the jdk repo. +TOOL_GENMODULEINFOSOURCE = $(JAVA_SMALL) \ + $(INTERIM_LANGTOOLS_ARGS) \ + -cp "$(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes" \ + build.tools.module.GenModuleInfoSource + +################################################################################ + +# Name of modification file. +MOD_FILENAME := module-info.java.extra + +# Construct all possible src directories for the module. +MODULE_CLASSES_DIRS := $(call FindModuleSrcDirs, $(MODULE)) + +# Find all the .extra files in the src dirs. +MOD_FILES := $(wildcard $(foreach f, $(MOD_FILENAME), $(addsuffix /$(f), \ + $(MODULE_CLASSES_DIRS)))) + +ifneq ($(MOD_FILES), ) + # Only make this call if modification files are found for this module + ALL_MODULES := $(call FindAllModules) + + $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/module-info.java: \ + $(firstword $(call FindAllModuleInfos, $(MODULE))) \ + $(BUILD_TOOLS_JDK) \ + $(MOD_FILES) \ + $(call DependOnVariable, ALL_MODULES) + $(call MakeTargetDir) + $(RM) $@ $@.tmp + $(TOOL_GENMODULEINFOSOURCE) -o $@.tmp \ + --source-file $< \ + --modules $(call CommaList, $(ALL_MODULES)) \ + $(MOD_FILES) + $(MV) $@.tmp $@ + + TARGETS += $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/module-info.java + +else + # If no modifications are found for this module, remove any module-info.java + # created by a previous build since that is no longer valid. + ifneq ($(wildcard $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/module-info.java), ) + $(shell $(RM) $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/module-info.java) + endif +endif + +################################################################################ + +all: $(TARGETS) diff -r 08102295011d -r 18659e040c64 make/gensrc/GensrcVarHandles.gmk --- a/make/gensrc/GensrcVarHandles.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/gensrc/GensrcVarHandles.gmk Wed Nov 06 17:13:26 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 @@ -173,4 +173,3 @@ # Include custom extension post hook $(eval $(call IncludeCustomExtension, gensrc/GensrcVarHandles-post.gmk)) - diff -r 08102295011d -r 18659e040c64 make/hotspot/CopyToExplodedJdk.gmk --- a/make/hotspot/CopyToExplodedJdk.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/hotspot/CopyToExplodedJdk.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/hotspot/lib/CompileDtraceLibraries.gmk --- a/make/hotspot/lib/CompileDtraceLibraries.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/hotspot/lib/CompileDtraceLibraries.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/hotspot/lib/JvmDtraceObjects.gmk --- a/make/hotspot/lib/JvmDtraceObjects.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/hotspot/lib/JvmDtraceObjects.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/hotspot/lib/JvmFlags.gmk --- a/make/hotspot/lib/JvmFlags.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/hotspot/lib/JvmFlags.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/hotspot/lib/JvmMapfile.gmk --- a/make/hotspot/lib/JvmMapfile.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/hotspot/lib/JvmMapfile.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2016, 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 diff -r 08102295011d -r 18659e040c64 make/hotspot/symbols/symbols-unix --- a/make/hotspot/symbols/symbols-unix Fri Nov 01 14:18:40 2019 +0100 +++ b/make/hotspot/symbols/symbols-unix Wed Nov 06 17:13:26 2019 +0100 @@ -46,7 +46,6 @@ JVM_ConstantPoolGetStringAt JVM_ConstantPoolGetTagAt JVM_ConstantPoolGetUTF8At -JVM_CountStackFrames JVM_CurrentThread JVM_CurrentTimeMillis JVM_DefineClass @@ -143,14 +142,12 @@ JVM_IsArrayClass JVM_IsConstructorIx JVM_IsInterface -JVM_IsInterrupted JVM_IsPrimitiveClass JVM_IsSameClassPackage JVM_IsSupportedJNIVersion JVM_IsThreadAlive JVM_IsVMGeneratedMethodIx JVM_LatestUserDefinedLoader -JVM_LinkClass JVM_LoadLibrary JVM_MaxMemory JVM_MaxObjectInspectionAge diff -r 08102295011d -r 18659e040c64 make/hotspot/test/GtestImage.gmk --- a/make/hotspot/test/GtestImage.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/hotspot/test/GtestImage.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/launcher/Launcher-java.security.jgss.gmk --- a/make/launcher/Launcher-java.security.jgss.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/launcher/Launcher-java.security.jgss.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, 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 diff -r 08102295011d -r 18659e040c64 make/launcher/Launcher-jdk.pack.gmk --- a/make/launcher/Launcher-jdk.pack.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/launcher/Launcher-jdk.pack.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/lib/CoreLibraries.gmk --- a/make/lib/CoreLibraries.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/CoreLibraries.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/lib/Lib-java.base.gmk --- a/make/lib/Lib-java.base.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-java.base.gmk Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 make/lib/Lib-java.instrument.gmk --- a/make/lib/Lib-java.instrument.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-java.instrument.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/lib/Lib-java.management.gmk --- a/make/lib/Lib-java.management.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-java.management.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/lib/Lib-java.prefs.gmk --- a/make/lib/Lib-java.prefs.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-java.prefs.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/lib/Lib-jdk.accessibility.gmk --- a/make/lib/Lib-jdk.accessibility.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-jdk.accessibility.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/lib/Lib-jdk.attach.gmk --- a/make/lib/Lib-jdk.attach.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-jdk.attach.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/lib/Lib-jdk.crypto.mscapi.gmk --- a/make/lib/Lib-jdk.crypto.mscapi.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-jdk.crypto.mscapi.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/lib/Lib-jdk.crypto.ucrypto.gmk --- a/make/lib/Lib-jdk.crypto.ucrypto.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-jdk.crypto.ucrypto.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it diff -r 08102295011d -r 18659e040c64 make/lib/Lib-jdk.hotspot.agent.gmk --- a/make/lib/Lib-jdk.hotspot.agent.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-jdk.hotspot.agent.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -53,10 +53,16 @@ endif endif +SA_TOOLCHAIN := $(TOOLCHAIN_DEFAULT) +ifeq ($(call isTargetOs, linux), true) + SA_TOOLCHAIN := TOOLCHAIN_BUILD_LINK_CXX +endif + ################################################################################ $(eval $(call SetupJdkLibrary, BUILD_LIBSA, \ NAME := saproc, \ + TOOLCHAIN := $(SA_TOOLCHAIN), \ OPTIMIZATION := HIGH, \ DISABLED_WARNINGS_microsoft := 4267, \ DISABLED_WARNINGS_gcc := sign-compare pointer-arith, \ diff -r 08102295011d -r 18659e040c64 make/lib/Lib-jdk.internal.le.gmk --- a/make/lib/Lib-jdk.internal.le.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-jdk.internal.le.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/lib/Lib-jdk.jdi.gmk --- a/make/lib/Lib-jdk.jdi.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-jdk.jdi.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/lib/Lib-jdk.jdwp.agent.gmk --- a/make/lib/Lib-jdk.jdwp.agent.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-jdk.jdwp.agent.gmk Wed Nov 06 17:13:26 2019 +0100 @@ -38,7 +38,7 @@ $(call SET_SHARED_LIBRARY_ORIGIN), \ LIBS_linux := -lpthread, \ LIBS_solaris := -lnsl -lsocket, \ - LIBS_windows := $(JDKLIB_LIBS) ws2_32.lib, \ + LIBS_windows := $(JDKLIB_LIBS) ws2_32.lib iphlpapi.lib, \ )) $(BUILD_LIBDT_SOCKET): $(call FindLib, java.base, java) diff -r 08102295011d -r 18659e040c64 make/lib/Lib-jdk.management.gmk --- a/make/lib/Lib-jdk.management.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-jdk.management.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/lib/Lib-jdk.net.gmk --- a/make/lib/Lib-jdk.net.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-jdk.net.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/lib/Lib-jdk.sctp.gmk --- a/make/lib/Lib-jdk.sctp.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/lib/Lib-jdk.sctp.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/rmic/Rmic-java.management.rmi.gmk --- a/make/rmic/Rmic-java.management.rmi.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/rmic/Rmic-java.management.rmi.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/test/BuildFailureHandler.gmk --- a/make/test/BuildFailureHandler.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/test/BuildFailureHandler.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 make/test/JtregGraalUnit.gmk --- a/make/test/JtregGraalUnit.gmk Fri Nov 01 14:18:40 2019 +0100 +++ b/make/test/JtregGraalUnit.gmk Wed Nov 06 17:13:26 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 diff -r 08102295011d -r 18659e040c64 src/hotspot/.mx.jvmci/suite.py --- a/src/hotspot/.mx.jvmci/suite.py Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/.mx.jvmci/suite.py Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 src/hotspot/cpu/aarch64/aarch64.ad --- a/src/hotspot/cpu/aarch64/aarch64.ad Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/aarch64/aarch64.ad Wed Nov 06 17:13:26 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 08102295011d -r 18659e040c64 src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -1978,6 +1978,9 @@ case T_ADDRESS: imm = opr2->as_constant_ptr()->as_jint(); break; + case T_METADATA: + imm = (intptr_t)(opr2->as_constant_ptr()->as_metadata()); + break; case T_OBJECT: case T_ARRAY: jobject2reg(opr2->as_constant_ptr()->as_jobject(), rscratch1); diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -23,6 +23,7 @@ #include "precompiled.hpp" #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" +#include "gc/shenandoah/shenandoahConcurrentRoots.hpp" #include "gc/shenandoah/shenandoahForwarding.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" @@ -346,29 +347,44 @@ } } +// +// Arguments: +// +// Inputs: +// src: oop location to load from, might be clobbered +// +// Output: +// dst: oop loaded from src location +// +// Kill: +// rscratch1 (scratch reg) +// +// Alias: +// dst: rscratch1 (might use rscratch1 as temporary output register to avoid clobbering src) +// void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register dst, Address src, Register tmp1, Register tmp_thread) { - bool on_oop = is_reference_type(type); - bool not_in_heap = (decorators & IN_NATIVE) != 0; - bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0; - bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; - bool on_reference = on_weak || on_phantom; - bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); - bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; + // 1: non-reference load, no additional barrier is needed + if (!is_reference_type(type)) { + BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); + return; + } - Register result_dst = dst; + // 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set + if (ShenandoahLoadRefBarrier) { + Register result_dst = dst; - if (on_oop) { - // We want to preserve src + // Preserve src location for LRB if (dst == src.base() || dst == src.index()) { dst = rscratch1; } assert_different_registers(dst, src.base(), src.index()); - } + + BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); - BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); - if (on_oop) { - if (not_in_heap && !is_traversal_mode) { + // Native barrier is for concurrent root processing + bool in_native = (decorators & IN_NATIVE) != 0; + if (in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots()) { load_reference_barrier_native(masm, dst, src); } else { load_reference_barrier(masm, dst, src); @@ -378,8 +394,19 @@ __ mov(result_dst, dst); dst = result_dst; } + } else { + BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); + } - if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) { + // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set + if (ShenandoahKeepAliveBarrier) { + bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0; + bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; + bool on_reference = on_weak || on_phantom; + bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); + bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; + + if (on_reference && keep_alive) { __ enter(); satb_write_barrier_pre(masm /* masm */, noreg /* obj */, @@ -443,8 +470,9 @@ __ cbz(obj, done); assert(obj != rscratch2, "need rscratch2"); - Address gc_state(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); - __ ldrb(rscratch2, gc_state); + Address gc_state(jni_env, ShenandoahThreadLocalData::gc_state_offset() - JavaThread::jni_environment_offset()); + __ lea(rscratch2, gc_state); + __ ldrb(rscratch2, Address(rscratch2)); // Check for heap in evacuation phase __ tbnz(rscratch2, ShenandoahHeap::EVACUATION_BITPOS, slowpath); @@ -544,7 +572,7 @@ Register obj = stub->obj()->as_register(); Register res = stub->result()->as_register(); - Register addr = stub->addr()->as_register_lo(); + Register addr = stub->addr()->as_pointer_register(); Register tmp1 = stub->tmp1()->as_register(); Register tmp2 = stub->tmp2()->as_register(); diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -287,8 +287,6 @@ //------------------------------------------------------------------- -address NativeMovRegMem::instruction_address() const { return addr_at(instruction_offset); } - int NativeMovRegMem::offset() const { address pc = instruction_address(); unsigned insn = *(unsigned*)pc; diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -381,11 +381,11 @@ public: // helper - int instruction_start() const; + int instruction_start() const { return instruction_offset; } - address instruction_address() const; + address instruction_address() const { return addr_at(instruction_offset); } - address next_instruction_address() const; + int num_bytes_to_end_of_patch() const { return instruction_offset + instruction_size; } int offset() const; diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp --- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -1817,6 +1817,11 @@ assert(opr2->as_constant_ptr()->as_jobject() == NULL, "cannot handle otherwise"); __ cmp(opr1->as_register(), 0); break; + case T_METADATA: + assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "Only equality tests"); + assert(opr2->as_constant_ptr()->as_metadata() == NULL, "cannot handle otherwise"); + __ cmp(opr1->as_register(), 0); + break; default: ShouldNotReachHere(); } diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/arm/nativeInst_arm_32.hpp --- a/src/hotspot/cpu/arm/nativeInst_arm_32.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/arm/nativeInst_arm_32.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -349,6 +349,11 @@ // (field access patching is handled differently in that case) class NativeMovRegMem: public NativeInstruction { public: + enum arm_specific_constants { + instruction_size = 8 + }; + + int num_bytes_to_end_of_patch() const { return instruction_size; } int offset() const; void set_offset(int x); diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/arm/vtableStubs_arm.cpp --- a/src/hotspot/cpu/arm/vtableStubs_arm.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/arm/vtableStubs_arm.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ #include "oops/compiledICHolder.hpp" #include "oops/instanceKlass.hpp" #include "oops/klassVtable.hpp" +#include "oops/klass.inline.hpp" #include "runtime/sharedRuntime.hpp" #include "vmreg_arm.inline.hpp" #ifdef COMPILER2 diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp --- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -1467,6 +1467,19 @@ } break; + case T_METADATA: + // We only need, for now, comparison with NULL for metadata. + { + assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops"); + Metadata* p = opr2->as_constant_ptr()->as_metadata(); + if (p == NULL) { + __ cmpdi(BOOL_RESULT, opr1->as_register(), 0); + } else { + ShouldNotReachHere(); + } + } + break; + default: ShouldNotReachHere(); break; diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/ppc/c1_globals_ppc.hpp --- a/src/hotspot/cpu/ppc/c1_globals_ppc.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/ppc/c1_globals_ppc.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -1,6 +1,6 @@ /* * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2018 SAP SE. All rights reserved. + * Copyright (c) 2012, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,8 +48,12 @@ define_pd_global(intx, FreqInlineSize, 325 ); define_pd_global(bool, ResizeTLAB, true); define_pd_global(uintx, ReservedCodeCacheSize, 32*M); +define_pd_global(uintx, NonProfiledCodeHeapSize, 13*M ); +define_pd_global(uintx, ProfiledCodeHeapSize, 14*M ); +define_pd_global(uintx, NonNMethodCodeHeapSize, 5*M ); define_pd_global(uintx, CodeCacheExpansionSize, 32*K); define_pd_global(uintx, CodeCacheMinBlockLength, 1); +define_pd_global(uintx, CodeCacheMinimumUseSpace, 400*K); define_pd_global(size_t, MetaspaceSize, 12*M); define_pd_global(bool, NeverActAsServerClassMachine, true); define_pd_global(size_t, NewSizeThreadIncrease, 16*K); diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/ppc/disassembler_ppc.cpp --- a/src/hotspot/cpu/ppc/disassembler_ppc.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/ppc/disassembler_ppc.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -27,8 +27,6 @@ #include "code/codeCache.hpp" #include "compiler/disassembler.hpp" #include "depChecker_ppc.hpp" -#include "gc/cms/concurrentMarkSweepGeneration.inline.hpp" -#include "gc/cms/parOopClosures.inline.hpp" #include "gc/shared/collectedHeap.hpp" #include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/genOopClosures.inline.hpp" diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp --- a/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -50,6 +50,8 @@ #if defined(COMPILER2) && (defined(AIX) || defined(LINUX)) // Include Transactional Memory lock eliding optimization #define INCLUDE_RTM_OPT 1 +#else +#define INCLUDE_RTM_OPT 0 #endif #define SUPPORT_RESERVED_STACK_AREA diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/ppc/nativeInst_ppc.hpp --- a/src/hotspot/cpu/ppc/nativeInst_ppc.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/ppc/nativeInst_ppc.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -462,6 +462,8 @@ address instruction_address() const { return addr_at(0); } + int num_bytes_to_end_of_patch() const { return instruction_size; } + intptr_t offset() const { #ifdef VM_LITTLE_ENDIAN short *hi_ptr = (short*)(addr_at(0)); diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -571,7 +571,6 @@ __ bctr(); } -#ifdef COMPILER2 static int reg2slot(VMReg r) { return r->reg2stack() + SharedRuntime::out_preserve_stack_slots(); } @@ -579,7 +578,6 @@ static int reg2offset(VMReg r) { return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; } -#endif // --------------------------------------------------------------------------- // Read the array of BasicTypes from a signature, and compute where the @@ -1305,7 +1303,6 @@ return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, c2i_no_clinit_check_entry); } -#ifdef COMPILER2 // An oop arg. Must pass a handle not the oop itself. static void object_move(MacroAssembler* masm, int frame_size_in_slots, @@ -1813,8 +1810,6 @@ receiver_reg, member_reg, /*for_compiler_entry:*/ true); } -#endif // COMPILER2 - // --------------------------------------------------------------------------- // Generate a native wrapper for a given method. The method takes arguments // in the Java compiled code convention, marshals them to the native @@ -1851,7 +1846,6 @@ VMRegPair *in_regs, BasicType ret_type, address critical_entry) { -#ifdef COMPILER2 if (method->is_method_handle_intrinsic()) { vmIntrinsics::ID iid = method->intrinsic_id(); intptr_t start = (intptr_t)__ pc(); @@ -2108,7 +2102,7 @@ // Check ic: object class == cached class? if (!method_is_static) { - Register ic = as_Register(Matcher::inline_cache_reg_encode()); + Register ic = R19_inline_cache_reg; Register receiver_klass = r_temp_1; __ cmpdi(CCR0, R3_ARG1, 0); @@ -2638,12 +2632,10 @@ // Handler for pending exceptions (out-of-line). // -------------------------------------------------------------------------- - // Since this is a native call, we know the proper exception handler // is the empty function. We just pop this frame and then jump to // forward_exception_entry. if (!is_critical_native) { - __ align(InteriorEntryAlignment); __ bind(handle_pending_exception); __ pop_frame(); @@ -2656,7 +2648,6 @@ // -------------------------------------------------------------------------- if (!method_is_static) { - __ align(InteriorEntryAlignment); __ bind(ic_miss); __ b64_patchable((address)SharedRuntime::get_ic_miss_stub(), @@ -2683,10 +2674,6 @@ } return nm; -#else - ShouldNotReachHere(); - return NULL; -#endif // COMPILER2 } // This function returns the adjust size (in number of words) to a c2i adapter @@ -2863,7 +2850,7 @@ // We can't grab a free register here, because all registers may // contain live values, so let the RegisterSaver do the adjustment // of the return pc. - const int return_pc_adjustment_no_exception = -HandlerImpl::size_deopt_handler(); + const int return_pc_adjustment_no_exception = -MacroAssembler::bl64_patchable_size; // Push the "unpack frame" // Save everything in sight. diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/ppc/stubGenerator_ppc.cpp --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -3103,6 +3103,7 @@ STUB_ENTRY(checkcast_arraycopy)); // fill routines +#ifdef COMPILER2 if (OptimizeFill) { StubRoutines::_jbyte_fill = generate_fill(T_BYTE, false, "jbyte_fill"); StubRoutines::_jshort_fill = generate_fill(T_SHORT, false, "jshort_fill"); @@ -3111,6 +3112,7 @@ StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill"); StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill"); } +#endif } // Safefetch stubs. @@ -3579,8 +3581,6 @@ if (UseMultiplyToLenIntrinsic) { StubRoutines::_multiplyToLen = generate_multiplyToLen(); } -#endif - if (UseSquareToLenIntrinsic) { StubRoutines::_squareToLen = generate_squareToLen(); } @@ -3595,6 +3595,7 @@ StubRoutines::_montgomerySquare = CAST_FROM_FN_PTR(address, SharedRuntime::montgomery_square); } +#endif if (UseAESIntrinsics) { StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock(); diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/ppc/vm_version_ppc.cpp --- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -312,6 +312,7 @@ FLAG_SET_DEFAULT(UseSHA, false); } +#ifdef COMPILER2 if (FLAG_IS_DEFAULT(UseSquareToLenIntrinsic)) { UseSquareToLenIntrinsic = true; } @@ -327,6 +328,7 @@ if (FLAG_IS_DEFAULT(UseMontgomerySquareIntrinsic)) { UseMontgomerySquareIntrinsic = true; } +#endif if (UseVectorizedMismatchIntrinsic) { warning("UseVectorizedMismatchIntrinsic specified, but not available on this CPU."); @@ -373,9 +375,11 @@ if (UseRTMDeopt) { FLAG_SET_DEFAULT(UseRTMDeopt, false); } +#ifdef COMPILER2 if (PrintPreciseRTMLockingStatistics) { FLAG_SET_DEFAULT(PrintPreciseRTMLockingStatistics, false); } +#endif } // This machine allows unaligned memory accesses diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -1322,6 +1322,15 @@ } else { __ z_cfi(reg1, c->as_jint()); } + } else if (c->type() == T_METADATA) { + // We only need, for now, comparison with NULL for metadata. + assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops"); + Metadata* m = c->as_metadata(); + if (m == NULL) { + __ z_cghi(reg1, 0); + } else { + ShouldNotReachHere(); + } } else if (is_reference_type(c->type())) { // In 64bit oops are single register. jobject o = c->as_jobject(); diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/s390/nativeInst_s390.hpp --- a/src/hotspot/cpu/s390/nativeInst_s390.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/s390/nativeInst_s390.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -535,6 +535,12 @@ inline NativeMovRegMem* nativeMovRegMem_at (address address); class NativeMovRegMem: public NativeInstruction { public: + enum z_specific_constants { + instruction_size = 12 // load_const used with access_field_id + }; + + int num_bytes_to_end_of_patch() const { return instruction_size; } + intptr_t offset() const { return nativeMovConstReg_at(addr_at(0))->data(); } diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp --- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -1511,6 +1511,18 @@ } break; + case T_METADATA: + // We only need, for now, comparison with NULL for metadata. + { assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops"); + Metadata* m = opr2->as_constant_ptr()->as_metadata(); + if (m == NULL) { + __ cmp(opr1->as_register(), 0); + } else { + ShouldNotReachHere(); + } + } + break; + default: ShouldNotReachHere(); break; diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/sparc/nativeInst_sparc.cpp --- a/src/hotspot/cpu/sparc/nativeInst_sparc.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/sparc/nativeInst_sparc.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -574,15 +574,6 @@ //------------------------------------------------------------------- -void NativeMovRegMem::copy_instruction_to(address new_instruction_address) { - Untested("copy_instruction_to"); - int instruction_size = next_instruction_address() - instruction_address(); - for (int i = 0; i < instruction_size; i += BytesPerInstWord) { - *(int*)(new_instruction_address + i) = *(int*)(address(this) + i); - } -} - - void NativeMovRegMem::verify() { NativeInstruction::verify(); // make sure code pattern is actually a "ld" or "st" of some sort. diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/sparc/nativeInst_sparc.hpp --- a/src/hotspot/cpu/sparc/nativeInst_sparc.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/sparc/nativeInst_sparc.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -576,7 +576,8 @@ // sethi and the add. The nop is required to be in the delay slot of the call instruction // which overwrites the sethi during patching. class NativeMovConstRegPatching; -inline NativeMovConstRegPatching* nativeMovConstRegPatching_at(address address);class NativeMovConstRegPatching: public NativeInstruction { +inline NativeMovConstRegPatching* nativeMovConstRegPatching_at(address address); +class NativeMovConstRegPatching: public NativeInstruction { public: enum Sparc_specific_constants { sethi_offset = 0, @@ -664,10 +665,13 @@ return (is_op(i0, Assembler::ldst_op)); } - address instruction_address() const { return addr_at(0); } - address next_instruction_address() const { - return addr_at(is_immediate() ? 4 : (7 * BytesPerInstWord)); + address instruction_address() const { return addr_at(0); } + + int num_bytes_to_end_of_patch() const { + return is_immediate()? BytesPerInstWord : + NativeMovConstReg::instruction_size; } + intptr_t offset() const { return is_immediate()? inv_simm(long_at(0), offset_width) : nativeMovConstReg_at(addr_at(0))->data(); @@ -684,8 +688,6 @@ set_offset (offset() + radd_offset); } - void copy_instruction_to(address new_instruction_address); - void verify(); void print (); diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -2641,6 +2641,15 @@ LIR_Const* c = opr2->as_constant_ptr(); if (c->type() == T_INT) { __ cmpl(reg1, c->as_jint()); + } else if (c->type() == T_METADATA) { + // All we need for now is a comparison with NULL for equality. + assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops"); + Metadata* m = c->as_metadata(); + if (m == NULL) { + __ cmpptr(reg1, (int32_t)0); + } else { + ShouldNotReachHere(); + } } else if (is_reference_type(c->type())) { // In 64bit oops are single register jobject o = c->as_jobject(); diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -23,6 +23,7 @@ #include "precompiled.hpp" #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" +#include "gc/shenandoah/shenandoahConcurrentRoots.hpp" #include "gc/shenandoah/shenandoahForwarding.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" @@ -445,21 +446,33 @@ } } +// +// Arguments: +// +// Inputs: +// src: oop location, might be clobbered +// tmp1: scratch register, might not be valid. +// +// Output: +// dst: oop loaded from src location +// +// Kill: +// tmp1 (if it is valid) +// void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register dst, Address src, Register tmp1, Register tmp_thread) { - bool on_oop = is_reference_type(type); - bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0; - bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; - bool not_in_heap = (decorators & IN_NATIVE) != 0; - bool on_reference = on_weak || on_phantom; - bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); - bool keep_alive = ((decorators & AS_NO_KEEPALIVE) == 0) || is_traversal_mode; + // 1: non-reference load, no additional barrier is needed + if (!is_reference_type(type)) { + BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); + return; + } - Register result_dst = dst; - bool use_tmp1_for_dst = false; + // 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set + if (ShenandoahLoadRefBarrier) { + Register result_dst = dst; + bool use_tmp1_for_dst = false; - if (on_oop) { - // We want to preserve src + // Preserve src location for LRB if (dst == src.base() || dst == src.index()) { // Use tmp1 for dst if possible, as it is not used in BarrierAssembler::load_at() if (tmp1->is_valid() && tmp1 != src.base() && tmp1 != src.index()) { @@ -469,19 +482,20 @@ dst = rdi; __ push(dst); } + assert_different_registers(dst, src.base(), src.index()); } - assert_different_registers(dst, src.base(), src.index()); - } - BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); + BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); - if (on_oop) { - if (not_in_heap && !is_traversal_mode) { + // Native barrier is for concurrent root processing + bool in_native = (decorators & IN_NATIVE) != 0; + if (in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots()) { load_reference_barrier_native(masm, dst, src); } else { load_reference_barrier(masm, dst, src); } + // Move loaded oop to final destination if (dst != result_dst) { __ movptr(result_dst, dst); @@ -491,8 +505,19 @@ dst = result_dst; } + } else { + BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread); + } - if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) { + // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set + if (ShenandoahKeepAliveBarrier) { + bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0; + bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; + bool on_reference = on_weak || on_phantom; + bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); + bool keep_alive = ((decorators & AS_NO_KEEPALIVE) == 0) || is_traversal_mode; + + if (on_reference && keep_alive) { const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread); assert_different_registers(dst, tmp1, tmp_thread); NOT_LP64(__ get_thread(thread)); diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/x86/nativeInst_x86.cpp --- a/src/hotspot/cpu/x86/nativeInst_x86.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/x86/nativeInst_x86.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -355,60 +355,7 @@ return off; } -address NativeMovRegMem::instruction_address() const { - return addr_at(instruction_start()); -} - -address NativeMovRegMem::next_instruction_address() const { - address ret = instruction_address() + instruction_size; - u_char instr_0 = *(u_char*) instruction_address(); - switch (instr_0) { - case instruction_operandsize_prefix: - - fatal("should have skipped instruction_operandsize_prefix"); - break; - - case instruction_extended_prefix: - fatal("should have skipped instruction_extended_prefix"); - break; - - case instruction_code_mem2reg_movslq: // 0x63 - case instruction_code_mem2reg_movzxb: // 0xB6 - case instruction_code_mem2reg_movsxb: // 0xBE - case instruction_code_mem2reg_movzxw: // 0xB7 - case instruction_code_mem2reg_movsxw: // 0xBF - case instruction_code_reg2mem: // 0x89 (q/l) - case instruction_code_mem2reg: // 0x8B (q/l) - case instruction_code_reg2memb: // 0x88 - case instruction_code_mem2regb: // 0x8a - - case instruction_code_lea: // 0x8d - - case instruction_code_float_s: // 0xd9 fld_s a - case instruction_code_float_d: // 0xdd fld_d a - - case instruction_code_xmm_load: // 0x10 - case instruction_code_xmm_store: // 0x11 - case instruction_code_xmm_lpd: // 0x12 - { - // If there is an SIB then instruction is longer than expected - u_char mod_rm = *(u_char*)(instruction_address() + 1); - if ((mod_rm & 7) == 0x4) { - ret++; - } - } - case instruction_code_xor: - fatal("should have skipped xor lead in"); - break; - - default: - fatal("not a NativeMovRegMem"); - } - return ret; - -} - -int NativeMovRegMem::offset() const{ +int NativeMovRegMem::patch_offset() const { int off = data_offset + instruction_start(); u_char mod_rm = *(u_char*)(instruction_address() + 1); // nnnn(r12|rsp) isn't coded as simple mod/rm since that is @@ -417,19 +364,7 @@ if ((mod_rm & 7) == 0x4) { off++; } - return int_at(off); -} - -void NativeMovRegMem::set_offset(int x) { - int off = data_offset + instruction_start(); - u_char mod_rm = *(u_char*)(instruction_address() + 1); - // nnnn(r12|rsp) isn't coded as simple mod/rm since that is - // the encoding to use an SIB byte. Which will have the nnnn - // field off by one byte - if ((mod_rm & 7) == 0x4) { - off++; - } - set_int_at(off, x); + return off; } void NativeMovRegMem::verify() { diff -r 08102295011d -r 18659e040c64 src/hotspot/cpu/x86/nativeInst_x86.hpp --- a/src/hotspot/cpu/x86/nativeInst_x86.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/cpu/x86/nativeInst_x86.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -361,7 +361,6 @@ instruction_VEX_prefix_3bytes = Assembler::VEX_3bytes, instruction_EVEX_prefix_4bytes = Assembler::EVEX_4bytes, - instruction_size = 4, instruction_offset = 0, data_offset = 2, next_instruction_offset = 4 @@ -370,15 +369,26 @@ // helper int instruction_start() const; - address instruction_address() const; + address instruction_address() const { + return addr_at(instruction_start()); + } - address next_instruction_address() const; + int num_bytes_to_end_of_patch() const { + return patch_offset() + sizeof(jint); + } - int offset() const; + int offset() const { + return int_at(patch_offset()); + } - void set_offset(int x); + void set_offset(int x) { + set_int_at(patch_offset(), x); + } - void add_offset_in_bytes(int add_offset) { set_offset ( ( offset() + add_offset ) ); } + void add_offset_in_bytes(int add_offset) { + int patch_off = patch_offset(); + set_int_at(patch_off, int_at(patch_off) + add_offset); + } void verify(); void print (); @@ -387,6 +397,7 @@ static void test() {} private: + int patch_offset() const; inline friend NativeMovRegMem* nativeMovRegMem_at (address address); }; diff -r 08102295011d -r 18659e040c64 src/hotspot/os/linux/osContainer_linux.cpp --- a/src/hotspot/os/linux/osContainer_linux.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/os/linux/osContainer_linux.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -54,12 +54,16 @@ bool OSContainer::_is_initialized = false; bool OSContainer::_is_containerized = false; +int OSContainer::_active_processor_count = 1; julong _unlimited_memory; class CgroupSubsystem: CHeapObj { friend class OSContainer; + private: + volatile jlong _next_check_counter; + /* mountinfo contents */ char *_root; char *_mount_point; @@ -72,6 +76,7 @@ _root = os::strdup(root); _mount_point = os::strdup(mountpoint); _path = NULL; + _next_check_counter = min_jlong; } /* @@ -121,6 +126,14 @@ } char *subsystem_path() { return _path; } + + bool cache_has_expired() { + return os::elapsed_counter() > _next_check_counter; + } + + void set_cache_expiry_time(jlong timeout) { + _next_check_counter = os::elapsed_counter() + timeout; + } }; class CgroupMemorySubsystem: CgroupSubsystem { @@ -132,31 +145,26 @@ * file if everything else seems unlimited */ bool _uses_mem_hierarchy; volatile jlong _memory_limit_in_bytes; - volatile jlong _next_check_counter; public: CgroupMemorySubsystem(char *root, char *mountpoint) : CgroupSubsystem::CgroupSubsystem(root, mountpoint) { _uses_mem_hierarchy = false; _memory_limit_in_bytes = -1; - _next_check_counter = min_jlong; } bool is_hierarchical() { return _uses_mem_hierarchy; } void set_hierarchical(bool value) { _uses_mem_hierarchy = value; } - bool should_check_memory_limit() { - return os::elapsed_counter() > _next_check_counter; - } jlong memory_limit_in_bytes() { return _memory_limit_in_bytes; } void set_memory_limit_in_bytes(jlong value) { _memory_limit_in_bytes = value; // max memory limit is unlikely to change, but we want to remain - // responsive to configuration changes. A very short (20ms) grace time + // responsive to configuration changes. A very short grace time // between re-read avoids excessive overhead during startup without // significantly reducing the VMs ability to promptly react to reduced // memory availability - _next_check_counter = os::elapsed_counter() + (NANOSECS_PER_SEC/50); + set_cache_expiry_time(OSCONTAINER_CACHE_TIMEOUT); } }; @@ -481,7 +489,7 @@ * OSCONTAINER_ERROR for not supported */ jlong OSContainer::memory_limit_in_bytes() { - if (!memory->should_check_memory_limit()) { + if (!memory->cache_has_expired()) { return memory->memory_limit_in_bytes(); } jlong memory_limit = read_memory_limit_in_bytes(); @@ -617,6 +625,14 @@ int cpu_count, limit_count; int result; + // We use a cache with a timeout to avoid performing expensive + // computations in the event this function is called frequently. + // [See 8227006]. + if (!cpu->cache_has_expired()) { + log_trace(os, container)("OSContainer::active_processor_count (cached): %d", OSContainer::_active_processor_count); + return OSContainer::_active_processor_count; + } + cpu_count = limit_count = os::Linux::active_processor_count(); int quota = cpu_quota(); int period = cpu_period(); @@ -649,6 +665,11 @@ result = MIN2(cpu_count, limit_count); log_trace(os, container)("OSContainer::active_processor_count: %d", result); + + // Update the value and reset the cache timeout + OSContainer::_active_processor_count = result; + cpu->set_cache_expiry_time(OSCONTAINER_CACHE_TIMEOUT); + return result; } diff -r 08102295011d -r 18659e040c64 src/hotspot/os/linux/osContainer_linux.hpp --- a/src/hotspot/os/linux/osContainer_linux.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/os/linux/osContainer_linux.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -31,11 +31,16 @@ #define OSCONTAINER_ERROR (-2) +// 20ms timeout between re-reads of memory limit and _active_processor_count. +#define OSCONTAINER_CACHE_TIMEOUT (NANOSECS_PER_SEC/50) + class OSContainer: AllStatic { private: static bool _is_initialized; static bool _is_containerized; + static int _active_processor_count; + static jlong read_memory_limit_in_bytes(); public: diff -r 08102295011d -r 18659e040c64 src/hotspot/os/windows/osThread_windows.cpp --- a/src/hotspot/os/windows/osThread_windows.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/os/windows/osThread_windows.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -39,28 +39,15 @@ } } -// We need to specialize these to interact with the _interrupt_event. - -volatile bool OSThread::interrupted() { - return _interrupted != 0 && - (WaitForSingleObject(_interrupt_event, 0) == WAIT_OBJECT_0); -} +// We need to specialize this to interact with the _interrupt_event. void OSThread::set_interrupted(bool z) { if (z) { - _interrupted = 1; - // More than one thread can get here with the same value of osthread, - // resulting in multiple notifications. We do, however, want the store - // to interrupted() to be visible to other threads before we post - // the interrupt event. - OrderAccess::release(); SetEvent(_interrupt_event); } else { // We should only ever clear the interrupt if we are in fact interrupted, // and this can only be done by the current thread on itself. - assert(_interrupted == 1, "invariant for clearing interrupt state"); - _interrupted = 0; ResetEvent(_interrupt_event); } } diff -r 08102295011d -r 18659e040c64 src/hotspot/os/windows/osThread_windows.hpp --- a/src/hotspot/os/windows/osThread_windows.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/os/windows/osThread_windows.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -43,10 +43,7 @@ void set_thread_handle(HANDLE handle) { _thread_handle = handle; } HANDLE interrupt_event() const { return _interrupt_event; } void set_interrupt_event(HANDLE interrupt_event) { _interrupt_event = interrupt_event; } - // These are specialized on Windows to interact with the _interrupt_event. - // Also note that Windows does not skip these calls if we are interrupted - see - // LibraryCallKit::inline_native_isInterrupted - volatile bool interrupted(); + // This is specialized on Windows to interact with the _interrupt_event. void set_interrupted(bool z); #ifndef PRODUCT diff -r 08102295011d -r 18659e040c64 src/hotspot/share/aot/aotCodeHeap.cpp --- a/src/hotspot/share/aot/aotCodeHeap.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/aot/aotCodeHeap.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -450,7 +450,6 @@ SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_jvmci_runtime_write_barrier_post", address, JVMCIRuntime::write_barrier_post); #endif SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_jvmci_runtime_identity_hash_code", address, JVMCIRuntime::identity_hash_code); - SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_jvmci_runtime_thread_is_interrupted", address, JVMCIRuntime::thread_is_interrupted); SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_jvmci_runtime_exception_handler_for_pc", address, JVMCIRuntime::exception_handler_for_pc); SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_jvmci_runtime_test_deoptimize_call_int", address, JVMCIRuntime::test_deoptimize_call_int); SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_jvmci_runtime_throw_and_post_jvmti_exception", address, JVMCIRuntime::throw_and_post_jvmti_exception); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/c1/c1_CodeStubs.hpp --- a/src/hotspot/share/c1/c1_CodeStubs.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/c1/c1_CodeStubs.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -409,7 +409,7 @@ if (_id == PatchingStub::access_field_id) { // embed a fixed offset to handle long patches which need to be offset by a word. // the patching code will just add the field offset field to this offset so - // that we can refernce either the high or low word of a double word field. + // that we can reference either the high or low word of a double word field. int field_offset = 0; switch (patch_code) { case lir_patch_low: field_offset = lo_word_offset_in_bytes; break; @@ -419,6 +419,8 @@ } NativeMovRegMem* n_move = nativeMovRegMem_at(pc_start()); n_move->set_offset(field_offset); + // Copy will never get executed, so only copy the part which is required for patching. + _bytes_to_copy = MAX2(n_move->num_bytes_to_end_of_patch(), (int)NativeGeneralJump::instruction_size); } else if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) { assert(_obj != noreg, "must have register object for load_klass/load_mirror"); #ifdef ASSERT diff -r 08102295011d -r 18659e040c64 src/hotspot/share/c1/c1_LIRGenerator.cpp --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -1301,7 +1301,7 @@ } __ move(new LIR_Address(rcvr.result(), java_lang_Class::klass_offset_in_bytes(), T_ADDRESS), temp, info); - __ cmp(lir_cond_notEqual, temp, LIR_OprFact::intConst(0)); + __ cmp(lir_cond_notEqual, temp, LIR_OprFact::metadataConst(0)); __ cmove(lir_cond_notEqual, LIR_OprFact::intConst(0), LIR_OprFact::intConst(1), result, T_BOOLEAN); } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/ci/ciMethodData.cpp --- a/src/hotspot/share/ci/ciMethodData.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/ci/ciMethodData.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -266,6 +266,8 @@ // With concurrent class unloading, the MDO could have stale metadata; override it clear_row(row); } + } else { + set_receiver(row, NULL); } } } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/classfile/classLoader.cpp --- a/src/hotspot/share/classfile/classLoader.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/classfile/classLoader.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -73,14 +73,17 @@ #include "utilities/hashtable.inline.hpp" #include "utilities/macros.hpp" +// Entry point in java.dll for path canonicalization + +static canonicalize_fn_t CanonicalizeEntry = NULL; + // Entry points in zip.dll for loading zip/jar file entries typedef void * * (*ZipOpen_t)(const char *name, char **pmsg); -typedef void (*ZipClose_t)(jzfile *zip); +typedef void (*ZipClose_t)(jzfile *zip); typedef jzentry* (*FindEntry_t)(jzfile *zip, const char *name, jint *sizeP, jint *nameLen); typedef jboolean (*ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf); typedef jzentry* (*GetNextEntry_t)(jzfile *zip, jint n); -typedef jboolean (*ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg); typedef jint (*Crc32_t)(jint crc, const jbyte *buf, jint len); static ZipOpen_t ZipOpen = NULL; @@ -88,8 +91,6 @@ static FindEntry_t FindEntry = NULL; static ReadEntry_t ReadEntry = NULL; static GetNextEntry_t GetNextEntry = NULL; -static canonicalize_fn_t CanonicalizeEntry = NULL; -static ZipInflateFully_t ZipInflateFully = NULL; static Crc32_t Crc32 = NULL; // Entry points for jimage.dll for loading jimage file entries @@ -295,9 +296,7 @@ } ClassPathZipEntry::~ClassPathZipEntry() { - if (ZipClose != NULL) { - (*ZipClose)(_zip); - } + (*ZipClose)(_zip); FREE_C_HEAP_ARRAY(char, _zip_name); } @@ -964,11 +963,28 @@ tty->print_cr("]"); } +void* ClassLoader::dll_lookup(void* lib, const char* name, const char* path) { + void* func = os::dll_lookup(lib, name); + if (func == NULL) { + char msg[256] = ""; + jio_snprintf(msg, sizeof(msg), "Could not resolve \"%s\"", name); + vm_exit_during_initialization(msg, path); + } + return func; +} + +void ClassLoader::load_java_library() { + assert(CanonicalizeEntry == NULL, "should not load java library twice"); + void *javalib_handle = os::native_java_library(); + if (javalib_handle == NULL) { + vm_exit_during_initialization("Unable to load java library", NULL); + } + + CanonicalizeEntry = CAST_TO_FN_PTR(canonicalize_fn_t, dll_lookup(javalib_handle, "Canonicalize", NULL)); +} + void ClassLoader::load_zip_library() { assert(ZipOpen == NULL, "should not load zip library twice"); - // First make sure native library is loaded - os::native_java_library(); - // Load zip library char path[JVM_MAXPATHLEN]; char ebuf[1024]; void* handle = NULL; @@ -976,37 +992,19 @@ handle = os::dll_load(path, ebuf, sizeof ebuf); } if (handle == NULL) { - vm_exit_during_initialization("Unable to load ZIP library", path); - } - // Lookup zip entry points - ZipOpen = CAST_TO_FN_PTR(ZipOpen_t, os::dll_lookup(handle, "ZIP_Open")); - ZipClose = CAST_TO_FN_PTR(ZipClose_t, os::dll_lookup(handle, "ZIP_Close")); - FindEntry = CAST_TO_FN_PTR(FindEntry_t, os::dll_lookup(handle, "ZIP_FindEntry")); - ReadEntry = CAST_TO_FN_PTR(ReadEntry_t, os::dll_lookup(handle, "ZIP_ReadEntry")); - GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry")); - ZipInflateFully = CAST_TO_FN_PTR(ZipInflateFully_t, os::dll_lookup(handle, "ZIP_InflateFully")); - Crc32 = CAST_TO_FN_PTR(Crc32_t, os::dll_lookup(handle, "ZIP_CRC32")); - - // ZIP_Close is not exported on Windows in JDK5.0 so don't abort if ZIP_Close is NULL - if (ZipOpen == NULL || FindEntry == NULL || ReadEntry == NULL || - GetNextEntry == NULL || Crc32 == NULL) { - vm_exit_during_initialization("Corrupted ZIP library", path); + vm_exit_during_initialization("Unable to load zip library", path); } - if (ZipInflateFully == NULL) { - vm_exit_during_initialization("Corrupted ZIP library ZIP_InflateFully missing", path); - } - - // Lookup canonicalize entry in libjava.dll - void *javalib_handle = os::native_java_library(); - CanonicalizeEntry = CAST_TO_FN_PTR(canonicalize_fn_t, os::dll_lookup(javalib_handle, "Canonicalize")); - // This lookup only works on 1.3. Do not check for non-null here + ZipOpen = CAST_TO_FN_PTR(ZipOpen_t, dll_lookup(handle, "ZIP_Open", path)); + ZipClose = CAST_TO_FN_PTR(ZipClose_t, dll_lookup(handle, "ZIP_Close", path)); + FindEntry = CAST_TO_FN_PTR(FindEntry_t, dll_lookup(handle, "ZIP_FindEntry", path)); + ReadEntry = CAST_TO_FN_PTR(ReadEntry_t, dll_lookup(handle, "ZIP_ReadEntry", path)); + GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, dll_lookup(handle, "ZIP_GetNextEntry", path)); + Crc32 = CAST_TO_FN_PTR(Crc32_t, dll_lookup(handle, "ZIP_CRC32", path)); } void ClassLoader::load_jimage_library() { - // First make sure native library is loaded - os::native_java_library(); - // Load jimage library + assert(JImageOpen == NULL, "should not load jimage library twice"); char path[JVM_MAXPATHLEN]; char ebuf[1024]; void* handle = NULL; @@ -1017,27 +1015,15 @@ vm_exit_during_initialization("Unable to load jimage library", path); } - // Lookup jimage entry points - JImageOpen = CAST_TO_FN_PTR(JImageOpen_t, os::dll_lookup(handle, "JIMAGE_Open")); - guarantee(JImageOpen != NULL, "function JIMAGE_Open not found"); - JImageClose = CAST_TO_FN_PTR(JImageClose_t, os::dll_lookup(handle, "JIMAGE_Close")); - guarantee(JImageClose != NULL, "function JIMAGE_Close not found"); - JImagePackageToModule = CAST_TO_FN_PTR(JImagePackageToModule_t, os::dll_lookup(handle, "JIMAGE_PackageToModule")); - guarantee(JImagePackageToModule != NULL, "function JIMAGE_PackageToModule not found"); - JImageFindResource = CAST_TO_FN_PTR(JImageFindResource_t, os::dll_lookup(handle, "JIMAGE_FindResource")); - guarantee(JImageFindResource != NULL, "function JIMAGE_FindResource not found"); - JImageGetResource = CAST_TO_FN_PTR(JImageGetResource_t, os::dll_lookup(handle, "JIMAGE_GetResource")); - guarantee(JImageGetResource != NULL, "function JIMAGE_GetResource not found"); - JImageResourceIterator = CAST_TO_FN_PTR(JImageResourceIterator_t, os::dll_lookup(handle, "JIMAGE_ResourceIterator")); - guarantee(JImageResourceIterator != NULL, "function JIMAGE_ResourceIterator not found"); -} - -jboolean ClassLoader::decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg) { - return (*ZipInflateFully)(in, inSize, out, outSize, pmsg); + JImageOpen = CAST_TO_FN_PTR(JImageOpen_t, dll_lookup(handle, "JIMAGE_Open", path)); + JImageClose = CAST_TO_FN_PTR(JImageClose_t, dll_lookup(handle, "JIMAGE_Close", path)); + JImagePackageToModule = CAST_TO_FN_PTR(JImagePackageToModule_t, dll_lookup(handle, "JIMAGE_PackageToModule", path)); + JImageFindResource = CAST_TO_FN_PTR(JImageFindResource_t, dll_lookup(handle, "JIMAGE_FindResource", path)); + JImageGetResource = CAST_TO_FN_PTR(JImageGetResource_t, dll_lookup(handle, "JIMAGE_GetResource", path)); + JImageResourceIterator = CAST_TO_FN_PTR(JImageResourceIterator_t, dll_lookup(handle, "JIMAGE_ResourceIterator", path)); } int ClassLoader::crc32(int crc, const char* buf, int len) { - assert(Crc32 != NULL, "ZIP_CRC32 is not found"); return (*Crc32)(crc, (const jbyte*)buf, len); } @@ -1527,11 +1513,45 @@ "unsafeDefineClassCalls"); } + // lookup java library entry points + load_java_library(); // 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 @@ -1620,24 +1640,17 @@ } } - bool ClassLoader::get_canonical_path(const char* orig, char* out, int len) { assert(orig != NULL && out != NULL && len > 0, "bad arguments"); - if (CanonicalizeEntry != NULL) { - JavaThread* THREAD = JavaThread::current(); - JNIEnv* env = THREAD->jni_environment(); - ResourceMark rm(THREAD); + JavaThread* THREAD = JavaThread::current(); + JNIEnv* env = THREAD->jni_environment(); + ResourceMark rm(THREAD); - // os::native_path writes into orig_copy - char* orig_copy = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(orig)+1); - strcpy(orig_copy, orig); - if ((CanonicalizeEntry)(env, os::native_path(orig_copy), out, len) < 0) { - return false; - } - } else { - // On JDK 1.2.2 the Canonicalize does not exist, so just do nothing - strncpy(out, orig, len); - out[len - 1] = '\0'; + // os::native_path writes into orig_copy + char* orig_copy = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, strlen(orig)+1); + strcpy(orig_copy, orig); + if ((CanonicalizeEntry)(env, os::native_path(orig_copy), out, len) < 0) { + return false; } return true; } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/classfile/classLoader.hpp --- a/src/hotspot/share/classfile/classLoader.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/classfile/classLoader.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -249,6 +249,8 @@ static void setup_patch_mod_entries(); static void create_javabase(); + static void* dll_lookup(void* lib, const char* name, const char* path); + static void load_java_library(); static void load_zip_library(); static void load_jimage_library(); @@ -275,7 +277,6 @@ static PackageEntry* get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS); public: - static jboolean decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg); static int crc32(int crc, const char* buf, int len); static bool update_class_path_entry_list(const char *path, bool check_for_duplicates, @@ -411,6 +412,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 08102295011d -r 18659e040c64 src/hotspot/share/classfile/javaClasses.cpp --- a/src/hotspot/share/classfile/javaClasses.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/classfile/javaClasses.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -56,6 +56,7 @@ #include "runtime/fieldDescriptor.inline.hpp" #include "runtime/frame.inline.hpp" #include "runtime/handles.inline.hpp" +#include "runtime/init.hpp" #include "runtime/interfaceSupport.inline.hpp" #include "runtime/java.hpp" #include "runtime/javaCalls.hpp" @@ -387,14 +388,20 @@ Handle java_lang_String::create_from_platform_dependent_str(const char* str, TRAPS) { assert(str != NULL, "bad arguments"); - typedef jstring (*to_java_string_fn_t)(JNIEnv*, const char *); + typedef jstring (JNICALL *to_java_string_fn_t)(JNIEnv*, const char *); static to_java_string_fn_t _to_java_string_fn = NULL; if (_to_java_string_fn == NULL) { void *lib_handle = os::native_java_library(); - _to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "NewStringPlatform")); + _to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "JNU_NewStringPlatform")); +#if defined(_WIN32) && !defined(_WIN64) if (_to_java_string_fn == NULL) { - fatal("NewStringPlatform missing"); + // On 32 bit Windows, also try __stdcall decorated name + _to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "_JNU_NewStringPlatform@8")); + } +#endif + if (_to_java_string_fn == NULL) { + fatal("JNU_NewStringPlatform missing"); } } @@ -1628,6 +1635,7 @@ int java_lang_Thread::_inheritedAccessControlContext_offset = 0; int java_lang_Thread::_priority_offset = 0; int java_lang_Thread::_eetop_offset = 0; +int java_lang_Thread::_interrupted_offset = 0; int java_lang_Thread::_daemon_offset = 0; int java_lang_Thread::_stillborn_offset = 0; int java_lang_Thread::_stackSize_offset = 0; @@ -1643,6 +1651,7 @@ macro(_priority_offset, k, vmSymbols::priority_name(), int_signature, false); \ macro(_daemon_offset, k, vmSymbols::daemon_name(), bool_signature, false); \ macro(_eetop_offset, k, "eetop", long_signature, false); \ + macro(_interrupted_offset, k, "interrupted", bool_signature, false); \ macro(_stillborn_offset, k, "stillborn", bool_signature, false); \ macro(_stackSize_offset, k, "stackSize", long_signature, false); \ macro(_tid_offset, k, "tid", long_signature, false); \ @@ -1671,6 +1680,21 @@ java_thread->address_field_put(_eetop_offset, (address)thread); } +bool java_lang_Thread::interrupted(oop java_thread) { +#if INCLUDE_JFR + if (java_thread == NULL) { + // can happen from Jfr::on_vm_init leading to call of JavaThread::sleep + assert(!is_init_completed(), "should only happen during init"); + return false; + } +#endif + return java_thread->bool_field_volatile(_interrupted_offset); +} + +void java_lang_Thread::set_interrupted(oop java_thread, bool val) { + java_thread->bool_field_put_volatile(_interrupted_offset, val); +} + oop java_lang_Thread::name(oop java_thread) { return java_thread->obj_field(_name_offset); @@ -1956,6 +1980,8 @@ // This class provides a simple wrapper over the internal structure of // exception backtrace to insulate users of the backtrace from needing // to know what it looks like. +// The code of this class is not GC safe. Allocations can only happen +// in expand(). class BacktraceBuilder: public StackObj { friend class BacktraceIterator; private: @@ -2104,10 +2130,14 @@ void set_has_hidden_top_frame(TRAPS) { if (_has_hidden_top_frame == NULL) { - jvalue prim; - prim.z = 1; - PauseNoSafepointVerifier pnsv(&_nsv); - _has_hidden_top_frame = java_lang_boxing_object::create(T_BOOLEAN, &prim, CHECK); + // It would be nice to add java/lang/Boolean::TRUE here + // to indicate that this backtrace has a hidden top frame. + // But this code is used before TRUE is allocated. + // Therefor let's just use an arbitrary legal oop + // available right here. We only test for != null + // anyways. _methods is a short[]. + assert(_methods != NULL, "we need a legal oop"); + _has_hidden_top_frame = _methods; _head->obj_at_put(trace_hidden_offset, _has_hidden_top_frame); } } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/classfile/javaClasses.hpp --- a/src/hotspot/share/classfile/javaClasses.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/classfile/javaClasses.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -373,6 +373,7 @@ static int _inheritedAccessControlContext_offset; static int _priority_offset; static int _eetop_offset; + static int _interrupted_offset; static int _daemon_offset; static int _stillborn_offset; static int _stackSize_offset; @@ -391,6 +392,9 @@ static JavaThread* thread(oop java_thread); // Set JavaThread for instance static void set_thread(oop java_thread, JavaThread* thread); + // Interrupted status + static bool interrupted(oop java_thread); + static void set_interrupted(oop java_thread, bool val); // Name static oop name(oop java_thread); static void set_name(oop java_thread, oop name); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/classfile/vmSymbols.cpp --- a/src/hotspot/share/classfile/vmSymbols.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/classfile/vmSymbols.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -568,7 +568,6 @@ if (!InlineClassNatives) return true; break; case vmIntrinsics::_currentThread: - case vmIntrinsics::_isInterrupted: if (!InlineThreadNatives) return true; break; case vmIntrinsics::_floatToRawIntBits: @@ -787,9 +786,6 @@ #endif // COMPILER1 #ifdef COMPILER2 case vmIntrinsics::_clone: -#if INCLUDE_ZGC - if (UseZGC) return true; -#endif case vmIntrinsics::_copyOf: case vmIntrinsics::_copyOfRange: // These intrinsics use both the objectcopy and the arraycopy diff -r 08102295011d -r 18659e040c64 src/hotspot/share/classfile/vmSymbols.hpp --- a/src/hotspot/share/classfile/vmSymbols.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/classfile/vmSymbols.hpp Wed Nov 06 17:13:26 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") \ @@ -860,9 +862,6 @@ do_intrinsic(_arraycopy, java_lang_System, arraycopy_name, arraycopy_signature, F_S) \ do_name( arraycopy_name, "arraycopy") \ do_signature(arraycopy_signature, "(Ljava/lang/Object;ILjava/lang/Object;II)V") \ - do_intrinsic(_isInterrupted, java_lang_Thread, isInterrupted_name, isInterrupted_signature, F_R) \ - do_name( isInterrupted_name, "isInterrupted") \ - do_signature(isInterrupted_signature, "(Z)Z") \ do_intrinsic(_currentThread, java_lang_Thread, currentThread_name, currentThread_signature, F_S) \ do_name( currentThread_name, "currentThread") \ do_signature(currentThread_signature, "()Ljava/lang/Thread;") \ diff -r 08102295011d -r 18659e040c64 src/hotspot/share/compiler/compilerDefinitions.cpp --- a/src/hotspot/share/compiler/compilerDefinitions.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/compiler/compilerDefinitions.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -37,6 +37,32 @@ "jvmci" }; +#ifdef TIERED +bool CompilationModeFlag::_quick_only = false; +bool CompilationModeFlag::_high_only = false; +bool CompilationModeFlag::_high_only_quick_internal = false; + + +bool CompilationModeFlag::initialize() { + if (CompilationMode != NULL) { + if (strcmp(CompilationMode, "default") == 0) { + // Do nothing, just support the "default" keyword. + } else if (strcmp(CompilationMode, "quick-only") == 0) { + _quick_only = true; + } else if (strcmp(CompilationMode, "high-only") == 0) { + _high_only = true; + } else if (strcmp(CompilationMode, "high-only-quick-internal") == 0) { + _high_only_quick_internal = true; + } else { + jio_fprintf(defaultStream::error_stream(), "Unsupported compilation mode '%s', supported modes are: quick-only, high-only, high-only-quick-internal\n", CompilationMode); + return false; + } + } + return true; +} + +#endif + #if defined(COMPILER2) CompLevel CompLevel_highest_tier = CompLevel_full_optimization; // pure C2 and tiered or JVMCI and tiered #elif defined(COMPILER1) @@ -185,7 +211,6 @@ } } -#endif // TIERED void CompilerConfig::set_tiered_flags() { // Increase the code cache size - tiered compiles a lot more. @@ -208,6 +233,12 @@ vm_exit_during_initialization("Negative value specified for CompileThresholdScaling", NULL); } + if (CompilationModeFlag::disable_intermediate()) { + if (FLAG_IS_DEFAULT(Tier0ProfilingStartPercentage)) { + FLAG_SET_DEFAULT(Tier0ProfilingStartPercentage, 33); + } + } + // Scale tiered compilation thresholds. // CompileThresholdScaling == 0.0 is equivalent to -Xint and leaves compilation thresholds unchanged. if (!FLAG_IS_DEFAULT(CompileThresholdScaling) && CompileThresholdScaling > 0.0) { @@ -234,9 +265,34 @@ FLAG_SET_ERGO(Tier4MinInvocationThreshold, scaled_compile_threshold(Tier4MinInvocationThreshold)); FLAG_SET_ERGO(Tier4CompileThreshold, scaled_compile_threshold(Tier4CompileThreshold)); FLAG_SET_ERGO(Tier4BackEdgeThreshold, scaled_compile_threshold(Tier4BackEdgeThreshold)); + + if (CompilationModeFlag::disable_intermediate()) { + FLAG_SET_ERGO(Tier40InvocationThreshold, scaled_compile_threshold(Tier40InvocationThreshold)); + FLAG_SET_ERGO(Tier40MinInvocationThreshold, scaled_compile_threshold(Tier40MinInvocationThreshold)); + FLAG_SET_ERGO(Tier40CompileThreshold, scaled_compile_threshold(Tier40CompileThreshold)); + FLAG_SET_ERGO(Tier40BackEdgeThreshold, scaled_compile_threshold(Tier40BackEdgeThreshold)); + } + +#if INCLUDE_AOT + if (UseAOT) { + FLAG_SET_ERGO(Tier3AOTInvocationThreshold, scaled_compile_threshold(Tier3AOTInvocationThreshold)); + FLAG_SET_ERGO(Tier3AOTMinInvocationThreshold, scaled_compile_threshold(Tier3AOTMinInvocationThreshold)); + FLAG_SET_ERGO(Tier3AOTCompileThreshold, scaled_compile_threshold(Tier3AOTCompileThreshold)); + FLAG_SET_ERGO(Tier3AOTBackEdgeThreshold, scaled_compile_threshold(Tier3AOTBackEdgeThreshold)); + + if (CompilationModeFlag::disable_intermediate()) { + FLAG_SET_ERGO(Tier0AOTInvocationThreshold, scaled_compile_threshold(Tier0AOTInvocationThreshold)); + FLAG_SET_ERGO(Tier0AOTMinInvocationThreshold, scaled_compile_threshold(Tier0AOTMinInvocationThreshold)); + FLAG_SET_ERGO(Tier0AOTCompileThreshold, scaled_compile_threshold(Tier0AOTCompileThreshold)); + FLAG_SET_ERGO(Tier0AOTBackEdgeThreshold, scaled_compile_threshold(Tier0AOTBackEdgeThreshold)); + } + } +#endif // INCLUDE_AOT } } +#endif // TIERED + #if INCLUDE_JVMCI void set_jvmci_specific_flags() { if (UseJVMCICompiler) { @@ -245,11 +301,6 @@ if (FLAG_IS_DEFAULT(TypeProfileWidth)) { FLAG_SET_DEFAULT(TypeProfileWidth, 8); } - if (TieredStopAtLevel != CompLevel_full_optimization) { - // Currently JVMCI compiler can only work at the full optimization level - warning("forcing TieredStopAtLevel to full optimization because JVMCI is enabled"); - FLAG_SET_ERGO(TieredStopAtLevel, CompLevel_full_optimization); - } if (FLAG_IS_DEFAULT(TypeProfileLevel)) { FLAG_SET_DEFAULT(TypeProfileLevel, 0); } @@ -270,11 +321,26 @@ } } } else { +#ifdef TIERED + if (!TieredCompilation) { + warning("Disabling tiered compilation with non-native JVMCI compiler is not recommended. " + "Turning on tiered compilation and disabling intermediate compilation levels instead. "); + FLAG_SET_ERGO(TieredCompilation, true); + if (CompilationModeFlag::normal()) { + CompilationModeFlag::set_high_only_quick_internal(true); + } + if (CICompilerCount < 2 && CompilationModeFlag::quick_internal()) { + warning("Increasing number of compiler threads for JVMCI compiler."); + FLAG_SET_ERGO(CICompilerCount, 2); + } + } +#else // TIERED // Adjust the on stack replacement percentage to avoid early // OSR compilations while JVMCI itself is warming up if (FLAG_IS_DEFAULT(OnStackReplacePercentage)) { FLAG_SET_DEFAULT(OnStackReplacePercentage, 933); } +#endif // !TIERED // JVMCI needs values not less than defaults if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) { FLAG_SET_DEFAULT(ReservedCodeCacheSize, MAX2(64*M, ReservedCodeCacheSize)); @@ -409,9 +475,12 @@ set_jvmci_specific_flags(); #endif +#ifdef TIERED if (TieredCompilation) { set_tiered_flags(); - } else { + } else +#endif + { // Scale CompileThreshold // CompileThresholdScaling == 0.0 is equivalent to -Xint and leaves CompileThreshold unchanged. if (!FLAG_IS_DEFAULT(CompileThresholdScaling) && CompileThresholdScaling > 0.0) { diff -r 08102295011d -r 18659e040c64 src/hotspot/share/compiler/compilerDefinitions.hpp --- a/src/hotspot/share/compiler/compilerDefinitions.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/compiler/compilerDefinitions.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -62,6 +62,26 @@ CompLevel_full_optimization = 4 // C2 or JVMCI }; +#ifdef TIERED +class CompilationModeFlag : AllStatic { + static bool _quick_only; + static bool _high_only; + static bool _high_only_quick_internal; + +public: + static bool initialize(); + static bool normal() { return !quick_only() && !high_only() && !high_only_quick_internal(); } + static bool quick_only() { return _quick_only; } + static bool high_only() { return _high_only; } + static bool high_only_quick_internal() { return _high_only_quick_internal; } + + static bool disable_intermediate() { return high_only() || high_only_quick_internal(); } + static bool quick_internal() { return !high_only(); } + + static void set_high_only_quick_internal(bool x) { _high_only_quick_internal = x; } +}; +#endif + extern CompLevel CompLevel_highest_tier; extern CompLevel CompLevel_initial_compile; @@ -129,7 +149,7 @@ static void ergo_initialize(); private: - static void set_tiered_flags(); + TIERED_ONLY(static void set_tiered_flags();) }; #endif // SHARE_COMPILER_COMPILERDEFINITIONS_HPP diff -r 08102295011d -r 18659e040c64 src/hotspot/share/compiler/tieredThresholdPolicy.cpp --- a/src/hotspot/share/compiler/tieredThresholdPolicy.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/compiler/tieredThresholdPolicy.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -28,6 +28,7 @@ #include "compiler/tieredThresholdPolicy.hpp" #include "memory/resourceArea.hpp" #include "runtime/arguments.hpp" +#include "runtime/frame.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/safepoint.hpp" #include "runtime/safepointVerifiers.hpp" @@ -42,43 +43,61 @@ #include "c1/c1_Compiler.hpp" #include "opto/c2compiler.hpp" -template -bool TieredThresholdPolicy::call_predicate_helper(int i, int b, double scale, Method* method) { +bool TieredThresholdPolicy::call_predicate_helper(Method* method, CompLevel cur_level, int i, int b, double scale) { double threshold_scaling; if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) { scale *= threshold_scaling; } - switch(level) { + switch(cur_level) { case CompLevel_aot: - return (i >= Tier3AOTInvocationThreshold * scale) || - (i >= Tier3AOTMinInvocationThreshold * scale && i + b >= Tier3AOTCompileThreshold * scale); + if (CompilationModeFlag::disable_intermediate()) { + return (i >= Tier0AOTInvocationThreshold * scale) || + (i >= Tier0AOTMinInvocationThreshold * scale && i + b >= Tier0AOTCompileThreshold * scale); + } else { + return (i >= Tier3AOTInvocationThreshold * scale) || + (i >= Tier3AOTMinInvocationThreshold * scale && i + b >= Tier3AOTCompileThreshold * scale); + } case CompLevel_none: + if (CompilationModeFlag::disable_intermediate()) { + return (i >= Tier40InvocationThreshold * scale) || + (i >= Tier40MinInvocationThreshold * scale && i + b >= Tier40CompileThreshold * scale); + } + // Fall through case CompLevel_limited_profile: return (i >= Tier3InvocationThreshold * scale) || (i >= Tier3MinInvocationThreshold * scale && i + b >= Tier3CompileThreshold * scale); case CompLevel_full_profile: return (i >= Tier4InvocationThreshold * scale) || (i >= Tier4MinInvocationThreshold * scale && i + b >= Tier4CompileThreshold * scale); + default: + return true; } - return true; } -template -bool TieredThresholdPolicy::loop_predicate_helper(int i, int b, double scale, Method* method) { +bool TieredThresholdPolicy::loop_predicate_helper(Method* method, CompLevel cur_level, int i, int b, double scale) { double threshold_scaling; if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) { scale *= threshold_scaling; } - switch(level) { + switch(cur_level) { case CompLevel_aot: - return b >= Tier3AOTBackEdgeThreshold * scale; + if (CompilationModeFlag::disable_intermediate()) { + return b >= Tier0AOTBackEdgeThreshold * scale; + } else { + return b >= Tier3AOTBackEdgeThreshold * scale; + } case CompLevel_none: + if (CompilationModeFlag::disable_intermediate()) { + return b >= Tier40BackEdgeThreshold * scale; + } + // Fall through case CompLevel_limited_profile: return b >= Tier3BackEdgeThreshold * scale; case CompLevel_full_profile: return b >= Tier4BackEdgeThreshold * scale; + default: + return true; } - return true; } // Simple methods are as good being compiled with C1 as C2. @@ -91,18 +110,17 @@ return false; } -bool TieredThresholdPolicy::should_compile_at_level_simple(Method* method) { - if (TieredThresholdPolicy::is_trivial(method)) { - return true; - } +bool TieredThresholdPolicy::force_comp_at_level_simple(Method* method) { + if (CompilationModeFlag::quick_internal()) { #if INCLUDE_JVMCI - if (UseJVMCICompiler) { - AbstractCompiler* comp = CompileBroker::compiler(CompLevel_full_optimization); - if (comp != NULL && comp->is_jvmci() && ((JVMCICompiler*) comp)->force_comp_at_level_simple(method)) { - return true; + if (UseJVMCICompiler) { + AbstractCompiler* comp = CompileBroker::compiler(CompLevel_full_optimization); + if (comp != NULL && comp->is_jvmci() && ((JVMCICompiler*) comp)->force_comp_at_level_simple(method)) { + return true; + } } +#endif } -#endif return false; } @@ -181,7 +199,12 @@ tty->print("@%d queues=%d,%d", bci, CompileBroker::queue_size(CompLevel_full_profile), CompileBroker::queue_size(CompLevel_full_optimization)); - print_specific(type, mh, imh, bci, level); + tty->print(" rate="); + if (mh->prev_time() == 0) tty->print("n/a"); + else tty->print("%f", mh->rate()); + + tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback), + threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback)); if (type != COMPILE) { print_counters("", mh); @@ -216,9 +239,11 @@ tty->print_cr("]"); } + void TieredThresholdPolicy::initialize() { int count = CICompilerCount; - bool c1_only = TieredStopAtLevel < CompLevel_full_optimization; + bool c1_only = TieredStopAtLevel < CompLevel_full_optimization || CompilationModeFlag::quick_only(); + bool c2_only = CompilationModeFlag::high_only(); #ifdef _LP64 // Turn on ergonomic compiler count selection if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) { @@ -257,6 +282,8 @@ if (c1_only) { // No C2 compiler thread required set_c1_count(count); + } else if (c2_only) { + set_c2_count(count); } else { set_c1_count(MAX2(count / 3, 1)); set_c2_count(MAX2(count - c1_count(), 1)); @@ -413,7 +440,7 @@ method_back_branch_event(method, inlinee, bci, comp_level, nm, thread); // Check if event led to a higher level OSR compilation CompLevel expected_comp_level = comp_level; - if (inlinee->is_not_osr_compilable(expected_comp_level)) { + if (!CompilationModeFlag::disable_intermediate() && inlinee->is_not_osr_compilable(expected_comp_level)) { // It's not possble to reach the expected level so fall back to simple. expected_comp_level = CompLevel_simple; } @@ -430,7 +457,25 @@ // Check if the method can be compiled, change level if necessary void TieredThresholdPolicy::compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) { assert(level <= TieredStopAtLevel, "Invalid compilation level"); + if (CompilationModeFlag::quick_only()) { + assert(level <= CompLevel_simple, "Invalid compilation level"); + } else if (CompilationModeFlag::disable_intermediate()) { + assert(level != CompLevel_full_profile && level != CompLevel_limited_profile, "C1 profiling levels shouldn't be used with intermediate levels disabled"); + } + if (level == CompLevel_none) { + if (mh->has_compiled_code()) { + // Happens when we switch from AOT to interpreter to profile. + MutexLocker ml(Compile_lock); + NoSafepointVerifier nsv; + if (mh->has_compiled_code()) { + mh->code()->make_not_used(); + } + // Deoptimize immediately (we don't have to wait for a compile). + RegisterMap map(thread, false); + frame fr = thread->last_frame().sender(&map); + Deoptimization::deoptimize_frame(thread, fr.id()); + } return; } if (level == CompLevel_aot) { @@ -452,26 +497,28 @@ return; } - // Check if the method can be compiled. If it cannot be compiled with C1, continue profiling - // in the interpreter and then compile with C2 (the transition function will request that, - // see common() ). If the method cannot be compiled with C2 but still can with C1, compile it with - // pure C1. - if ((bci == InvocationEntryBci && !can_be_compiled(mh, level))) { - if (level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) { - compile(mh, bci, CompLevel_simple, thread); + if (!CompilationModeFlag::disable_intermediate()) { + // Check if the method can be compiled. If it cannot be compiled with C1, continue profiling + // in the interpreter and then compile with C2 (the transition function will request that, + // see common() ). If the method cannot be compiled with C2 but still can with C1, compile it with + // pure C1. + if ((bci == InvocationEntryBci && !can_be_compiled(mh, level))) { + if (level == CompLevel_full_optimization && can_be_compiled(mh, CompLevel_simple)) { + compile(mh, bci, CompLevel_simple, thread); + } + return; } - return; - } - if ((bci != InvocationEntryBci && !can_be_osr_compiled(mh, level))) { - if (level == CompLevel_full_optimization && can_be_osr_compiled(mh, CompLevel_simple)) { - nmethod* osr_nm = mh->lookup_osr_nmethod_for(bci, CompLevel_simple, false); - if (osr_nm != NULL && osr_nm->comp_level() > CompLevel_simple) { - // Invalidate the existing OSR nmethod so that a compile at CompLevel_simple is permitted. - osr_nm->make_not_entrant(); + if ((bci != InvocationEntryBci && !can_be_osr_compiled(mh, level))) { + if (level == CompLevel_full_optimization && can_be_osr_compiled(mh, CompLevel_simple)) { + nmethod* osr_nm = mh->lookup_osr_nmethod_for(bci, CompLevel_simple, false); + if (osr_nm != NULL && osr_nm->comp_level() > CompLevel_simple) { + // Invalidate the existing OSR nmethod so that a compile at CompLevel_simple is permitted. + osr_nm->make_not_entrant(); + } + compile(mh, bci, CompLevel_simple, thread); } - compile(mh, bci, CompLevel_simple, thread); + return; } - return; } if (bci != InvocationEntryBci && mh->is_not_osr_compilable(level)) { return; @@ -480,29 +527,12 @@ if (PrintTieredEvents) { print_event(COMPILE, mh, mh, bci, level); } - submit_compile(mh, bci, level, thread); + int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count(); + update_rate(os::javaTimeMillis(), mh()); + CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread); } } -// Update the rate and submit compile -void TieredThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) { - int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count(); - update_rate(os::javaTimeMillis(), mh()); - CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread); -} - -// Print an event. -void TieredThresholdPolicy::print_specific(EventType type, const methodHandle& mh, const methodHandle& imh, - int bci, CompLevel level) { - tty->print(" rate="); - if (mh->prev_time() == 0) tty->print("n/a"); - else tty->print("%f", mh->rate()); - - tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback), - threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback)); - -} - // update_rate() is called from select_task() while holding a compile queue lock. void TieredThresholdPolicy::update_rate(jlong t, Method* m) { // Skip update if counters are absent. @@ -585,27 +615,30 @@ if (mdo != NULL) { int i = mdo->invocation_count_delta(); int b = mdo->backedge_count_delta(); - return call_predicate_helper(i, b, 1, method); + return call_predicate_helper(method, CompilationModeFlag::disable_intermediate() ? CompLevel_none : CompLevel_full_profile, i, b, 1); } return false; } double TieredThresholdPolicy::threshold_scale(CompLevel level, int feedback_k) { - double queue_size = CompileBroker::queue_size(level); int comp_count = compiler_count(level); - double k = queue_size / (feedback_k * comp_count) + 1; + if (comp_count > 0) { + double queue_size = CompileBroker::queue_size(level); + double k = queue_size / (feedback_k * comp_count) + 1; - // Increase C1 compile threshold when the code cache is filled more - // than specified by IncreaseFirstTierCompileThresholdAt percentage. - // The main intention is to keep enough free space for C2 compiled code - // to achieve peak performance if the code cache is under stress. - if ((TieredStopAtLevel == CompLevel_full_optimization) && (level != CompLevel_full_optimization)) { - double current_reverse_free_ratio = CodeCache::reverse_free_ratio(CodeCache::get_code_blob_type(level)); - if (current_reverse_free_ratio > _increase_threshold_at_ratio) { - k *= exp(current_reverse_free_ratio - _increase_threshold_at_ratio); + // Increase C1 compile threshold when the code cache is filled more + // than specified by IncreaseFirstTierCompileThresholdAt percentage. + // The main intention is to keep enough free space for C2 compiled code + // to achieve peak performance if the code cache is under stress. + if (!CompilationModeFlag::disable_intermediate() && TieredStopAtLevel == CompLevel_full_optimization && level != CompLevel_full_optimization) { + double current_reverse_free_ratio = CodeCache::reverse_free_ratio(CodeCache::get_code_blob_type(level)); + if (current_reverse_free_ratio > _increase_threshold_at_ratio) { + k *= exp(current_reverse_free_ratio - _increase_threshold_at_ratio); + } } + return k; } - return k; + return 1; } // Call and loop predicates determine whether a transition to a higher @@ -615,55 +648,71 @@ // how many methods per compiler thread can be in the queue before // the threshold values double. bool TieredThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level, Method* method) { + double k = 1; switch(cur_level) { case CompLevel_aot: { - double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); - return loop_predicate_helper(i, b, k, method); + k = CompilationModeFlag::disable_intermediate() ? 1 : threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); + break; } - case CompLevel_none: + case CompLevel_none: { + if (CompilationModeFlag::disable_intermediate()) { + k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback); + break; + } + } + // Fall through case CompLevel_limited_profile: { - double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); - return loop_predicate_helper(i, b, k, method); + k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); + break; } case CompLevel_full_profile: { - double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback); - return loop_predicate_helper(i, b, k, method); + k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback); + break; } default: return true; } + return loop_predicate_helper(method, cur_level, i, b, k); } bool TieredThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level, Method* method) { + double k = 1; switch(cur_level) { case CompLevel_aot: { - double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); - return call_predicate_helper(i, b, k, method); + k = CompilationModeFlag::disable_intermediate() ? 1 : threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); + break; } - case CompLevel_none: + case CompLevel_none: { + if (CompilationModeFlag::disable_intermediate()) { + k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback); + break; + } + } + // Fall through case CompLevel_limited_profile: { - double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); - return call_predicate_helper(i, b, k, method); + k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); + break; } case CompLevel_full_profile: { - double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback); - return call_predicate_helper(i, b, k, method); + k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback); + break; } default: return true; } + return call_predicate_helper(method, cur_level, i, b, k); } // Determine is a method is mature. bool TieredThresholdPolicy::is_mature(Method* method) { - if (should_compile_at_level_simple(method)) return true; + if (is_trivial(method) || force_comp_at_level_simple(method)) return true; MethodData* mdo = method->method_data(); if (mdo != NULL) { int i = mdo->invocation_count(); int b = mdo->backedge_count(); double k = ProfileMaturityPercentage / 100.0; - return call_predicate_helper(i, b, k, method) || - loop_predicate_helper(i, b, k, method); + CompLevel main_profile_level = CompilationModeFlag::disable_intermediate() ? CompLevel_none : CompLevel_full_profile; + return call_predicate_helper(method, main_profile_level, i, b, k) || loop_predicate_helper(method, main_profile_level, i, b, k); } return false; } @@ -672,13 +721,16 @@ // start profiling without waiting for the compiled method to arrive. // We also take the load on compilers into the account. bool TieredThresholdPolicy::should_create_mdo(Method* method, CompLevel cur_level) { - if (cur_level == CompLevel_none && - CompileBroker::queue_size(CompLevel_full_optimization) <= - Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { - int i = method->invocation_count(); - int b = method->backedge_count(); - double k = Tier0ProfilingStartPercentage / 100.0; - return call_predicate_helper(i, b, k, method) || loop_predicate_helper(i, b, k, method); + if (cur_level != CompLevel_none || force_comp_at_level_simple(method)) { + return false; + } + int i = method->invocation_count(); + int b = method->backedge_count(); + double k = Tier0ProfilingStartPercentage / 100.0; + + // If the top level compiler is not keeping up, delay profiling. + if (CompileBroker::queue_size(CompLevel_full_optimization) <= (CompilationModeFlag::disable_intermediate() ? Tier0Delay : Tier3DelayOn) * compiler_count(CompLevel_full_optimization)) { + return call_predicate_helper(method, CompLevel_none, i, b, k) || loop_predicate_helper(method, CompLevel_none, i, b, k); } return false; } @@ -714,7 +766,7 @@ * 1 - pure C1 (CompLevel_simple) * 2 - C1 with invocation and backedge counting (CompLevel_limited_profile) * 3 - C1 with full profiling (CompLevel_full_profile) - * 4 - C2 (CompLevel_full_optimization) + * 4 - C2 or Graal (CompLevel_full_optimization) * * Common state transition patterns: * a. 0 -> 3 -> 4. @@ -752,106 +804,129 @@ int i = method->invocation_count(); int b = method->backedge_count(); - if (should_compile_at_level_simple(method)) { + if (force_comp_at_level_simple(method)) { next_level = CompLevel_simple; } else { - switch(cur_level) { + if (!CompilationModeFlag::disable_intermediate() && is_trivial(method)) { + next_level = CompLevel_simple; + } else { + switch(cur_level) { default: break; - case CompLevel_aot: { - // If we were at full profile level, would we switch to full opt? - if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) { - next_level = CompLevel_full_optimization; - } else if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= - Tier3DelayOff * compiler_count(CompLevel_full_optimization) && - (this->*p)(i, b, cur_level, method))) { - next_level = CompLevel_full_profile; - } - } - break; - case CompLevel_none: - // If we were at full profile level, would we switch to full opt? - if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) { - next_level = CompLevel_full_optimization; - } else if ((this->*p)(i, b, cur_level, method)) { -#if INCLUDE_JVMCI - if (EnableJVMCI && UseJVMCICompiler) { - // Since JVMCI takes a while to warm up, its queue inevitably backs up during - // early VM execution. As of 2014-06-13, JVMCI's inliner assumes that the root - // compilation method and all potential inlinees have mature profiles (which - // includes type profiling). If it sees immature profiles, JVMCI's inliner - // can perform pathologically bad (e.g., causing OutOfMemoryErrors due to - // exploring/inlining too many graphs). Since a rewrite of the inliner is - // in progress, we simply disable the dialing back heuristic for now and will - // revisit this decision once the new inliner is completed. - next_level = CompLevel_full_profile; - } else -#endif - { - // C1-generated fully profiled code is about 30% slower than the limited profile - // code that has only invocation and backedge counters. The observation is that - // if C2 queue is large enough we can spend too much time in the fully profiled code - // while waiting for C2 to pick the method from the queue. To alleviate this problem - // we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long - // we choose to compile a limited profiled version and then recompile with full profiling - // when the load on C2 goes down. - if (!disable_feedback && CompileBroker::queue_size(CompLevel_full_optimization) > - Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { - next_level = CompLevel_limited_profile; - } else { + case CompLevel_aot: + if (CompilationModeFlag::disable_intermediate()) { + if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= + Tier0Delay * compiler_count(CompLevel_full_optimization) && + (this->*p)(i, b, cur_level, method))) { + next_level = CompLevel_none; + } + } else { + // If we were at full profile level, would we switch to full opt? + if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) { + next_level = CompLevel_full_optimization; + } else if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= + Tier3DelayOff * compiler_count(CompLevel_full_optimization) && + (this->*p)(i, b, cur_level, method))) { next_level = CompLevel_full_profile; } } - } - break; - case CompLevel_limited_profile: - if (is_method_profiled(method)) { - // Special case: we got here because this method was fully profiled in the interpreter. - next_level = CompLevel_full_optimization; - } else { - MethodData* mdo = method->method_data(); - if (mdo != NULL) { - if (mdo->would_profile()) { + break; + case CompLevel_none: + if (CompilationModeFlag::disable_intermediate()) { + MethodData* mdo = method->method_data(); + if (mdo != NULL) { + // If mdo exists that means we are in a normal profiling mode. + int mdo_i = mdo->invocation_count_delta(); + int mdo_b = mdo->backedge_count_delta(); + if ((this->*p)(mdo_i, mdo_b, cur_level, method)) { + next_level = CompLevel_full_optimization; + } + } + } else { + // If we were at full profile level, would we switch to full opt? + if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) { + next_level = CompLevel_full_optimization; + } else if ((this->*p)(i, b, cur_level, method)) { + #if INCLUDE_JVMCI + if (EnableJVMCI && UseJVMCICompiler) { + // Since JVMCI takes a while to warm up, its queue inevitably backs up during + // early VM execution. As of 2014-06-13, JVMCI's inliner assumes that the root + // compilation method and all potential inlinees have mature profiles (which + // includes type profiling). If it sees immature profiles, JVMCI's inliner + // can perform pathologically bad (e.g., causing OutOfMemoryErrors due to + // exploring/inlining too many graphs). Since a rewrite of the inliner is + // in progress, we simply disable the dialing back heuristic for now and will + // revisit this decision once the new inliner is completed. + next_level = CompLevel_full_profile; + } else + #endif + { + // C1-generated fully profiled code is about 30% slower than the limited profile + // code that has only invocation and backedge counters. The observation is that + // if C2 queue is large enough we can spend too much time in the fully profiled code + // while waiting for C2 to pick the method from the queue. To alleviate this problem + // we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long + // we choose to compile a limited profiled version and then recompile with full profiling + // when the load on C2 goes down. + if (!disable_feedback && CompileBroker::queue_size(CompLevel_full_optimization) > + Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { + next_level = CompLevel_limited_profile; + } else { + next_level = CompLevel_full_profile; + } + } + } + } + break; + case CompLevel_limited_profile: + if (is_method_profiled(method)) { + // Special case: we got here because this method was fully profiled in the interpreter. + next_level = CompLevel_full_optimization; + } else { + MethodData* mdo = method->method_data(); + if (mdo != NULL) { + if (mdo->would_profile()) { + if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= + Tier3DelayOff * compiler_count(CompLevel_full_optimization) && + (this->*p)(i, b, cur_level, method))) { + next_level = CompLevel_full_profile; + } + } else { + next_level = CompLevel_full_optimization; + } + } else { + // If there is no MDO we need to profile if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= Tier3DelayOff * compiler_count(CompLevel_full_optimization) && (this->*p)(i, b, cur_level, method))) { next_level = CompLevel_full_profile; } - } else { - next_level = CompLevel_full_optimization; - } - } else { - // If there is no MDO we need to profile - if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= - Tier3DelayOff * compiler_count(CompLevel_full_optimization) && - (this->*p)(i, b, cur_level, method))) { - next_level = CompLevel_full_profile; } } - } - break; - case CompLevel_full_profile: - { - MethodData* mdo = method->method_data(); - if (mdo != NULL) { - if (mdo->would_profile()) { - int mdo_i = mdo->invocation_count_delta(); - int mdo_b = mdo->backedge_count_delta(); - if ((this->*p)(mdo_i, mdo_b, cur_level, method)) { + break; + case CompLevel_full_profile: + { + MethodData* mdo = method->method_data(); + if (mdo != NULL) { + if (mdo->would_profile()) { + int mdo_i = mdo->invocation_count_delta(); + int mdo_b = mdo->backedge_count_delta(); + if ((this->*p)(mdo_i, mdo_b, cur_level, method)) { + next_level = CompLevel_full_optimization; + } + } else { next_level = CompLevel_full_optimization; } - } else { - next_level = CompLevel_full_optimization; } } + break; } - break; } } - return MIN2(next_level, (CompLevel)TieredStopAtLevel); + return MIN2(next_level, CompilationModeFlag::quick_only() ? CompLevel_simple : (CompLevel)TieredStopAtLevel); } // Determine if a method should be compiled with a normal entry point at a different level. -CompLevel TieredThresholdPolicy::call_event(Method* method, CompLevel cur_level, JavaThread * thread) { +CompLevel TieredThresholdPolicy::call_event(Method* method, CompLevel cur_level, JavaThread* thread) { CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(), common(&TieredThresholdPolicy::loop_predicate, method, cur_level, true)); CompLevel next_level = common(&TieredThresholdPolicy::call_predicate, method, cur_level); @@ -950,7 +1025,8 @@ if (level == CompLevel_aot) { // Recompile the enclosing method to prevent infinite OSRs. Stay at AOT level while it's compiling. if (max_osr_level != CompLevel_none && !CompileBroker::compilation_is_in_queue(mh)) { - compile(mh, InvocationEntryBci, MIN2((CompLevel)TieredStopAtLevel, CompLevel_full_profile), thread); + CompLevel enclosing_level = MIN2(CompilationModeFlag::quick_only() ? CompLevel_simple : (CompLevel)TieredStopAtLevel, CompLevel_full_profile); + compile(mh, InvocationEntryBci, enclosing_level, thread); } } else { // Current loop event level is not AOT diff -r 08102295011d -r 18659e040c64 src/hotspot/share/compiler/tieredThresholdPolicy.hpp --- a/src/hotspot/share/compiler/tieredThresholdPolicy.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/compiler/tieredThresholdPolicy.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -222,22 +222,18 @@ enum EventType { CALL, LOOP, COMPILE, REMOVE_FROM_QUEUE, UPDATE_IN_QUEUE, REPROFILE, MAKE_NOT_ENTRANT }; void print_event(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level); - // Print policy-specific information if necessary - void print_specific(EventType type, const methodHandle& mh, const methodHandle& imh, int bci, CompLevel level); // Check if the method can be compiled, change level if necessary void compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread); - // Submit a given method for compilation - void submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread); // Simple methods are as good being compiled with C1 as C2. // This function tells if it's such a function. inline static bool is_trivial(Method* method); // Force method to be compiled at CompLevel_simple? - inline static bool should_compile_at_level_simple(Method* method); + inline bool force_comp_at_level_simple(Method* method); // Predicate helpers are used by .*_predicate() methods as well as others. // They check the given counter values, multiplied by the scale against the thresholds. - template static inline bool call_predicate_helper(int i, int b, double scale, Method* method); - template static inline bool loop_predicate_helper(int i, int b, double scale, Method* method); + inline bool call_predicate_helper(Method* method, CompLevel cur_level, int i, int b, double scale); + inline bool loop_predicate_helper(Method* method, CompLevel cur_level, int i, int b, double scale); // Get a compilation level for a given method. static CompLevel comp_level(Method* method); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/g1/g1Trace.cpp --- a/src/hotspot/share/gc/g1/g1Trace.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/g1/g1Trace.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -59,10 +59,10 @@ }; static void register_jfr_type_constants() { - JfrSerializer::register_serializer(TYPE_G1HEAPREGIONTYPE, false, true, + JfrSerializer::register_serializer(TYPE_G1HEAPREGIONTYPE, true, new G1HeapRegionTypeConstant()); - JfrSerializer::register_serializer(TYPE_G1YCTYPE, false, true, + JfrSerializer::register_serializer(TYPE_G1YCTYPE, true, new G1YCTypeConstant()); } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/shared/c2/barrierSetC2.cpp --- a/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -96,7 +96,6 @@ store = kit->store_to_memory(kit->control(), access.addr().node(), val.node(), access.type(), access.addr().type(), mo, requires_atomic_access, unaligned, mismatched, unsafe); - access.set_raw_access(store); } else { assert(!requires_atomic_access, "not yet supported"); assert(access.is_opt_access(), "either parse or opt access"); @@ -120,6 +119,8 @@ mm->set_memory_at(alias, st); } } + access.set_raw_access(store); + return store; } @@ -153,7 +154,6 @@ load = kit->make_load(control, adr, val_type, access.type(), adr_type, mo, dep, requires_atomic_access, unaligned, mismatched, unsafe); } - access.set_raw_access(load); } else { assert(!requires_atomic_access, "not yet supported"); assert(access.is_opt_access(), "either parse or opt access"); @@ -165,6 +165,7 @@ load = LoadNode::make(gvn, control, mem, adr, adr_type, val_type, access.type(), mo, dep, unaligned, mismatched); load = gvn.transform(load); } + access.set_raw_access(load); return load; } @@ -806,7 +807,8 @@ Node* dest_offset = ac->in(ArrayCopyNode::DestPos); Node* length = ac->in(ArrayCopyNode::Length); - assert (src_offset == NULL && dest_offset == NULL, "for clone offsets should be null"); + assert (src_offset == NULL, "for clone offsets should be null"); + assert (dest_offset == NULL, "for clone offsets should be null"); const char* copyfunc_name = "arraycopy"; address copyfunc_addr = diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp --- a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -25,6 +25,7 @@ #include "c1/c1_IR.hpp" #include "gc/shared/satbMarkQueue.hpp" #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" +#include "gc/shenandoah/shenandoahConcurrentRoots.hpp" #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" #include "gc/shenandoah/shenandoahRuntime.hpp" @@ -203,46 +204,49 @@ } void ShenandoahBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) { + // 1: non-reference load, no additional barrier is needed if (!access.is_oop()) { BarrierSetC1::load_at_resolved(access, result); return; } LIRGenerator* gen = access.gen(); - DecoratorSet decorators = access.decorators(); - bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); - if ((decorators & IN_NATIVE) != 0 && !is_traversal_mode) { - assert(access.is_oop(), "IN_NATIVE access only for oop values"); - BarrierSetC1::load_at_resolved(access, result); - LIR_OprList* args = new LIR_OprList(); - LIR_Opr addr = access.resolved_addr(); - addr = ensure_in_register(gen, addr); - args->append(result); - args->append(addr); - BasicTypeList signature; - signature.append(T_OBJECT); - signature.append(T_ADDRESS); - LIR_Opr call_result = gen->call_runtime(&signature, args, - CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), - objectType, NULL); - __ move(call_result, result); - } else { - if (ShenandoahLoadRefBarrier) { + // 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set + if (ShenandoahLoadRefBarrier) { + // Native barrier is for concurrent root processing + bool in_native = (decorators & IN_NATIVE) != 0; + if (in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots()) { + BarrierSetC1::load_at_resolved(access, result); + LIR_OprList* args = new LIR_OprList(); + LIR_Opr addr = access.resolved_addr(); + addr = ensure_in_register(gen, addr); + args->append(result); + args->append(addr); + BasicTypeList signature; + signature.append(T_OBJECT); + signature.append(T_ADDRESS); + LIR_Opr call_result = gen->call_runtime(&signature, args, + CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), + objectType, NULL); + __ move(call_result, result); + } else { LIR_Opr tmp = gen->new_register(T_OBJECT); BarrierSetC1::load_at_resolved(access, tmp); - tmp = load_reference_barrier(access.gen(), tmp, access.resolved_addr()); + tmp = load_reference_barrier(gen, tmp, access.resolved_addr()); __ move(tmp, result); - } else { - BarrierSetC1::load_at_resolved(access, result); } + } else { + BarrierSetC1::load_at_resolved(access, result); } + // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set if (ShenandoahKeepAliveBarrier) { bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0; bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; + bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; if ((is_weak || is_phantom || is_anonymous) && keep_alive) { @@ -252,13 +256,13 @@ Lcont_anonymous = new LabelObj(); generate_referent_check(access, Lcont_anonymous); } - pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr /* addr_opr */, + pre_barrier(gen, access.access_emit_info(), decorators, LIR_OprFact::illegalOpr /* addr_opr */, result /* pre_val */); if (is_anonymous) { __ branch_destination(Lcont_anonymous->label()); } } - } + } } class C1ShenandoahPreBarrierCodeGenClosure : public StubAssemblerCodeGenClosure { diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -23,6 +23,7 @@ #include "precompiled.hpp" #include "gc/shared/barrierSet.hpp" +#include "gc/shenandoah/shenandoahConcurrentRoots.hpp" #include "gc/shenandoah/shenandoahForwarding.hpp" #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeuristics.hpp" @@ -534,66 +535,69 @@ } Node* ShenandoahBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const { - DecoratorSet decorators = access.decorators(); - - Node* adr = access.addr().node(); - Node* obj = access.base(); + // 1: non-reference load, no additional barrier is needed + if (!access.is_oop()) { + return BarrierSetC2::load_at_resolved(access, val_type);; + } - bool mismatched = (decorators & C2_MISMATCHED) != 0; - bool unknown = (decorators & ON_UNKNOWN_OOP_REF) != 0; - bool on_heap = (decorators & IN_HEAP) != 0; - bool on_weak_ref = (decorators & (ON_WEAK_OOP_REF | ON_PHANTOM_OOP_REF)) != 0; - bool is_unordered = (decorators & MO_UNORDERED) != 0; - bool need_cpu_mem_bar = !is_unordered || mismatched || !on_heap; - bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); - bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; + Node* load = BarrierSetC2::load_at_resolved(access, val_type); + DecoratorSet decorators = access.decorators(); bool in_native = (decorators & IN_NATIVE) != 0; - Node* top = Compile::current()->top(); - - Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top; - Node* load = BarrierSetC2::load_at_resolved(access, val_type); - - if (access.is_oop()) { - if (ShenandoahLoadRefBarrier) { - load = new ShenandoahLoadReferenceBarrierNode(NULL, load, in_native && !is_traversal_mode); - if (access.is_parse_access()) { - load = static_cast(access).kit()->gvn().transform(load); - } else { - load = static_cast(access).gvn().transform(load); - } + // 2: apply LRB if ShenandoahLoadRefBarrier is set + if (ShenandoahLoadRefBarrier) { + // Native barrier is for concurrent root processing + bool use_native_barrier = in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots(); + load = new ShenandoahLoadReferenceBarrierNode(NULL, load, use_native_barrier); + if (access.is_parse_access()) { + load = static_cast(access).kit()->gvn().transform(load); + } else { + load = static_cast(access).gvn().transform(load); } } - // If we are reading the value of the referent field of a Reference - // object (either by using Unsafe directly or through reflection) - // then, if SATB is enabled, we need to record the referent in an - // SATB log buffer using the pre-barrier mechanism. - // Also we need to add memory barrier to prevent commoning reads - // from this field across safepoint since GC can change its value. - bool need_read_barrier = ShenandoahKeepAliveBarrier && - (on_weak_ref || (unknown && offset != top && obj != top)); + // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set + if (ShenandoahKeepAliveBarrier) { + Node* top = Compile::current()->top(); + Node* adr = access.addr().node(); + Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top; + Node* obj = access.base(); - if (!access.is_oop() || !need_read_barrier) { - return load; - } + bool unknown = (decorators & ON_UNKNOWN_OOP_REF) != 0; + bool on_weak_ref = (decorators & (ON_WEAK_OOP_REF | ON_PHANTOM_OOP_REF)) != 0; + bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); + bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; - assert(access.is_parse_access(), "entry not supported at optimization time"); - C2ParseAccess& parse_access = static_cast(access); - GraphKit* kit = parse_access.kit(); + // If we are reading the value of the referent field of a Reference + // object (either by using Unsafe directly or through reflection) + // then, if SATB is enabled, we need to record the referent in an + // SATB log buffer using the pre-barrier mechanism. + // Also we need to add memory barrier to prevent commoning reads + // from this field across safepoint since GC can change its value. + if (!on_weak_ref || (unknown && (offset == top || obj == top)) || !keep_alive) { + return load; + } - if (on_weak_ref && keep_alive) { - // Use the pre-barrier to record the value in the referent field - satb_write_barrier_pre(kit, false /* do_load */, - NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */, - load /* pre_val */, T_OBJECT); - // Add memory barrier to prevent commoning reads from this field - // across safepoint since GC can change its value. - kit->insert_mem_bar(Op_MemBarCPUOrder); - } else if (unknown) { - // We do not require a mem bar inside pre_barrier if need_mem_bar - // is set: the barriers would be emitted by us. - insert_pre_barrier(kit, obj, offset, load, !need_cpu_mem_bar); + assert(access.is_parse_access(), "entry not supported at optimization time"); + C2ParseAccess& parse_access = static_cast(access); + GraphKit* kit = parse_access.kit(); + bool mismatched = (decorators & C2_MISMATCHED) != 0; + bool is_unordered = (decorators & MO_UNORDERED) != 0; + bool need_cpu_mem_bar = !is_unordered || mismatched || in_native; + + if (on_weak_ref) { + // Use the pre-barrier to record the value in the referent field + satb_write_barrier_pre(kit, false /* do_load */, + NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */, + load /* pre_val */, T_OBJECT); + // Add memory barrier to prevent commoning reads from this field + // across safepoint since GC can change its value. + kit->insert_mem_bar(Op_MemBarCPUOrder); + } else if (unknown) { + // We do not require a mem bar inside pre_barrier if need_mem_bar + // is set: the barriers would be emitted by us. + insert_pre_barrier(kit, obj, offset, load, !need_cpu_mem_bar); + } } return load; diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -29,11 +29,6 @@ #include "logging/log.hpp" #include "logging/logTag.hpp" -ShenandoahPassiveHeuristics::ShenandoahPassiveHeuristics() : ShenandoahHeuristics() { - // Passive runs with max speed for allocation, because GC is always STW - SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahPacing); -} - bool ShenandoahPassiveHeuristics::should_start_gc() const { // Never do concurrent GCs. return false; diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -28,8 +28,6 @@ class ShenandoahPassiveHeuristics : public ShenandoahHeuristics { public: - ShenandoahPassiveHeuristics(); - virtual bool should_start_gc() const; virtual bool should_process_references(); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -47,7 +47,6 @@ void ShenandoahJFRSupport::register_jfr_type_serializers() { JfrSerializer::register_serializer(TYPE_SHENANDOAHHEAPREGIONSTATE, - false, true, new ShenandoahHeapRegionStateConstant()); } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -238,6 +238,15 @@ return; } + // Threads that are attaching should not block at all: they are not + // fully initialized yet. Calling sleep() on them would be awkward. + // This is probably the path that allocates the thread oop itself. + // Forcefully claim without waiting. + if (JavaThread::current()->is_attaching_via_jni()) { + claim_for_alloc(words, true); + return; + } + size_t max = ShenandoahPacingMaxDelay; double start = os::elapsedTime(); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/shenandoah/shenandoahPassiveMode.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahPassiveMode.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/shenandoah/shenandoahPassiveMode.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -32,8 +32,8 @@ FLAG_SET_DEFAULT(ExplicitGCInvokesConcurrent, false); FLAG_SET_DEFAULT(ShenandoahImplicitGCInvokesConcurrent, false); - // Passive runs with max speed, reacts on allocation failure. - FLAG_SET_DEFAULT(ShenandoahPacing, false); + // Passive runs with max speed for allocation, because GC is always STW + SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahPacing); // No need for evacuation reserve with Full GC, only for Degenerated GC. if (!ShenandoahDegeneratedGC) { diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -28,7 +28,7 @@ #include "classfile/systemDictionary.hpp" #include "code/codeCache.hpp" #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp" -#include "gc/shenandoah/shenandoahHeap.hpp" +#include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "gc/shenandoah/shenandoahStringDedup.hpp" #include "gc/shenandoah/shenandoahTimingTracker.hpp" diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -695,8 +695,8 @@ guarantee(cl.committed() == heap_committed, "%s: heap committed size must be consistent: heap-committed = " SIZE_FORMAT "%s, regions-committed = " SIZE_FORMAT "%s", label, - byte_size_in_exact_unit(heap_committed), proper_unit_for_byte_size(heap_committed), - byte_size_in_exact_unit(cl.committed()), proper_unit_for_byte_size(cl.committed())); + byte_size_in_proper_unit(heap_committed), proper_unit_for_byte_size(heap_committed), + byte_size_in_proper_unit(cl.committed()), proper_unit_for_byte_size(cl.committed())); } // Internal heap region checks diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp --- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -27,14 +27,17 @@ #include "gc/z/zBarrierSet.hpp" #include "gc/z/zBarrierSetAssembler.hpp" #include "gc/z/zBarrierSetRuntime.hpp" +#include "opto/arraycopynode.hpp" #include "opto/block.hpp" #include "opto/compile.hpp" #include "opto/graphKit.hpp" #include "opto/machnode.hpp" +#include "opto/macro.hpp" #include "opto/memnode.hpp" #include "opto/node.hpp" #include "opto/regalloc.hpp" #include "opto/rootnode.hpp" +#include "opto/runtime.hpp" #include "utilities/growableArray.hpp" #include "utilities/macros.hpp" @@ -429,3 +432,50 @@ } } } + +const TypeFunc *oop_clone_Type() { + // create input type (domain) + const Type **fields = TypeTuple::fields(3); + fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // src Object + fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // dst Object + fields[TypeFunc::Parms+2] = TypeInt::INT; // Object size + const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields); + + // create result type (range) + fields = TypeTuple::fields(0); + + const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); + + return TypeFunc::make(domain, range); +} + +void ZBarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const { + Node *ctrl = ac->in(TypeFunc::Control); + Node *mem = ac->in(TypeFunc::Memory); + Node *src = ac->in(ArrayCopyNode::Src); + Node *src_offset = ac->in(ArrayCopyNode::SrcPos); + Node *dest = ac->in(ArrayCopyNode::Dest); + Node *dest_offset = ac->in(ArrayCopyNode::DestPos); + Node *length = ac->in(ArrayCopyNode::Length); + + assert (src_offset == NULL, "for clone offsets should be null"); + assert (dest_offset == NULL, "for clone offsets should be null"); + + if (src->bottom_type()->isa_instptr()) { + // Instances must have all oop fiels healed before cloning - call runtime leaf + const char *clonefunc_name = "clone_oop"; + address clonefunc_addr = ZBarrierSetRuntime::clone_oop_addr(); + const TypePtr *raw_adr_type = TypeRawPtr::BOTTOM; + const TypeFunc *call_type = oop_clone_Type(); + + Node *call = phase->make_leaf_call(ctrl, mem, call_type, clonefunc_addr, clonefunc_name, raw_adr_type, src, dest, + length); + phase->transform_later(call); + phase->igvn().replace_node(ac, call); + } else { + assert(src->bottom_type()->isa_aryptr() != NULL, "Only arrays"); + + // Clones of primitive arrays go here + BarrierSetC2::clone_at_expansion(phase, ac); + } +} diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp --- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -86,6 +86,7 @@ virtual void late_barrier_analysis() const; virtual int estimate_stub_size() const; virtual void emit_stubs(CodeBuffer& cb) const; + virtual void clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const; }; #endif // SHARE_GC_Z_C2_ZBARRIERSETC2_HPP diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/z/zBarrier.hpp --- a/src/hotspot/share/gc/z/zBarrier.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/z/zBarrier.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -119,6 +119,7 @@ static oop load_barrier_on_oop_field(volatile narrowOop* p); static oop load_barrier_on_oop_field_preloaded(volatile narrowOop* p, oop o); static void load_barrier_on_oop_array(volatile narrowOop* p, size_t length); + static void clone_oop(volatile oop src, oop dst, size_t length); static oop load_barrier_on_weak_oop_field_preloaded(volatile narrowOop* p, oop o); static oop load_barrier_on_phantom_oop_field_preloaded(volatile narrowOop* p, oop o); static oop weak_load_barrier_on_oop_field_preloaded(volatile narrowOop* p, oop o); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/z/zBarrier.inline.hpp --- a/src/hotspot/share/gc/z/zBarrier.inline.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/z/zBarrier.inline.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -175,6 +175,10 @@ } } +inline void ZBarrier::clone_oop(volatile oop src, oop dst, size_t length) { + HeapAccess<>::clone(src, dst, length); +} + // ON_WEAK barriers should only ever be applied to j.l.r.Reference.referents. inline void verify_on_weak(volatile oop* referent_addr) { #ifdef ASSERT diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/z/zBarrierSetRuntime.cpp --- a/src/hotspot/share/gc/z/zBarrierSetRuntime.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/z/zBarrierSetRuntime.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -42,6 +42,10 @@ ZBarrier::load_barrier_on_oop_array(p, length); JRT_END +JRT_LEAF(void, ZBarrierSetRuntime::clone_oop(oop src, oop dst, size_t length)) + ZBarrier::clone_oop(src, dst, length); +JRT_END + address ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(DecoratorSet decorators) { if (decorators & ON_PHANTOM_OOP_REF) { return load_barrier_on_phantom_oop_field_preloaded_addr(); @@ -67,3 +71,7 @@ address ZBarrierSetRuntime::load_barrier_on_oop_array_addr() { return reinterpret_cast
(load_barrier_on_oop_array); } + +address ZBarrierSetRuntime::clone_oop_addr() { + return reinterpret_cast
(clone_oop); +} diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/z/zBarrierSetRuntime.hpp --- a/src/hotspot/share/gc/z/zBarrierSetRuntime.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/z/zBarrierSetRuntime.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -36,6 +36,7 @@ static oopDesc* load_barrier_on_weak_oop_field_preloaded(oopDesc* o, oop* p); static oopDesc* load_barrier_on_phantom_oop_field_preloaded(oopDesc* o, oop* p); static void load_barrier_on_oop_array(oop* p, size_t length); + static void clone_oop(oop src, oop dst, size_t length); public: static address load_barrier_on_oop_field_preloaded_addr(DecoratorSet decorators); @@ -43,6 +44,7 @@ static address load_barrier_on_weak_oop_field_preloaded_addr(); static address load_barrier_on_phantom_oop_field_preloaded_addr(); static address load_barrier_on_oop_array_addr(); + static address clone_oop_addr(); }; #endif // SHARE_GC_Z_ZBARRIERSETRUNTIME_HPP diff -r 08102295011d -r 18659e040c64 src/hotspot/share/gc/z/zTracer.cpp --- a/src/hotspot/share/gc/z/zTracer.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/gc/z/zTracer.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -59,11 +59,9 @@ static void register_jfr_type_serializers() { JfrSerializer::register_serializer(TYPE_ZSTATISTICSCOUNTERTYPE, - false /* require_safepoint */, true /* permit_cache */, new ZStatisticsCounterTypeConstant()); JfrSerializer::register_serializer(TYPE_ZSTATISTICSSAMPLERTYPE, - false /* require_safepoint */, true /* permit_cache */, new ZStatisticsSamplerTypeConstant()); } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/include/jvm.h --- a/src/hotspot/share/include/jvm.h Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/include/jvm.h Wed Nov 06 17:13:26 2019 +0100 @@ -248,16 +248,10 @@ JNIEXPORT jobject JNICALL JVM_CurrentThread(JNIEnv *env, jclass threadClass); -JNIEXPORT jint JNICALL -JVM_CountStackFrames(JNIEnv *env, jobject thread); - JNIEXPORT void JNICALL JVM_Interrupt(JNIEnv *env, jobject thread); JNIEXPORT jboolean JNICALL -JVM_IsInterrupted(JNIEnv *env, jobject thread, jboolean clearInterrupted); - -JNIEXPORT jboolean JNICALL JVM_HoldsLock(JNIEnv *env, jclass threadClass, jobject obj); JNIEXPORT void JNICALL @@ -352,11 +346,6 @@ JNIEXPORT jclass JNICALL JVM_FindPrimitiveClass(JNIEnv *env, const char *utf); -/* - * Link the 'arg' class - */ -JNIEXPORT void JNICALL -JVM_LinkClass(JNIEnv *env, jclass classClass, jclass arg); /* * Find a class from a boot class loader. Returns NULL if class not found. @@ -1073,13 +1062,6 @@ method_size_info main; /* used everywhere else */ } class_size_info; -/* - * Functions defined in libjava.so to perform string conversions. - * - */ - -typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str); - #define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \ JVM_ACC_FINAL | \ JVM_ACC_SUPER | \ diff -r 08102295011d -r 18659e040c64 src/hotspot/share/interpreter/bytecode.cpp --- a/src/hotspot/share/interpreter/bytecode.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/interpreter/bytecode.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -147,7 +147,6 @@ BasicType Bytecode_member_ref::result_type() const { ResultTypeFinder rts(signature()); - rts.iterate(); return rts.type(); } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/dcmd/jfrDcmds.cpp --- a/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -349,6 +349,7 @@ _filename("filename", "Resulting recording filename, e.g. \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", false), _maxage("maxage", "Maximum time to keep recorded data (on disk) in (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 60m, or 0 for no limit", "NANOTIME", false, "0"), _maxsize("maxsize", "Maximum amount of bytes to keep (on disk) in (k)B, (M)B or (G)B, e.g. 500M, or 0 for no limit", "MEMORY SIZE", false, "0"), + _flush_interval("flush-interval", "Minimum time before flushing buffers, measured in (s)econds, e.g. 4 s, or 0 for flushing when a recording ends", "NANOTIME", false, "1s"), _dump_on_exit("dumponexit", "Dump running recording when JVM shuts down", "BOOLEAN", false), _path_to_gc_roots("path-to-gc-roots", "Collect path to GC roots", "BOOLEAN", false, "false") { _dcmdparser.add_dcmd_option(&_name); @@ -359,6 +360,7 @@ _dcmdparser.add_dcmd_option(&_filename); _dcmdparser.add_dcmd_option(&_maxage); _dcmdparser.add_dcmd_option(&_maxsize); + _dcmdparser.add_dcmd_option(&_flush_interval); _dcmdparser.add_dcmd_option(&_dump_on_exit); _dcmdparser.add_dcmd_option(&_path_to_gc_roots); }; @@ -411,6 +413,10 @@ maxsize = JfrJavaSupport::new_java_lang_Long(_maxsize.value()._size, CHECK); } + jobject flush_interval = NULL; + if (_flush_interval.is_set()) { + flush_interval = JfrJavaSupport::new_java_lang_Long(_flush_interval.value()._nanotime, CHECK); + } jobject duration = NULL; if (_duration.is_set()) { duration = JfrJavaSupport::new_java_lang_Long(_duration.value()._nanotime, CHECK); @@ -464,7 +470,7 @@ static const char method[] = "execute"; static const char signature[] = "(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/Long;" "Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/String;" - "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/lang/String;"; + "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/lang/String;"; JfrJavaArguments execute_args(&result, klass, method, signature, CHECK); execute_args.set_receiver(h_dcmd_instance); @@ -478,6 +484,7 @@ execute_args.push_jobject(filename); execute_args.push_jobject(maxage); execute_args.push_jobject(maxsize); + execute_args.push_jobject(flush_interval); execute_args.push_jobject(dump_on_exit); execute_args.push_jobject(path_to_gc_roots); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/dcmd/jfrDcmds.hpp --- a/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -90,6 +90,7 @@ DCmdArgument _filename; DCmdArgument _maxage; DCmdArgument _maxsize; + DCmdArgument _flush_interval; DCmdArgument _dump_on_exit; DCmdArgument _path_to_gc_roots; diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp --- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -1497,35 +1497,6 @@ ik = new_ik; } -// During retransform/redefine, copy the Method specific trace flags -// from the previous ik ("the original klass") to the new ik ("the scratch_klass"). -// The open code for retransform/redefine does not know about these. -// In doing this migration here, we ensure the new Methods (defined in scratch klass) -// will carry over trace tags from the old Methods being replaced, -// ensuring flag/tag continuity while being transparent to open code. -static void copy_method_trace_flags(const InstanceKlass* the_original_klass, const InstanceKlass* the_scratch_klass) { - assert(the_original_klass != NULL, "invariant"); - assert(the_scratch_klass != NULL, "invariant"); - assert(the_original_klass->name() == the_scratch_klass->name(), "invariant"); - const Array* old_methods = the_original_klass->methods(); - const Array* new_methods = the_scratch_klass->methods(); - const bool equal_array_length = old_methods->length() == new_methods->length(); - // The Method array has the property of being sorted. - // If they are the same length, there is a one-to-one mapping. - // If they are unequal, there was a method added (currently only - // private static methods allowed to be added), use lookup. - for (int i = 0; i < old_methods->length(); ++i) { - const Method* const old_method = old_methods->at(i); - Method* const new_method = equal_array_length ? new_methods->at(i) : - the_scratch_klass->find_method(old_method->name(), old_method->signature()); - assert(new_method != NULL, "invariant"); - assert(new_method->name() == old_method->name(), "invariant"); - assert(new_method->signature() == old_method->signature(), "invariant"); - new_method->set_trace_flags(old_method->trace_flags()); - assert(new_method->trace_flags() == old_method->trace_flags(), "invariant"); - } -} - static bool is_retransforming(const InstanceKlass* ik, TRAPS) { assert(ik != NULL, "invariant"); assert(JdkJfrEvent::is_a(ik), "invariant"); @@ -1533,16 +1504,7 @@ assert(name != NULL, "invariant"); Handle class_loader(THREAD, ik->class_loader()); Handle protection_domain(THREAD, ik->protection_domain()); - // nota bene: use lock-free dictionary lookup - const InstanceKlass* prev_ik = (const InstanceKlass*)SystemDictionary::find(name, class_loader, protection_domain, THREAD); - if (prev_ik == NULL) { - return false; - } - // an existing ik implies a retransform/redefine - assert(prev_ik != NULL, "invariant"); - assert(JdkJfrEvent::is_a(prev_ik), "invariant"); - copy_method_trace_flags(prev_ik, ik); - return true; + return SystemDictionary::find(name, class_loader, protection_domain, THREAD) != NULL; } // target for JFR_ON_KLASS_CREATION hook @@ -1571,12 +1533,8 @@ return; } assert(JdkJfrEvent::is_subklass(ik), "invariant"); - if (is_retransforming(ik, THREAD)) { - // not the initial klass load - return; - } - if (ik->is_abstract()) { - // abstract classes are not instrumented + if (ik->is_abstract() || is_retransforming(ik, THREAD)) { + // abstract and scratch classes are not instrumented return; } ResourceMark rm(THREAD); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/jfr.cpp --- a/src/hotspot/share/jfr/jfr.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/jfr.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -71,6 +71,18 @@ JfrThreadLocal::on_exit(t); } +void Jfr::exclude_thread(Thread* t) { + JfrThreadLocal::exclude(t); +} + +void Jfr::include_thread(Thread* t) { + JfrThreadLocal::include(t); +} + +bool Jfr::is_excluded(Thread* t) { + return t != NULL && t->jfr_thread_local()->is_excluded(); +} + void Jfr::on_java_thread_dismantle(JavaThread* jt) { if (JfrRecorder::is_recording()) { JfrCheckpointManager::write_thread_checkpoint(jt); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/jfr.hpp --- a/src/hotspot/share/jfr/jfr.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/jfr.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -53,6 +53,9 @@ static bool on_flight_recorder_option(const JavaVMOption** option, char* delimiter); static bool on_start_flight_recording_option(const JavaVMOption** option, char* delimiter); static void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f); + static void exclude_thread(Thread* thread); + static bool is_excluded(Thread* thread); + static void include_thread(Thread* thread); }; #endif // SHARE_JFR_JFR_HPP diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/jni/jfrJavaSupport.cpp --- a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -23,7 +23,6 @@ */ #include "precompiled.hpp" -#include "jni.h" #include "classfile/javaClasses.inline.hpp" #include "classfile/modules.hpp" #include "classfile/symbolTable.hpp" @@ -42,9 +41,11 @@ #include "runtime/fieldDescriptor.inline.hpp" #include "runtime/java.hpp" #include "runtime/jniHandles.inline.hpp" +#include "runtime/semaphore.inline.hpp" #include "runtime/synchronizer.hpp" #include "runtime/thread.inline.hpp" #include "runtime/threadSMR.hpp" +#include "utilities/growableArray.hpp" #ifdef ASSERT void JfrJavaSupport::check_java_thread_in_vm(Thread* t) { @@ -58,6 +59,12 @@ assert(t->is_Java_thread(), "invariant"); assert(((JavaThread*)t)->thread_state() == _thread_in_native, "invariant"); } + +static void check_new_unstarted_java_thread(Thread* t) { + assert(t != NULL, "invariant"); + assert(t->is_Java_thread(), "invariant"); + assert(((JavaThread*)t)->thread_state() == _thread_new, "invariant"); +} #endif /* @@ -93,6 +100,21 @@ JNIHandles::destroy_global(handle); } +jweak JfrJavaSupport::global_weak_jni_handle(const oop obj, Thread* t) { + DEBUG_ONLY(check_java_thread_in_vm(t)); + HandleMark hm(t); + return JNIHandles::make_weak_global(Handle(t, obj)); +} + +jweak JfrJavaSupport::global_weak_jni_handle(const jobject handle, Thread* t) { + const oop obj = JNIHandles::resolve(handle); + return obj == NULL ? NULL : global_weak_jni_handle(obj, t); +} + +void JfrJavaSupport::destroy_global_weak_jni_handle(jweak handle) { + JNIHandles::destroy_weak_global(handle); +} + oop JfrJavaSupport::resolve_non_null(jobject obj) { return JNIHandles::resolve_non_null(obj); } @@ -603,9 +625,149 @@ return true; } -jlong JfrJavaSupport::jfr_thread_id(jobject target_thread) { +class ThreadExclusionListAccess : public StackObj { + private: + static Semaphore _mutex_semaphore; + public: + ThreadExclusionListAccess() { _mutex_semaphore.wait(); } + ~ThreadExclusionListAccess() { _mutex_semaphore.signal(); } +}; + +Semaphore ThreadExclusionListAccess::_mutex_semaphore(1); +static GrowableArray* exclusion_list = NULL; + +static bool equals(const jweak excluded_thread, Handle target_thread) { + return JfrJavaSupport::resolve_non_null(excluded_thread) == target_thread(); +} + +static int find_exclusion_thread_idx(Handle thread) { + if (exclusion_list != NULL) { + for (int i = 0; i < exclusion_list->length(); ++i) { + if (equals(exclusion_list->at(i), thread)) { + return i; + } + } + } + return -1; +} + +static Handle as_handle(jobject thread) { + return Handle(Thread::current(), JfrJavaSupport::resolve_non_null(thread)); +} + +static bool thread_is_not_excluded(Handle thread) { + return -1 == find_exclusion_thread_idx(thread); +} + +static bool thread_is_not_excluded(jobject thread) { + return thread_is_not_excluded(as_handle(thread)); +} + +static bool is_thread_excluded(jobject thread) { + return !thread_is_not_excluded(thread); +} + +#ifdef ASSERT +static bool is_thread_excluded(Handle thread) { + return !thread_is_not_excluded(thread); +} +#endif // ASSERT + +static int add_thread_to_exclusion_list(jobject thread) { + ThreadExclusionListAccess lock; + if (exclusion_list == NULL) { + exclusion_list = new (ResourceObj::C_HEAP, mtTracing) GrowableArray(10, true, mtTracing); + } + assert(exclusion_list != NULL, "invariant"); + assert(thread_is_not_excluded(thread), "invariant"); + jweak ref = JfrJavaSupport::global_weak_jni_handle(thread, Thread::current()); + const int idx = exclusion_list->append(ref); + assert(is_thread_excluded(thread), "invariant"); + return idx; +} + +static void remove_thread_from_exclusion_list(Handle thread) { + assert(exclusion_list != NULL, "invariant"); + assert(is_thread_excluded(thread), "invariant"); + assert(exclusion_list != NULL, "invariant"); + const int idx = find_exclusion_thread_idx(thread); + assert(idx >= 0, "invariant"); + assert(idx < exclusion_list->length(), "invariant"); + JfrJavaSupport::destroy_global_weak_jni_handle(exclusion_list->at(idx)); + exclusion_list->delete_at(idx); + assert(thread_is_not_excluded(thread), "invariant"); + if (0 == exclusion_list->length()) { + delete exclusion_list; + exclusion_list = NULL; + } +} + +static void remove_thread_from_exclusion_list(jobject thread) { + ThreadExclusionListAccess lock; + remove_thread_from_exclusion_list(as_handle(thread)); +} + +// includes removal +static bool check_exclusion_state_on_thread_start(JavaThread* jt) { + Handle h_obj(jt, jt->threadObj()); + ThreadExclusionListAccess lock; + if (thread_is_not_excluded(h_obj)) { + return false; + } + remove_thread_from_exclusion_list(h_obj); + return true; +} + +jlong JfrJavaSupport::jfr_thread_id(jobject thread) { ThreadsListHandle tlh; JavaThread* native_thread = NULL; - (void)tlh.cv_internal_thread_to_JavaThread(target_thread, &native_thread, NULL); + (void)tlh.cv_internal_thread_to_JavaThread(thread, &native_thread, NULL); return native_thread != NULL ? JFR_THREAD_ID(native_thread) : 0; } + +void JfrJavaSupport::exclude(jobject thread) { + HandleMark hm; + ThreadsListHandle tlh; + JavaThread* native_thread = NULL; + (void)tlh.cv_internal_thread_to_JavaThread(thread, &native_thread, NULL); + if (native_thread != NULL) { + JfrThreadLocal::exclude(native_thread); + } else { + // not started yet, track the thread oop + add_thread_to_exclusion_list(thread); + } +} + +void JfrJavaSupport::include(jobject thread) { + HandleMark hm; + ThreadsListHandle tlh; + JavaThread* native_thread = NULL; + (void)tlh.cv_internal_thread_to_JavaThread(thread, &native_thread, NULL); + if (native_thread != NULL) { + JfrThreadLocal::include(native_thread); + } else { + // not started yet, untrack the thread oop + remove_thread_from_exclusion_list(thread); + } +} + +bool JfrJavaSupport::is_excluded(jobject thread) { + HandleMark hm; + ThreadsListHandle tlh; + JavaThread* native_thread = NULL; + (void)tlh.cv_internal_thread_to_JavaThread(thread, &native_thread, NULL); + return native_thread != NULL ? native_thread->jfr_thread_local()->is_excluded() : is_thread_excluded(thread); +} + +void JfrJavaSupport::on_thread_start(Thread* t) { + assert(t != NULL, "invariant"); + assert(Thread::current() == t, "invariant"); + if (!t->is_Java_thread()) { + return; + } + DEBUG_ONLY(check_new_unstarted_java_thread(t);) + HandleMark hm; + if (check_exclusion_state_on_thread_start((JavaThread*)t)) { + JfrThreadLocal::exclude(t); + } +} diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/jni/jfrJavaSupport.hpp --- a/src/hotspot/share/jfr/jni/jfrJavaSupport.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/jni/jfrJavaSupport.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -29,18 +29,21 @@ #include "utilities/exceptions.hpp" class Klass; -class JavaThread; class outputStream; class JfrJavaSupport : public AllStatic { public: static jobject local_jni_handle(const oop obj, Thread* t); static jobject local_jni_handle(const jobject handle, Thread* t); - static void destroy_local_jni_handle(const jobject handle); + static void destroy_local_jni_handle(jobject handle); static jobject global_jni_handle(const oop obj, Thread* t); static jobject global_jni_handle(const jobject handle, Thread* t); - static void destroy_global_jni_handle(const jobject handle); + static void destroy_global_jni_handle(jobject handle); + + static jweak global_weak_jni_handle(const oop obj, Thread* t); + static jweak global_weak_jni_handle(const jobject handle, Thread* t); + static void destroy_global_weak_jni_handle(jweak handle); static oop resolve_non_null(jobject obj); static void notify_all(jobject obj, TRAPS); @@ -85,7 +88,11 @@ static bool is_jdk_jfr_module_available(); static bool is_jdk_jfr_module_available(outputStream* stream, TRAPS); - static jlong jfr_thread_id(jobject target_thread); + static jlong jfr_thread_id(jobject thread); + static void exclude(jobject thread); + static void include(jobject thread); + static bool is_excluded(jobject thread); + static void on_thread_start(Thread* t); // critical static void abort(jstring errorMsg, TRAPS); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/jni/jfrJniMethod.cpp --- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -284,6 +284,10 @@ return JfrJavaEventWriter::flush(writer, used_size, requested_size, thread); JVM_END +JVM_ENTRY_NO_ENV(void, jfr_flush(JNIEnv* env, jobject jvm)) + JfrRepository::flush(thread); +JVM_END + JVM_ENTRY_NO_ENV(void, jfr_set_repository_location(JNIEnv* env, jobject repo, jstring location)) return JfrRepository::set_path(location, thread); JVM_END @@ -311,3 +315,20 @@ JVM_ENTRY_NO_ENV(void, jfr_emit_old_object_samples(JNIEnv* env, jobject jvm, jlong cutoff_ticks, jboolean emit_all)) LeakProfiler::emit_events(cutoff_ticks, emit_all == JNI_TRUE); JVM_END + +JVM_ENTRY_NO_ENV(void, jfr_exclude_thread(JNIEnv* env, jobject jvm, jobject t)) + JfrJavaSupport::exclude(t); +JVM_END + +JVM_ENTRY_NO_ENV(void, jfr_include_thread(JNIEnv* env, jobject jvm, jobject t)) + JfrJavaSupport::include(t); +JVM_END + +JVM_ENTRY_NO_ENV(jboolean, jfr_is_thread_excluded(JNIEnv* env, jobject jvm, jobject t)) + return JfrJavaSupport::is_excluded(t); +JVM_END + +JVM_ENTRY_NO_ENV(jlong, jfr_chunk_start_nanos(JNIEnv* env, jobject jvm)) + return JfrRepository::current_chunk_start_nanos(); +JVM_END + diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/jni/jfrJniMethod.hpp --- a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -113,6 +113,7 @@ jboolean JNICALL jfr_event_writer_flush(JNIEnv* env, jclass cls, jobject writer, jint used_size, jint requested_size); +void JNICALL jfr_flush(JNIEnv* env, jobject jvm); void JNICALL jfr_abort(JNIEnv* env, jobject jvm, jstring errorMsg); jlong JNICALL jfr_get_epoch_address(JNIEnv* env, jobject jvm); @@ -131,6 +132,13 @@ jboolean JNICALL jfr_should_rotate_disk(JNIEnv* env, jobject jvm); +void JNICALL jfr_exclude_thread(JNIEnv* env, jobject jvm, jobject t); + +void JNICALL jfr_include_thread(JNIEnv* env, jobject jvm, jobject t); + +jboolean JNICALL jfr_is_thread_excluded(JNIEnv* env, jobject jvm, jobject t); + +jlong JNICALL jfr_chunk_start_nanos(JNIEnv* env, jobject jvm); #ifdef __cplusplus } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp --- a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp Wed Nov 06 17:13:26 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 @@ -70,6 +70,7 @@ (char*)"getEventWriter", (char*)"()Ljava/lang/Object;", (void*)jfr_get_event_writer, (char*)"newEventWriter", (char*)"()Ljdk/jfr/internal/EventWriter;", (void*)jfr_new_event_writer, (char*)"flush", (char*)"(Ljdk/jfr/internal/EventWriter;II)Z", (void*)jfr_event_writer_flush, + (char*)"flush", (char*)"()V", (void*)jfr_flush, (char*)"setRepositoryLocation", (char*)"(Ljava/lang/String;)V", (void*)jfr_set_repository_location, (char*)"abort", (char*)"(Ljava/lang/String;)V", (void*)jfr_abort, (char*)"getEpochAddress", (char*)"()J",(void*)jfr_get_epoch_address, @@ -79,7 +80,11 @@ (char*)"getUnloadedEventClassCount", (char*)"()J", (void*)jfr_get_unloaded_event_classes_count, (char*)"setCutoff", (char*)"(JJ)Z", (void*)jfr_set_cutoff, (char*)"emitOldObjectSamples", (char*)"(JZ)V", (void*)jfr_emit_old_object_samples, - (char*)"shouldRotateDisk", (char*)"()Z", (void*)jfr_should_rotate_disk + (char*)"shouldRotateDisk", (char*)"()Z", (void*)jfr_should_rotate_disk, + (char*)"exclude", (char*)"(Ljava/lang/Thread;)V", (void*)jfr_exclude_thread, + (char*)"include", (char*)"(Ljava/lang/Thread;)V", (void*)jfr_include_thread, + (char*)"isExcluded", (char*)"(Ljava/lang/Thread;)Z", (void*)jfr_is_thread_excluded, + (char*)"getChunkStartNanos", (char*)"()J", (void*)jfr_chunk_start_nanos }; const size_t method_array_length = sizeof(method) / sizeof(JNINativeMethod); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/leakprofiler/chains/edgeStore.cpp --- a/src/hotspot/share/jfr/leakprofiler/chains/edgeStore.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeStore.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -259,6 +259,7 @@ assert(leak_context_edge->parent() == NULL, "invariant"); if (1 == length) { + store_gc_root_id_in_leak_context_edge(leak_context_edge, leak_context_edge); return; } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.cpp --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -34,6 +34,7 @@ #include "memory/resourceArea.hpp" #include "oops/markWord.hpp" #include "oops/oop.inline.hpp" +#include "runtime/mutexLocker.hpp" #include "runtime/thread.inline.hpp" #include "runtime/vmThread.hpp" @@ -51,8 +52,8 @@ } void EventEmitter::emit(ObjectSampler* sampler, int64_t cutoff_ticks, bool emit_all) { + assert(JfrStream_lock->owned_by_self(), "invariant"); assert(sampler != NULL, "invariant"); - ResourceMark rm; EdgeStore edge_store; if (cutoff_ticks <= 0) { @@ -68,6 +69,7 @@ } size_t EventEmitter::write_events(ObjectSampler* object_sampler, EdgeStore* edge_store, bool emit_all) { + assert_locked_or_safepoint(JfrStream_lock); assert(_thread == Thread::current(), "invariant"); assert(_thread->jfr_thread_local() == _jfr_thread_local, "invariant"); assert(object_sampler != NULL, "invariant"); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -37,6 +37,7 @@ #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp" #include "jfr/utilities/jfrHashtable.hpp" #include "jfr/utilities/jfrTypes.hpp" +#include "runtime/mutexLocker.hpp" #include "runtime/safepoint.hpp" #include "runtime/thread.hpp" #include "utilities/growableArray.hpp" @@ -271,7 +272,7 @@ } const JfrStackTrace* const stack_trace = resolve(sample); DEBUG_ONLY(validate_stack_trace(sample, stack_trace)); - JfrCheckpointWriter writer(false, true, Thread::current()); + JfrCheckpointWriter writer; writer.write_type(TYPE_STACKTRACE); writer.write_count(1); ObjectSampleCheckpoint::write_stacktrace(stack_trace, writer); @@ -291,6 +292,7 @@ // caller needs ResourceMark void ObjectSampleCheckpoint::on_rotation(const ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repo) { + assert(JfrStream_lock->owned_by_self(), "invariant"); assert(sampler != NULL, "invariant"); assert(LeakProfiler::is_running(), "invariant"); install_stack_traces(sampler, stack_trace_repo); @@ -388,7 +390,7 @@ static void write_sample_blobs(const ObjectSampler* sampler, bool emit_all, Thread* thread) { // sample set is predicated on time of last sweep const jlong last_sweep = emit_all ? max_jlong : sampler->last_sweep().value(); - JfrCheckpointWriter writer(false, false, thread); + JfrCheckpointWriter writer(thread, false); BlobWriter cbw(sampler, writer, last_sweep); iterate_samples(cbw, true); // reset blob write states @@ -397,13 +399,14 @@ } void ObjectSampleCheckpoint::write(const ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread) { + assert_locked_or_safepoint(JfrStream_lock); assert(sampler != NULL, "invariant"); assert(edge_store != NULL, "invariant"); assert(thread != NULL, "invariant"); write_sample_blobs(sampler, emit_all, thread); // write reference chains if (!edge_store->is_empty()) { - JfrCheckpointWriter writer(false, true, thread); + JfrCheckpointWriter writer(thread); ObjectSampleWriter osw(writer, edge_store); edge_store->iterate(osw); } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleWriter.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -355,10 +355,6 @@ static traceid get_gc_root_description_info_id(const Edge& edge, traceid id) { assert(edge.is_root(), "invariant"); - if (EdgeUtils::is_leak_edge(edge)) { - return 0; - } - if (root_infos == NULL) { root_infos = new RootDescriptionInfo(); } @@ -606,8 +602,8 @@ static void register_serializers() { static bool is_registered = false; if (!is_registered) { - JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTSYSTEM, false, true, new RootSystemType()); - JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTTYPE, false, true, new RootType()); + JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTSYSTEM, true, new RootSystemType()); + JfrSerializer::register_serializer(TYPE_OLDOBJECTROOTTYPE, true, new RootType()); is_registered = true; } } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -29,6 +29,7 @@ #include "gc/shared/strongRootsScope.hpp" #include "jfr/leakprofiler/utilities/unifiedOop.hpp" #include "jfr/leakprofiler/checkpoint/rootResolver.hpp" +#include "jfr/utilities/jfrThreadIterator.hpp" #include "memory/iterator.hpp" #include "memory/universe.hpp" #include "oops/klass.hpp" @@ -36,7 +37,6 @@ #include "prims/jvmtiThreadState.hpp" #include "runtime/frame.inline.hpp" #include "runtime/mutexLocker.hpp" -#include "runtime/threadSMR.inline.hpp" #include "runtime/vframe_hp.hpp" #include "services/management.hpp" #include "utilities/growableArray.hpp" @@ -256,8 +256,9 @@ public: ReferenceToThreadRootClosure(RootCallback& callback) :_callback(callback), _complete(false) { assert_locked_or_safepoint(Threads_lock); - for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) { - if (do_thread_roots(jt)) { + JfrJavaThreadIterator iter; + while (iter.has_next()) { + if (do_thread_roots(iter.next())) { return; } } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/leakprofiler/leakProfiler.cpp --- a/src/hotspot/share/jfr/leakprofiler/leakProfiler.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/leakprofiler/leakProfiler.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -31,6 +31,7 @@ #include "jfr/recorder/service/jfrOptionSet.hpp" #include "logging/log.hpp" #include "memory/iterator.hpp" +#include "runtime/mutexLocker.hpp" #include "runtime/thread.inline.hpp" #include "runtime/vmThread.hpp" @@ -92,6 +93,7 @@ if (!is_running()) { return; } + MutexLocker lock(JfrStream_lock); // exclusive access to object sampler instance ObjectSampler* const sampler = ObjectSampler::acquire(); assert(sampler != NULL, "invariant"); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp --- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -110,6 +110,9 @@ } const JfrThreadLocal* const tl = thread->jfr_thread_local(); assert(tl != NULL, "invariant"); + if (tl->is_excluded()) { + return 0; + } if (!tl->has_thread_blob()) { JfrCheckpointManager::create_thread_blob(thread); } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/metadata/jfrSerializer.hpp --- a/src/hotspot/share/jfr/metadata/jfrSerializer.hpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/metadata/jfrSerializer.hpp Wed Nov 06 17:13:26 2019 +0100 @@ -70,7 +70,8 @@ class JfrSerializer : public CHeapObj { public: virtual ~JfrSerializer() {} - static bool register_serializer(JfrTypeId id, bool require_safepoint, bool permit_cache, JfrSerializer* serializer); + virtual void on_rotation() {} + static bool register_serializer(JfrTypeId id, bool permit_cache, JfrSerializer* serializer); virtual void serialize(JfrCheckpointWriter& writer) = 0; }; diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/metadata/metadata.xml --- a/src/hotspot/share/jfr/metadata/metadata.xml Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/metadata/metadata.xml Wed Nov 06 17:13:26 2019 +0100 @@ -154,7 +154,7 @@ - + @@ -162,27 +162,27 @@ - + - + - + - + @@ -442,7 +442,7 @@ - + @@ -484,7 +484,7 @@ - + @@ -585,21 +585,21 @@ - - - @@ -810,8 +810,8 @@ - - + + @@ -1004,6 +1004,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1183,35 +1219,40 @@ - + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + @@ -1223,5 +1264,5 @@ - + diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/periodic/jfrNetworkUtilization.cpp --- a/src/hotspot/share/jfr/periodic/jfrNetworkUtilization.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/periodic/jfrNetworkUtilization.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ traceid id; uint64_t bytes_in; uint64_t bytes_out; - bool in_use; + mutable bool written; }; static GrowableArray* _interfaces = NULL; @@ -71,7 +71,7 @@ entry.id = ++interface_id; entry.bytes_in = iface->get_bytes_in(); entry.bytes_out = iface->get_bytes_out(); - entry.in_use = false; + entry.written = false; return _interfaces->at(_interfaces->append(entry)); } @@ -108,6 +108,39 @@ return ((current - old) * NANOSECS_PER_SEC) / interval.nanoseconds(); } +class JfrNetworkInterfaceName : public JfrSerializer { + public: + void serialize(JfrCheckpointWriter& writer) {} // we write each constant lazily + + void on_rotation() { + for (int i = 0; i < _interfaces->length(); ++i) { + const InterfaceEntry& entry = _interfaces->at(i); + if (entry.written) { + entry.written = false; + } + } + } +}; + +static bool register_network_interface_name_serializer() { + assert(_interfaces != NULL, "invariant"); + return JfrSerializer::register_serializer(TYPE_NETWORKINTERFACENAME, + false, // disallow caching; we want a callback every rotation + new JfrNetworkInterfaceName()); +} + +static void write_interface_constant(const InterfaceEntry& entry) { + if (entry.written) { + return; + } + JfrCheckpointWriter writer; + writer.write_type(TYPE_NETWORKINTERFACENAME); + writer.write_count(1); + writer.write_key(entry.id); + writer.write(entry.name); + entry.written = true; +} + static bool get_interfaces(NetworkInterface** network_interfaces) { const int ret_val = JfrOSInterface::network_utilization(network_interfaces); if (ret_val == OS_ERR) { @@ -117,39 +150,6 @@ return ret_val != FUNCTIONALITY_NOT_IMPLEMENTED; } -class JfrNetworkInterfaceName : public JfrSerializer { - public: - void serialize(JfrCheckpointWriter& writer) { - assert(_interfaces != NULL, "invariant"); - const JfrCheckpointContext ctx = writer.context(); - const intptr_t count_offset = writer.reserve(sizeof(u4)); // Don't know how many yet - int active_interfaces = 0; - for (int i = 0; i < _interfaces->length(); ++i) { - InterfaceEntry& entry = _interfaces->at(i); - if (entry.in_use) { - entry.in_use = false; - writer.write_key(entry.id); - writer.write(entry.name); - ++active_interfaces; - } - } - if (active_interfaces == 0) { - // nothing to write, restore context - writer.set_context(ctx); - return; - } - writer.write_count(active_interfaces, count_offset); - } -}; - -static bool register_network_interface_name_serializer() { - assert(_interfaces != NULL, "invariant"); - return JfrSerializer::register_serializer(TYPE_NETWORKINTERFACENAME, - false, // require safepoint - false, // disallow caching; we want a callback every rotation - new JfrNetworkInterfaceName()); -} - void JfrNetworkUtilization::send_events() { ResourceMark rm; NetworkInterface* network_interfaces; @@ -169,7 +169,7 @@ const uint64_t read_rate = rate_per_second(current_bytes_in, entry.bytes_in, interval); const uint64_t write_rate = rate_per_second(current_bytes_out, entry.bytes_out, interval); if (read_rate > 0 || write_rate > 0) { - entry.in_use = true; + write_interface_constant(entry); EventNetworkUtilization event(UNTIMED); event.set_starttime(cur_time); event.set_endtime(cur_time); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/periodic/jfrPeriodic.cpp --- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -44,6 +44,7 @@ #include "jfr/periodic/jfrNetworkUtilization.hpp" #include "jfr/recorder/jfrRecorder.hpp" #include "jfr/support/jfrThreadId.hpp" +#include "jfr/utilities/jfrThreadIterator.hpp" #include "jfr/utilities/jfrTime.hpp" #include "jfrfiles/jfrPeriodic.hpp" #include "logging/log.hpp" @@ -56,7 +57,6 @@ #include "runtime/os.hpp" #include "runtime/os_perf.hpp" #include "runtime/thread.inline.hpp" -#include "runtime/threadSMR.hpp" #include "runtime/sweeper.hpp" #include "runtime/vmThread.hpp" #include "services/classLoadingService.hpp" @@ -410,13 +410,12 @@ GrowableArray allocated(initial_size); GrowableArray thread_ids(initial_size); JfrTicks time_stamp = JfrTicks::now(); - { - // Collect allocation statistics while holding threads lock - MutexLocker ml(Threads_lock); - for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) { - allocated.append(jt->cooked_allocated_bytes()); - thread_ids.append(JFR_THREAD_ID(jt)); - } + JfrJavaThreadIterator iter; + while (iter.has_next()) { + JavaThread* const jt = iter.next(); + assert(jt != NULL, "invariant"); + allocated.append(jt->cooked_allocated_bytes()); + thread_ids.append(JFR_THREAD_ID(jt)); } // Write allocation statistics to buffer. @@ -558,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 08102295011d -r 18659e040c64 src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.cpp --- a/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,11 +28,10 @@ #include "jfr/periodic/jfrThreadCPULoadEvent.hpp" #include "jfr/support/jfrThreadId.hpp" #include "jfr/support/jfrThreadLocal.hpp" +#include "jfr/utilities/jfrThreadIterator.hpp" #include "jfr/utilities/jfrTime.hpp" #include "utilities/globalDefinitions.hpp" #include "runtime/os.hpp" -#include "runtime/thread.inline.hpp" -#include "runtime/threadSMR.inline.hpp" jlong JfrThreadCPULoadEvent::get_wallclock_time() { return os::javaTimeNanos(); @@ -115,8 +114,12 @@ JfrTicks event_time = JfrTicks::now(); jlong cur_wallclock_time = JfrThreadCPULoadEvent::get_wallclock_time(); - JavaThreadIteratorWithHandle jtiwh; - while (JavaThread* jt = jtiwh.next()) { + JfrJavaThreadIterator iter; + int number_of_threads = 0; + while (iter.has_next()) { + JavaThread* const jt = iter.next(); + assert(jt != NULL, "invariant"); + ++number_of_threads; EventThreadCPULoad event(UNTIMED); if (JfrThreadCPULoadEvent::update_event(event, jt, cur_wallclock_time, processor_count)) { event.set_starttime(event_time); @@ -129,7 +132,7 @@ event.commit(); } } - log_trace(jfr)("Measured CPU usage for %d threads in %.3f milliseconds", jtiwh.length(), + log_trace(jfr)("Measured CPU usage for %d threads in %.3f milliseconds", number_of_threads, (double)(JfrTicks::now() - event_time).milliseconds()); // Restore this thread's thread id periodic_thread_tl->set_thread_id(periodic_thread_id); diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -30,6 +30,7 @@ #include "jfr/recorder/service/jfrOptionSet.hpp" #include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp" #include "jfr/support/jfrThreadId.hpp" +#include "jfr/support/jfrThreadLocal.hpp" #include "jfr/utilities/jfrTime.hpp" #include "logging/log.hpp" #include "runtime/frame.inline.hpp" @@ -352,9 +353,14 @@ } } +static bool is_excluded(JavaThread* thread) { + assert(thread != NULL, "invariant"); + return thread->is_hidden_from_external_view() || thread->in_deopt_handler() || thread->jfr_thread_local()->is_excluded(); +} + bool JfrThreadSampleClosure::do_sample_thread(JavaThread* thread, JfrStackFrame* frames, u4 max_frames, JfrSampleType type) { assert(Threads_lock->owned_by_self(), "Holding the thread table lock."); - if (thread->is_hidden_from_external_view() || thread->in_deopt_handler()) { + if (is_excluded(thread)) { return false; } diff -r 08102295011d -r 18659e040c64 src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp Fri Nov 01 14:18:40 2019 +0100 +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp Wed Nov 06 17:13:26 2019 +0100 @@ -37,11 +37,14 @@ #include "jfr/recorder/storage/jfrMemorySpace.inline.hpp" #include "jfr/recorder/storage/jfrStorageUtils.inline.hpp" #include "jfr/utilities/jfrBigEndian.hpp" +#include "jfr/utilities/jfrIterator.hpp" +#include "jfr/utilities/jfrThreadIterator.hpp" #include "jfr/utilities/jfrTypes.hpp" +#include "jfr/writers/jfrJavaEventWriter.hpp" #include "logging/log.hpp" #include "memory/resourceArea.hpp" #include "runtime/handles.inline.hpp" -#include "runtime/mutexLocker.hpp" +#include "runtime/mutex.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.inline.hpp" #include "runtime/safepoint.hpp" @@ -168,7 +171,7 @@ } bool JfrCheckpointManager::use_epoch_transition_mspace(const Thread* thread) const { - return _service_thread != thread && OrderAccess::load_acquire(&_checkpoint_epoch_state) != JfrTraceIdEpoch::epoch(); + return _service_thread != thread && _checkpoint_epoch_state != JfrTraceIdEpoch::epoch(); } static const size_t lease_retry = 10; @@ -181,12 +184,24 @@ return lease_free(size, manager._free_list_mspace, lease_retry, thread); } +JfrCheckpointMspace* JfrCheckpointManager::lookup(BufferPtr old) const { + assert(old != NULL, "invariant"); + return _free_list_mspace->in_free_list(old) ? _free_list_mspace : _epoch_transition_mspace; +} + +BufferPtr JfrCheckpointManager::lease_buffer(BufferPtr old, Thread* thread, size_t size /* 0 */) { + assert(old != NULL, "invariant"); + JfrCheckpointMspace* mspace = instance().lookup(old); + assert(mspace != NULL, "invariant"); + return lease_free(size, mspace, lease_retry, thread); +} + /* -* If the buffer was a "lease" from the free list, release back. -* -* The buffer is effectively invalidated for the thread post-return, -* and the caller should take means to ensure that it is not referenced. -*/ + * If the buffer was a lease, release back. + * + * The buffer is effectively invalidated for the thread post-return, + * and the caller should take means to ensure that it is not referenced. + */ static void release(BufferPtr const buffer, Thread* thread) { DEBUG_ONLY(assert_release(buffer);) buffer->clear_lease(); @@ -202,7 +217,7 @@ return NULL; } // migration of in-flight information - BufferPtr const new_buffer = lease_buffer(thread, used + requested); + BufferPtr const new_buffer = lease_buffer(old, thread, used + requested); if (new_buffer != NULL) { migrate_outstanding_writes(old, new_buffer, used, requested); } @@ -213,8 +228,8 @@ // offsets into the JfrCheckpointEntry static const juint starttime_offset = sizeof(jlong); static const juint duration_offset = starttime_offset + sizeof(jlong); -static const juint flushpoint_offset = duration_offset + sizeof(jlong); -static const juint types_offset = flushpoint_offset + sizeof(juint); +static const juint checkpoint_type_offset = duration_offset + sizeof(jlong); +static const juint types_offset = checkpoint_type_offset + sizeof(juint); static const juint payload_offset = types_offset + sizeof(juint); template @@ -234,21 +249,21 @@ return read_data(data + duration_offset); } -static bool is_flushpoint(const u1* data) { - return read_data(data + flushpoint_offset) == (juint)1; +static u1 checkpoint_type(const u1* data) { + return read_data(data + checkpoint_type_offset); } static juint number_of_types(const u1* data) { return read_data(data + types_offset); } -static void write_checkpoint_header(JfrChunkWriter& cw, int64_t offset_prev_cp_event, const u1* data) { +static void write_checkpoint_header(JfrChunkWriter& cw, int64_t delta_to_last_checkpoint, const u1* data) { cw.reserve(sizeof(u4)); cw.write(EVENT_CHECKPOINT); cw.write(starttime(data)); cw.write(duration(data)); - cw.write(offset_prev_cp_event); - cw.write(is_flushpoint(data)); + cw.write(delta_to_last_checkpoint); + cw.write(checkpoint_type(data)); cw.write(number_of_types(data)); } @@ -261,9 +276,9 @@ assert(data != NULL, "invariant"); const int64_t event_begin = cw.current_offset(); const int64_t last_checkpoint_event = cw.last_checkpoint_offset(); - const int64_t delta = last_checkpoint_event == 0 ? 0 : last_checkpoint_event - event_begin; + const int64_t delta_to_last_checkpoint = last_checkpoint_event == 0 ? 0 : last_checkpoint_event - event_begin; const int64_t checkpoint_size = total_size(data); - write_checkpoint_header(cw, delta, data); + write_checkpoint_header(cw, delta_to_last_checkpoint, data); write_checkpoint_content(cw, data, checkpoint_size); const int64_t event_size = cw.current_offset() - event_begin; cw.write_padded_at_offset(event_size, event_begin); @@ -305,13 +320,13 @@ typedef CheckpointWriteOp WriteOperation; typedef ReleaseOp CheckpointReleaseOperation; -template