OpenJDK / jdk / hs
changeset 37478:ef779fb991cf
Merge
author | amurillo |
---|---|
date | Thu, 14 Apr 2016 19:55:39 -0700 |
parents | 82e233a4a546 0ca0b7388bb6 |
children | 14a195eaf2c5 3bf78337709d |
files | hotspot/src/share/vm/utilities/top.hpp |
diffstat | 271 files changed, 6125 insertions(+), 2259 deletions(-) [+] |
line wrap: on
line diff
--- a/hotspot/make/Makefile Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/Makefile Thu Apr 14 19:55:39 2016 -0700 @@ -237,19 +237,21 @@ $(MAKE_ARGS) $(VM_TARGET) endif +# NOTE: Changes in this file was just to facilitate comparison when +# developing the new build, and should not be integrated. generic_buildcore: $(HOTSPOT_SCRIPT) -ifeq ($(HS_ARCH),ppc) - ifeq ($(ARCH_DATA_MODEL),64) +#ifeq ($(HS_ARCH),ppc) +# ifeq ($(ARCH_DATA_MODEL),64) $(MKDIR) -p $(OUTPUTDIR) $(CD) $(OUTPUTDIR); \ $(MAKE) -f $(ABS_OS_MAKEFILE) \ $(MAKE_ARGS) $(VM_TARGET) - else - @$(ECHO) "No ($(VM_TARGET)) for ppc ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)" - endif -else - @$(ECHO) "No ($(VM_TARGET)) for $(HS_ARCH)" -endif +# else +# @$(ECHO) "No ($(VM_TARGET)) for ppc ARCH_DATA_MODEL=$(ARCH_DATA_MODEL)" +# endif +#else +# @$(ECHO) "No ($(VM_TARGET)) for $(HS_ARCH)" +#endif generic_buildzero: $(HOTSPOT_SCRIPT) $(MKDIR) -p $(OUTPUTDIR)
--- a/hotspot/make/aix/makefiles/trace.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/aix/makefiles/trace.make Thu Apr 14 19:55:39 2016 -0700 @@ -53,13 +53,13 @@ TraceGeneratedNames = \ traceEventClasses.hpp \ - traceEventIds.hpp \ - traceTypes.hpp + traceEventIds.hpp \ + traceTypes.hpp ifeq ($(HAS_ALT_SRC), true) - TraceGeneratedNames += \ - traceRequestables.hpp \ - traceEventControl.hpp +TraceGeneratedNames += \ + traceRequestables.hpp \ + traceEventControl.hpp endif TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/bsd/makefiles/trace.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/bsd/makefiles/trace.make Thu Apr 14 19:55:39 2016 -0700 @@ -53,13 +53,13 @@ TraceGeneratedNames = \ traceEventClasses.hpp \ - traceEventIds.hpp \ - traceTypes.hpp + traceEventIds.hpp \ + traceTypes.hpp ifeq ($(HAS_ALT_SRC), true) - TraceGeneratedNames += \ - traceRequestables.hpp \ - traceEventControl.hpp +TraceGeneratedNames += \ + traceRequestables.hpp \ + traceEventControl.hpp endif TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/linux/makefiles/gcc.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/linux/makefiles/gcc.make Thu Apr 14 19:55:39 2016 -0700 @@ -221,7 +221,7 @@ ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0" # GCC < 4.3 WARNING_FLAGS += -Wconversion - endif + endif ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 8 \) \))" "1" # GCC >= 4.8 # This flag is only known since GCC 4.3. Gcc 4.8 contains a fix so that with templates no @@ -260,7 +260,7 @@ OPT_CFLAGS = $(OPT_CFLAGS/$(OPT_CFLAGS_DEFAULT)) $(OPT_EXTRAS) -# Variable tracking size limit exceeded for VMStructs::init() +# Variable tracking size limit exceeded for VMStructs::init() ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "1" # GCC >= 4.3 # Gcc 4.1.2 does not support this flag, nor does it have problems compiling the file.
--- a/hotspot/make/linux/makefiles/trace.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/linux/makefiles/trace.make Thu Apr 14 19:55:39 2016 -0700 @@ -53,13 +53,13 @@ TraceGeneratedNames = \ traceEventClasses.hpp \ - traceEventIds.hpp \ - traceTypes.hpp + traceEventIds.hpp \ + traceTypes.hpp ifeq ($(HAS_ALT_SRC), true) - TraceGeneratedNames += \ - traceRequestables.hpp \ - traceEventControl.hpp +TraceGeneratedNames += \ + traceRequestables.hpp \ + traceEventControl.hpp endif TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/linux/makefiles/zero.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/linux/makefiles/zero.make Thu Apr 14 19:55:39 2016 -0700 @@ -30,3 +30,8 @@ # Install libjvm.so, etc in in server directory. VM_SUBDIR = server + +# Disable trace for zero builds +# NOTE: This is used for simple comparison with the new build system, and +# should not be merged into mainline with build-infra. +INCLUDE_TRACE := false
--- a/hotspot/make/share/makefiles/mapfile-vers Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/share/makefiles/mapfile-vers Thu Apr 14 19:55:39 2016 -0700 @@ -41,7 +41,6 @@ JVM_DumpAllStacks; JVM_DumpThreads; JVM_FillInStackTrace; - JVM_FillStackFrames; JVM_FindClassFromCaller; JVM_FindClassFromClass; JVM_FindClassFromBootLoader; @@ -157,13 +156,13 @@ JVM_SetClassSigners; JVM_SetNativeThreadName; JVM_SetPrimitiveArrayElement; - JVM_SetMethodInfo; JVM_SetThreadPriority; JVM_Sleep; JVM_StartThread; JVM_StopThread; JVM_SuspendThread; JVM_SupportsCX8; + JVM_ToStackTraceElement; JVM_TotalMemory; JVM_UnloadLibrary; JVM_Yield;
--- a/hotspot/make/solaris/makefiles/dtrace.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/solaris/makefiles/dtrace.make Thu Apr 14 19:55:39 2016 -0700 @@ -270,7 +270,7 @@ @echo $(LOG_INFO) Compiling $(DTRACE).d $(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -G -xlazyload -o $@ -s $(DTRACE).d \ - $(DTraced_Files) ||\ + $(sort $(DTraced_Files)) ||\ STATUS=$$?;\ if [ x"$$STATUS" = x"1" ]; then \ if [ x`uname -r` = x"5.10" -a \
--- a/hotspot/make/solaris/makefiles/trace.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/solaris/makefiles/trace.make Thu Apr 14 19:55:39 2016 -0700 @@ -53,13 +53,13 @@ TraceGeneratedNames = \ traceEventClasses.hpp \ - traceEventIds.hpp \ - traceTypes.hpp + traceEventIds.hpp \ + traceTypes.hpp ifeq ($(HAS_ALT_SRC), true) - TraceGeneratedNames += \ - traceRequestables.hpp \ - traceEventControl.hpp +TraceGeneratedNames += \ + traceRequestables.hpp \ + traceEventControl.hpp endif TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
--- a/hotspot/make/windows/makefiles/debug.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/windows/makefiles/debug.make Thu Apr 14 19:55:39 2016 -0700 @@ -48,10 +48,10 @@ # Force resources to be rebuilt every time $(Res_Files): FORCE +# NOTE: Changes in this file was just to give a proper command line when linking +# for use when developing the new build, and should not be integrated. $(AOUT): $(Res_Files) $(Obj_Files) vm.def - $(LD) @<< - $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) -<< + $(LD) $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) !if "$(MT)" != "" # The previous link command created a .manifest file that we want to # insert into the linked artifact so we do not need to track it
--- a/hotspot/make/windows/makefiles/fastdebug.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/windows/makefiles/fastdebug.make Thu Apr 14 19:55:39 2016 -0700 @@ -47,10 +47,10 @@ # Force resources to be rebuilt every time $(Res_Files): FORCE +# NOTE: Changes in this file was just to give a proper command line when linking +# for use when developing the new build, and should not be integrated. $(AOUT): $(Res_Files) $(Obj_Files) vm.def - $(LD) @<< - $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) -<< + $(LD) $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) !if "$(MT)" != "" # The previous link command created a .manifest file that we want to # insert into the linked artifact so we do not need to track it
--- a/hotspot/make/windows/makefiles/product.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/windows/makefiles/product.make Thu Apr 14 19:55:39 2016 -0700 @@ -51,10 +51,11 @@ # Force resources to be rebuilt every time $(Res_Files): FORCE +# NOTE: Changes in this file was just to give a proper command line when linking +# for use when developing the new build, and should not be integrated. $(AOUT): $(Res_Files) $(Obj_Files) vm.def - $(LD) @<< - $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) -<< + $(LD) $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) + !if "$(MT)" != "" # The previous link command created a .manifest file that we want to # insert into the linked artifact so we do not need to track it
--- a/hotspot/make/windows/makefiles/trace.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/windows/makefiles/trace.make Thu Apr 14 19:55:39 2016 -0700 @@ -41,6 +41,12 @@ !endif !endif +!ifndef OPENJDK +!if EXISTS($(TraceAltSrcDir)) +HAS_ALT_SRC = true +!endif +!endif + TraceGeneratedNames = \ traceEventClasses.hpp \ traceEventIds.hpp \
--- a/hotspot/make/windows/makefiles/vm.make Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/make/windows/makefiles/vm.make Thu Apr 14 19:55:39 2016 -0700 @@ -305,8 +305,10 @@ # This guy should remain a single colon rule because # otherwise we can't specify the output filename. +# NOTE: Changes in this file was just to give a proper command line when linking +# for use when developing the new build, and should not be integrated. {$(COMMONSRC)\os\windows\vm}.rc.res: - @$(RC) $(RC_FLAGS) /fo"$@" $< + $(RC) $(RC_FLAGS) /fo"$@" $< {$(COMMONSRC)\cpu\$(Platform_arch)\vm}.cpp.obj:: $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/BuildHotspot.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,54 @@ +# +# Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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 must be the first rule +default: all + +include $(SPEC) +include MakeBase.gmk + +VARIANT_TARGETS := $(foreach v, $(JVM_VARIANTS), variant-$v) +VARIANT_GENSRC_TARGETS := $(addsuffix -gensrc, $(VARIANT_TARGETS)) +VARIANT_LIBS_TARGETS := $(addsuffix -libs, $(VARIANT_TARGETS)) + +$(VARIANT_GENSRC_TARGETS): variant-%-gensrc: + $(call LogWarn, Building JVM variant '$*' with features '$(JVM_FEATURES_$*)') + +$(MAKE) -f gensrc/GenerateSources.gmk JVM_VARIANT=$* + +$(VARIANT_LIBS_TARGETS): variant-%-libs: variant-%-gensrc + +$(MAKE) -f lib/CompileLibraries.gmk JVM_VARIANT=$* + +$(VARIANT_TARGETS): variant-%: variant-%-gensrc variant-%-libs + +jsig: + +$(MAKE) -f lib/CompileLibjsig.gmk + +dist: $(VARIANT_TARGETS) jsig + +$(MAKE) -f Dist.gmk + +all: dist + +.PHONY: $(VARIANT_TARGETS) $(VARIANT_GENSRC_TARGETS) $(VARIANT_LIBS_TARGETS) \ + jsig dist all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/Dist.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,239 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +################################################################################ +# Copy the generated output into well-defined places in the dist directory. + +# This must be the first rule +default: all + +include $(SPEC) +include MakeBase.gmk + +$(eval $(call IncludeCustomExtension, hotspot, Dist.gmk)) + +DIST_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/dist + +# Unfortunately, all platforms have different target subdirs. +ifeq ($(OPENJDK_TARGET_OS), windows) + LIB_SUBDIR := bin +else ifeq ($(OPENJDK_TARGET_OS), macosx) + LIB_SUBDIR := lib +else + LIB_SUBDIR := lib$(OPENJDK_TARGET_CPU_LIBDIR) +endif + +################################################################################ +# Functions to setup copying of files for variants + +# Support macro for SetupDistLibFile +define macosx_universalize + $(MKDIR) -p $(@D) + $(LIPO) -create -output $@ $< +endef + +################################################################################ +# Setup make rules to copy a native library and associated data. +# +# Parameter 1 is the name of the rule. This name is used as variable prefix, +# and the targets generated are listed in a variable by that name. +# +# Remaining parameters are named arguments. These include: +# NAME -- The base name of the native library (e.g. 'jvm') +# VARIANT -- The variant to copy from +# VARIANT_TARGET_DIR -- The variant target sub dir, with trailing slash, optional +SetupDistLibFile = $(NamedParamsMacroTemplate) +define SetupDistLibFileBody + ifneq ($$($1_VARIANT), ) + $1_SRC_DIR := $$(HOTSPOT_OUTPUTDIR)/variant-$$($1_VARIANT)/lib$$($1_NAME) + else + $1_SRC_DIR := $$(HOTSPOT_OUTPUTDIR)/lib$$($1_NAME) + endif + $1_LIB_NAME := $(LIBRARY_PREFIX)$$($1_NAME) + $1_TARGET_DIR := $$(DIST_OUTPUTDIR)/$$(LIB_SUBDIR)/$$($1_VARIANT_TARGET_DIR) + + ifeq ($(OPENJDK_TARGET_OS), macosx) + # We must use the 'universalize' macro to run lipo on shared libraries, at + # least until JDK-8069540 is fixed. + $1_MACRO := macosx_universalize + endif + + # Copy the the native library. + $$(eval $$(call SetupCopyFiles, $1_COPY_LIB, \ + DEST := $$($1_TARGET_DIR), \ + MACRO := $$($1_MACRO), \ + FILES := $$(wildcard \ + $$($1_SRC_DIR)/$$($1_LIB_NAME)$(SHARED_LIBRARY_SUFFIX)), \ + )) + + TARGETS += $$($1_COPY_LIB) + + # Copy related data (debug symbols, static-build symbols file etc) + $$(eval $$(call SetupCopyFiles, $1_COPY_FILES, \ + DEST := $$($1_TARGET_DIR), \ + FILES := $$(wildcard \ + $$(addprefix $$($1_SRC_DIR)/$$($1_LIB_NAME), \ + .diz .debuginfo .pdb .map .symbols)), \ + )) + + TARGETS += $$($1_COPY_FILES) + + ifeq ($(OPENJDK_TARGET_OS), macosx) + # Debug symbols on macosx is a directory, not a single file, per library. + $1_DSYM_SRC := $$($1_SRC_DIR)/$$($1_LIB_NAME)$(SHARED_LIBRARY_SUFFIX).dSYM) + ifneq ($$(wildcard $$($1_DSYM_SRC)), ) + $$(eval $$(call SetupCopyFiles, $1_COPY_DSYM_DIR, \ + DEST := $$($1_TARGET_DIR), \ + SRC := $$($1_SRC_DIR), \ + FILES := $$(shell $(FIND) $$($1_DSYM_SRC) -type f), \ + )) + TARGETS += $$($1_COPY_DSYM_DIR) + endif + endif +endef + +################################################################################ +# Copy common files, which are independent on the jvm variant(s) being built. +# For files that were generated during the build, we assume all versions of +# these files are identical, and just pick one arbitrarily to use as source. + +ANY_JVM_VARIANT := $(firstword $(JVM_VARIANTS)) +JVM_VARIANT_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/variant-$(ANY_JVM_VARIANT) + +### Copy platform-independent .h files +INCLUDE_FILES_SRC_DIR := $(HOTSPOT_TOPDIR)/src/share/vm +$(eval $(call SetupCopyFiles, COPY_INCLUDE, \ + SRC := $(INCLUDE_FILES_SRC_DIR), \ + DEST := $(DIST_OUTPUTDIR)/include, \ + FLATTEN := true, \ + FILES := $(INCLUDE_FILES_SRC_DIR)/prims/jni.h \ + $(INCLUDE_FILES_SRC_DIR)/code/jvmticmlr.h \ + $(INCLUDE_FILES_SRC_DIR)/services/jmm.h)) + +TARGETS += $(COPY_INCLUDE) + +### Copy jni_md.h + +# This might have been defined in a custom extension +ifeq ($(JNI_MD_H_SRC), ) + JNI_MD_H_SRC := $(HOTSPOT_TOPDIR)/src/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm/jni_$(HOTSPOT_TARGET_CPU_ARCH).h +endif + +ifeq ($(OPENJDK_TARGET_OS), macosx) + # NOTE: This should most likely be darwin, but the old hotspot build uses bsd + JNI_MD_SUBDIR := bsd +else ifeq ($(OPENJDK_TARGET_OS), windows) + JNI_MD_SUBDIR := win32 +else + JNI_MD_SUBDIR := $(OPENJDK_TARGET_OS) +endif + +# SetupCopyFiles is not used here since it's non-trivial to copy a single +# file with a different target name. +$(DIST_OUTPUTDIR)/include/$(JNI_MD_SUBDIR)/jni_md.h: $(JNI_MD_H_SRC) + $(call LogInfo, Copying hotspot/dist/include/$(JNI_MD_SUBDIR)/jni_md.h) + $(install-file) + +TARGETS += $(DIST_OUTPUTDIR)/include/$(JNI_MD_SUBDIR)/jni_md.h + +$(eval $(call SetupCopyFiles, COPY_JVMTI_H, \ + DEST := $(DIST_OUTPUTDIR)/include, \ + FLATTEN := true, \ + FILES := $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles/jvmti.h)) + +TARGETS += $(COPY_JVMTI_H) + +# NOTE: In the old build, this file was not copied on Windows. +ifneq ($(OPENJDK_TARGET_OS), windows) + $(eval $(call SetupCopyFiles, COPY_JVMTI_HTML, \ + DEST := $(DIST_OUTPUTDIR)/docs/platform/jvmti, \ + FILES := $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles/jvmti.html)) +endif + +TARGETS += $(COPY_JVMTI_HTML) + +ifeq ($(OPENJDK_TARGET_OS), windows) + $(eval $(call SetupCopyFiles, COPY_JVM_LIB, \ + DEST := $(DIST_OUTPUTDIR)/lib, \ + FILES :=$(JVM_VARIANT_OUTPUTDIR)/libjvm/objs/jvm.lib)) + + TARGETS += $(COPY_JVM_LIB) +endif + +# Copy libjsig, if it exists +$(eval $(call SetupDistLibFile, DIST_jsig, \ + NAME := jsig, \ +)) + +################################################################################ +# Copy variant-specific files + +# Setup make rules to copy a single variant to dist. +# $1: The name of the variant +define SetupDistForVariant + ifneq ($$(filter client minimal, $1), ) + VARIANT_TARGET_DIR := $1 + else + # Use 'server' as default target directory name for all other variants. + VARIANT_TARGET_DIR := server + endif + + $$(eval $$(call SetupDistLibFile, DIST_$(strip $1)_jvm, \ + NAME := jvm, \ + VARIANT := $1, \ + VARIANT_TARGET_DIR := $$(VARIANT_TARGET_DIR)/, \ + )) + + # Copy the dtrace libraries, if they exist + $$(eval $$(call SetupDistLibFile, DIST_$(strip $1)_jvm_db, \ + NAME := jvm_db, \ + VARIANT := $1, \ + VARIANT_TARGET_DIR := $$(VARIANT_TARGET_DIR)/, \ + )) + + $$(eval $$(call SetupDistLibFile, DIST_$(strip $1)_jvm_dtrace, \ + NAME := jvm_dtrace, \ + VARIANT := $1, \ + VARIANT_TARGET_DIR := $$(VARIANT_TARGET_DIR)/, \ + )) + + # Copy the Xusage.txt file + $$(eval $$(call SetupCopyFiles, DIST_$(strip $1)_Xusage, \ + DEST := $$(DIST_OUTPUTDIR)/$$(LIB_SUBDIR)/$(strip $1), \ + FILES := $$(HOTSPOT_OUTPUTDIR)/variant-$(strip $1)/support/misc/Xusage.txt, \ + )) + + TARGETS += $$(DIST_$(strip $1)_Xusage) +endef + +$(foreach variant, $(JVM_VARIANTS), \ + $(eval $(call SetupDistForVariant, $(variant))) \ +) + +################################################################################ + +all: $(TARGETS) + +.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/HotspotCommon.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,45 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +ifeq ($(JVM_VARIANT), ) + $(error This makefile must be called with JVM_VARIANT set) +endif + +JVM_VARIANT_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/variant-$(JVM_VARIANT) +JVM_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm +JVM_SUPPORT_DIR := $(JVM_VARIANT_OUTPUTDIR)/support + +DTRACE_SUPPORT_DIR := $(JVM_SUPPORT_DIR)/dtrace + +################################################################################ + +# Test if a feature is available in the present build of JVM_VARIANT. Will return +# 'true' or 'false'. +# $1 - the feature to test for +check-jvm-feature = \ + $(strip \ + $(if $(filter-out $(VALID_JVM_FEATURES), $1), \ + $(error Internal error: Invalid feature tested: $1)) \ + $(if $(filter $1, $(JVM_FEATURES_$(JVM_VARIANT))), true, false))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/gensrc/GenerateSources.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,75 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +default: all + +include $(SPEC) +include MakeBase.gmk +include JavaCompilation.gmk +include NativeCompilation.gmk +include TextFileProcessing.gmk + +include HotspotCommon.gmk + +# The real work is done in these files + +include gensrc/GensrcAdlc.gmk +include gensrc/GensrcDtrace.gmk +include gensrc/GensrcJvmti.gmk + +$(eval $(call IncludeCustomExtension, hotspot, gensrc/GenerateSources.gmk)) + +# While technically the rules below are "gendata" which can be done in parallel +# with native compilation, let's keep it here for simplicity. + +# The Xusage.txt file needs to have platform specific path separator +$(eval $(call SetupTextFileProcessing, CREATE_XUSAGE, \ + SOURCE_FILES := $(HOTSPOT_TOPDIR)/src/share/vm/Xusage.txt, \ + OUTPUT_FILE := $(JVM_SUPPORT_DIR)/misc/Xusage.txt, \ + REPLACEMENTS := separated by ;> => separated by $(PATH_SEP)> ; , \ +)) + +TARGETS += $(CREATE_XUSAGE) + +# Setup the hotspot launcher script for developer use +$(eval $(call SetupTextFileProcessing, CREATE_HOTSPOT_LAUNCHER, \ + SOURCE_FILES := $(HOTSPOT_TOPDIR)/make/hotspot.script, \ + OUTPUT_FILE := $(JVM_OUTPUTDIR)/hotspot, \ + REPLACEMENTS := \ + @@LIBARCH@@ => $(OPENJDK_TARGET_CPU_LEGACY_LIB) ; \ + @@JDK_IMPORT_PATH@@ => $(JDK_OUTPUTDIR) ; , \ +)) + +CHMOD_HOTSPOT_LAUNCHER := $(JVM_VARIANT_OUTPUTDIR)/libjvm/_hotspot-script-chmod.marker + +$(CHMOD_HOTSPOT_LAUNCHER): $(CREATE_HOTSPOT_LAUNCHER) + $(CHMOD) +x $< + $(TOUCH) $@ + +TARGETS += $(CREATE_HOTSPOT_LAUNCHER) $(CHMOD_HOTSPOT_LAUNCHER) + +all: $(TARGETS) + +.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/gensrc/GensrcAdlc.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,191 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +$(eval $(call IncludeCustomExtension, hotspot, gensrc/GensrcAdlc.gmk)) + +ifeq ($(call check-jvm-feature, compiler2), true) + + ADLC_SUPPORT_DIR := $(JVM_SUPPORT_DIR)/adlc + + ############################################################################## + # Build the ad compiler (the adlc build tool) + + # Flags depending on the build platform/tool chain + # NOTE: No optimization or debug flags set here + ifeq ($(OPENJDK_BUILD_OS), linux) + ADLC_CFLAGS := -fno-exceptions -DLINUX + else ifeq ($(OPENJDK_BUILD_OS), solaris) + ADLC_LDFLAGS := -m64 + ADLC_CFLAGS := -m64 + ADLC_CFLAGS_WARNINGS := +w + else ifeq ($(OPENJDK_BUILD_OS), aix) + ADLC_LDFLAGS := -q64 + ADLC_CFLAGS := -qnortti -qeh -q64 -DAIX + else ifeq ($(OPENJDK_BUILD_OS), windows) + ADLC_LDFLAGS := -nologo + ADLC_CFLAGS := -nologo -EHsc + # NOTE: The old build also have -D_CRT_SECURE_NO_DEPRECATE but it doesn't + # seem needed any more. + ADLC_CFLAGS_WARNINGS := -W3 -D_CRT_SECURE_NO_WARNINGS + endif + + # NOTE: The old build didn't set -DASSERT for windows but it doesn't seem to + # hurt. + ADLC_CFLAGS += -DASSERT + + ADLC_CFLAGS += -D$(HOTSPOT_TARGET_CPU_DEFINE) + + ADLC_CFLAGS += -I$(HOTSPOT_TOPDIR)/src/share/vm + + $(eval $(call SetupNativeCompilation, BUILD_ADLC, \ + TOOLCHAIN := TOOLCHAIN_BUILD_LINK_CXX, \ + SRC := $(HOTSPOT_TOPDIR)/src/share/vm/adlc, \ + EXTRA_FILES := $(HOTSPOT_TOPDIR)/src/share/vm/opto/opcodes.cpp, \ + CFLAGS := $(ADLC_CFLAGS) $(ADLC_CFLAGS_WARNINGS), \ + LDFLAGS := $(ADLC_LDFLAGS), \ + LIBS := $(ADLC_LIBS), \ + OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/adlc/objs, \ + OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/adlc, \ + PROGRAM := adlc, \ + DEBUG_SYMBOLS := false, \ + DISABLED_WARNINGS_clang := parentheses tautological-compare, \ + DISABLED_WARNINGS_solstudio := notemsource, \ + )) + + ADLC_TOOL := $(BUILD_ADLC_TARGET) + + ############################################################################## + # Transform the ad source files into C++ source files using adlc + + # Setup flags for the adlc build tool (ADLCFLAGS). + ADLCFLAGS += -q -T + + # ADLC flags depending on target OS + ifeq ($(OPENJDK_TARGET_OS), linux) + ADLCFLAGS += -DLINUX=1 -D_GNU_SOURCE=1 + else ifeq ($(OPENJDK_TARGET_OS), solaris) + ADLCFLAGS += -DSOLARIS=1 -DSPARC_WORKS=1 + else ifeq ($(OPENJDK_TARGET_OS), aix) + ADLCFLAGS += -DAIX=1 + else ifeq ($(OPENJDK_TARGET_OS), macosx) + ADLCFLAGS += -D_ALLBSD_SOURCE=1 -D_GNU_SOURCE=1 + endif + + ifneq ($(OPENJDK_TARGET_OS), windows) + # NOTE: Windows adlc flags was different in the old build. Is this really + # correct? + + # -g makes #line directives in the generated C++ files. + ADLCFLAGS += -g + + ADLCFLAGS += -D$(HOTSPOT_TARGET_CPU_DEFINE)=1 + endif + + # This generates checks in the generated C++ files that _LP64 is correctly + # (un)defined when compiling them. + ifeq ($(OPENJDK_TARGET_CPU_BITS), 64) + ADLCFLAGS += -D_LP64=1 + else + ADLCFLAGS += -U_LP64 + endif + + ############################################################################## + # Concatenate all ad source files into a single file, which will be fed to + # adlc. Also include a #line directive at the start of every included file + # (after the initial header block), stating the original source file name. + # + # Normally, debugging is done directly on the ad_<arch>*.cpp files, but the + # #line directives in those files will be pointing back to <arch>.ad. + + # AD_SRC_ROOTS might have been added to by a custom extension + AD_SRC_ROOTS += $(HOTSPOT_TOPDIR)/src + + AD_SRC_FILES := $(call uniq, $(wildcard $(foreach d, $(AD_SRC_ROOTS), \ + $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm/$(HOTSPOT_TARGET_CPU).ad \ + $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm/$(HOTSPOT_TARGET_CPU_ARCH).ad \ + $d/os_cpu/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH)/vm/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH).ad \ + ))) + + SINGLE_AD_SRCFILE := $(ADLC_SUPPORT_DIR)/all-ad-src.ad + + INSERT_FILENAME_AWK_SCRIPT := \ + '{ \ + if (CUR_FN != FILENAME) { CUR_FN=FILENAME; NR_BASE=NR-1; need_lineno=1 } \ + if (need_lineno && $$0 !~ /\/\//) \ + { print "\n\n\#line " (NR-NR_BASE) " \"" FILENAME "\""; need_lineno=0 }; \ + print \ + }' + + $(SINGLE_AD_SRCFILE): $(AD_SRC_FILES) + $(call LogInfo, Preprocessing adlc files $(^F)) + $(call MakeDir, $(@D)) + $(NAWK) $(INSERT_FILENAME_AWK_SCRIPT) $^ > $@ + + ############################################################################## + # Run the adlc tool on the single concatenated ad source file, and store the + # output in support/adlc for further processing. + ADLC_RUN_MARKER := $(ADLC_SUPPORT_DIR)/_adlc_run.marker + + $(ADLC_RUN_MARKER): $(BUILD_ADLC) $(SINGLE_AD_SRCFILE) + $(call LogInfo, Generating adlc files) + $(call MakeDir, $(@D)) + $(call ExecuteWithLog, $(ADLC_SUPPORT_DIR)/adlc_run, \ + $(FIXPATH) $(ADLC_TOOL) $(ADLCFLAGS) $(SINGLE_AD_SRCFILE) \ + -c$(ADLC_SUPPORT_DIR)/ad_$(HOTSPOT_TARGET_CPU).cpp \ + -h$(ADLC_SUPPORT_DIR)/ad_$(HOTSPOT_TARGET_CPU).hpp \ + -a$(ADLC_SUPPORT_DIR)/dfa_$(HOTSPOT_TARGET_CPU).cpp \ + -v$(ADLC_SUPPORT_DIR)/adGlobals_$(HOTSPOT_TARGET_CPU).hpp) + $(TOUCH) $@ + + ############################################################################## + # Finally copy the generated files from support/adlc into gensrc/adfiles, + # and postprocess them by fixing dummy #line directives. + + ADLC_GENERATED_FILES := $(addprefix $(JVM_VARIANT_OUTPUTDIR)/gensrc/adfiles/, \ + ad_$(HOTSPOT_TARGET_CPU).cpp \ + ad_$(HOTSPOT_TARGET_CPU).hpp \ + ad_$(HOTSPOT_TARGET_CPU)_clone.cpp \ + ad_$(HOTSPOT_TARGET_CPU)_expand.cpp \ + ad_$(HOTSPOT_TARGET_CPU)_format.cpp \ + ad_$(HOTSPOT_TARGET_CPU)_gen.cpp \ + ad_$(HOTSPOT_TARGET_CPU)_misc.cpp \ + ad_$(HOTSPOT_TARGET_CPU)_peephole.cpp \ + ad_$(HOTSPOT_TARGET_CPU)_pipeline.cpp \ + adGlobals_$(HOTSPOT_TARGET_CPU).hpp \ + dfa_$(HOTSPOT_TARGET_CPU).cpp \ + ) + + $(JVM_VARIANT_OUTPUTDIR)/gensrc/adfiles/%: $(ADLC_RUN_MARKER) + $(call LogInfo, Postprocessing adlc file $*) + $(call MakeDir, $(@D)) + $(NAWK) \ + 'BEGIN { print "#line 1 \"$*\""; } \ + /^#line 999999$$/ {print "#line " (NR+1) " \"$*\""; next} \ + {print}' \ + < $(ADLC_SUPPORT_DIR)/$* > $@ + + TARGETS := $(ADLC_GENERATED_FILES) + +endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/gensrc/GensrcDtrace.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,56 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +################################################################################ +# Gensrc support for dtrace. The files generated here are included by dtrace.hpp + +ifeq ($(call check-jvm-feature, dtrace), true) + + ifeq ($(OPENJDK_TARGET_OS), solaris) + DTRACE_FLAGS := -64 + DTRACE_CPP_FLAGS := -D_LP64 + else ifeq ($(OPENJDK_TARGET_OS), macosx) + DTRACE_CPP_FLAGS := -D_LP64 -x c + else ifeq ($(OPENJDK_TARGET_OS), linux) + DTRACE_CPP_FLAGS := -x c + endif + + DTRACE_SOURCE_DIR := $(HOTSPOT_TOPDIR)/src/os/posix/dtrace + DTRACE_GENSRC_DIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/dtracefiles + + # Make sure we run our selected compiler for preprocessing instead of letting + # the dtrace tool pick it on it's own. + $(DTRACE_GENSRC_DIR)/%.h: $(DTRACE_SOURCE_DIR)/%.d + $(call LogInfo, Generating dtrace header file $(@F)) + $(call MakeDir, $(@D) $(DTRACE_SUPPORT_DIR)) + $(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d) + $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -h -o $@ -s $(DTRACE_SUPPORT_DIR)/$(@F).d) + + # Process all .d files in DTRACE_SOURCE_DIR. They are: + # hotspot_jni.d hotspot.d hs_private.d + TARGETS += $(patsubst $(DTRACE_SOURCE_DIR)/%.d, \ + $(DTRACE_GENSRC_DIR)/%.h, $(wildcard $(DTRACE_SOURCE_DIR)/*.d)) + +endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/gensrc/GensrcJvmti.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,174 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +$(eval $(call IncludeCustomExtension, hotspot, gensrc/GensrcJvmti.gmk)) + +################################################################################ +# Build tools needed for the JVMTI source code generation + +JVMTI_TOOLS_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/prims +JVMTI_TOOLS_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/tools/jvmti + +$(eval $(call SetupJavaCompiler, GENERATE_OLDBYTECODE, \ + JAVAC := $(JAVAC), \ + FLAGS := $(DISABLE_WARNINGS), \ + SERVER_DIR := $(SJAVAC_SERVER_DIR), \ + SERVER_JVM := $(SJAVAC_SERVER_JAVA), \ + DISABLE_SJAVAC := true, \ +)) + +$(eval $(call SetupJavaCompilation, BUILD_JVMTI_TOOLS, \ + SETUP := GENERATE_OLDBYTECODE, \ + SRC := $(JVMTI_TOOLS_SRCDIR), \ + INCLUDE_FILES := jvmtiGen.java jvmtiEnvFill.java, \ + BIN := $(JVMTI_TOOLS_OUTPUTDIR), \ +)) + +TOOL_JVMTI_GEN := $(JAVA_SMALL) -cp $(JVMTI_TOOLS_OUTPUTDIR) jvmtiGen +TOOL_JVMTI_ENV_FILL := $(JAVA_SMALL) -cp $(JVMTI_TOOLS_OUTPUTDIR) jvmtiEnvFill + +################################################################################ +# Setup make rules for an xml transform for jvmti/trace file generation. +# +# Parameter 1 is the name of the rule. This name is used as variable prefix, +# and the targets generated are listed in a variable by that name. This name is +# also used as the name of the output file. +# +# Remaining parameters are named arguments. These include: +# XML_FILE -- The input source file to use +# XSL_FILE -- The xsl file to use +# OUTPUT_DIR -- The directory to put the generated file in +# ARGS -- Additional arguments to the jvmtiGen tool +# DEPS -- Additional dependencies +SetupXslTransform = $(NamedParamsMacroTemplate) +define SetupXslTransformBody + $$($1_OUTPUT_DIR)/$1: $$($1_XML_FILE) $$($1_XSL_FILE) $$($1_DEPS) $$(BUILD_JVMTI_TOOLS) + $$(call LogInfo, Generating $$(@F)) + $$(call MakeDir, $$(@D)) + $$(call ExecuteWithLog, $$@, $$(TOOL_JVMTI_GEN) -IN $$($1_XML_FILE) -XSL $$($1_XSL_FILE) -OUT $$@ $$($1_ARGS)) + # jvmtiGen does not return error code properly on fail. + # NOTE: We should really fix jvmtiGen.java instead. + test -f $$@ + + TARGETS += $$($1_OUTPUT_DIR)/$1 +endef + +################################################################################ +# Create JVMTI files in gensrc/jvmtifiles + +JVMTI_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/prims +JVMTI_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles + +# Setup rule for generating a jvmti file +# +# $1 is generated source file name in $(JVMTI_OUTPUTDIR) +# $2 is XSL file to use in $(JVMTI_SRCDIR) +# $3 is optional extra arguments to jvmtiGen +define SetupJvmtiGeneration + $$(eval $$(call SetupXslTransform, $1, \ + XML_FILE := $$(JVMTI_SRCDIR)/jvmti.xml, \ + XSL_FILE := $$(JVMTI_SRCDIR)/$(strip $2), \ + OUTPUT_DIR := $$(JVMTI_OUTPUTDIR), \ + ARGS := $3, \ + DEPS := $$(JVMTI_SRCDIR)/jvmtiLib.xsl, \ + )) +endef + +$(eval $(call SetupJvmtiGeneration, jvmtiEnter.cpp, jvmtiEnter.xsl, \ + -PARAM interface jvmti)) +$(eval $(call SetupJvmtiGeneration, jvmtiEnterTrace.cpp, jvmtiEnter.xsl, \ + -PARAM interface jvmti -PARAM trace Trace)) +$(eval $(call SetupJvmtiGeneration, jvmtiEnv.hpp, jvmtiHpp.xsl)) +$(eval $(call SetupJvmtiGeneration, jvmti.h, jvmtiH.xsl)) +$(eval $(call SetupJvmtiGeneration, jvmti.html, jvmti.xsl)) +$(eval $(call SetupJvmtiGeneration, jvmtiEnvStub.cpp, jvmtiEnv.xsl)) + +JVMTI_BC_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/interpreter + +$(eval $(call SetupXslTransform, bytecodeInterpreterWithChecks.cpp, \ + XML_FILE := $(JVMTI_BC_SRCDIR)/bytecodeInterpreterWithChecks.xml, \ + XSL_FILE := $(JVMTI_BC_SRCDIR)/bytecodeInterpreterWithChecks.xsl, \ + OUTPUT_DIR := $(JVMTI_OUTPUTDIR), \ + DEPS := $(JVMTI_BC_SRCDIR)/bytecodeInterpreter.cpp, \ +)) + +# We need $(JVMTI_OUTPUTDIR)/jvmtiEnvStub.cpp (generated above) as input +$(JVMTI_OUTPUTDIR)/jvmtiEnvRecommended.cpp: $(JVMTI_SRCDIR)/jvmtiEnv.cpp \ + $(JVMTI_OUTPUTDIR)/jvmtiEnvStub.cpp $(BUILD_JVMTI_TOOLS) + $(call LogInfo, Generating $(@F)) + $(call MakeDir, $(@D)) + $(call ExecuteWithLog, $@, $(TOOL_JVMTI_ENV_FILL) $(JVMTI_SRCDIR)/jvmtiEnv.cpp \ + $(JVMTI_OUTPUTDIR)/jvmtiEnvStub.cpp \ + $(JVMTI_OUTPUTDIR)/jvmtiEnvRecommended.cpp) + # jvmtiEnvFill does not necessarily return an error code on failure. + # NOTE: We should really fix jvmtiEnvFill.java instead. + test -f $@ + +TARGETS += $(JVMTI_OUTPUTDIR)/jvmtiEnvRecommended.cpp + +################################################################################ +# Create trace files in gensrc/tracefiles + +TRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/tracefiles +TRACE_SRCDIR := $(HOTSPOT_TOPDIR)/src/share/vm/trace + +# Append directories to search (might have been set by custom extensions) +TRACE_SEARCH_DIRS += $(TRACE_SRCDIR) + +TRACE_XML ?= $(TRACE_SRCDIR)/trace.xml + +# Changing these will trigger a rebuild of generated trace files. +TRACE_DEPS += \ + $(TRACE_XML) \ + $(TRACE_SRCDIR)/tracetypes.xml \ + $(TRACE_SRCDIR)/tracerelationdecls.xml \ + $(TRACE_SRCDIR)/traceevents.xml \ + $(TRACE_SRCDIR)/trace.dtd \ + $(TRACE_SRCDIR)/xinclude.mod \ + # + +# Setup rule for generating a trace file +# +# $1 is generated source file name in $(TRACE_OUTPUTDIR) +define SetupTraceGeneration + $$(eval $$(call SetupXslTransform, $1, \ + XML_FILE := $$(TRACE_XML), \ + XSL_FILE := $$(firstword $$(wildcard $$(addsuffix /$$(basename $1).xsl, $$(TRACE_SEARCH_DIRS)))), \ + OUTPUT_DIR := $$(TRACE_OUTPUTDIR), \ + DEPS := $$(TRACE_DEPS), \ + )) +endef + +# Append files to generated (might have been set by custom extensions) +TRACE_GENSRC_FILES += \ + traceEventClasses.hpp \ + traceEventIds.hpp \ + traceTypes.hpp \ + # + +# Call SetupTraceGeneration for all trace gensrc files +$(foreach tracefile, $(TRACE_GENSRC_FILES), \ + $(eval $(call SetupTraceGeneration, $(tracefile))) \ +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/ide/CreateVSProject.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,153 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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 must be the first rule +default: all + +include $(SPEC) +include MakeBase.gmk +include JavaCompilation.gmk +include SetupJavaCompilers.gmk + +ifeq ($(OPENJDK_TARGET_OS), windows) + # The next part is a bit hacky. We include the CompileJvm.gmk to be + # able to extact flags, but we do not wish to execute the rules. + + # Use client as base for defines and includes + JVM_VARIANT=client + + include HotspotCommon.gmk + include lib/CompileJvm.gmk + + # Reset targets so we don't build libjvm. + TARGETS := + + # Helper macro to convert a unix path to a Windows path, suitable for + # inclusion in a command line. + FixPath = \ + $(strip $(subst \,\\,$(shell $(CYGPATH) -w $1))) + + JVM_DEFINES_client := $(patsubst -D%,%, $(filter -D%, $(JVM_CFLAGS))) + EXTRACTED_DEFINES_client := $(addprefix -define , $(JVM_DEFINES_client)) + + JVM_INCLUDES_client := $(patsubst -I%,%, $(filter -I%, $(JVM_CFLAGS))) + EXTRACTED_INCLUDES_client := $(foreach path, $(JVM_INCLUDES_client), -absoluteInclude $(call FixPath, $(path))) + + # Hand-code variant-specific arguments, based on the fact that we use + # client for general arguments. Not optimal but other solutions require + # major changes in ProjectCreator. + ADDITIONAL_VARIANT_ARGS := \ + -define_server COMPILER2 \ + -ignorePath_client adfiles \ + -ignorePath_client c2_ \ + -ignorePath_client runtime_ \ + -ignorePath_client libadt \ + -ignorePath_client opto \ + # + + IGNORED_PLATFORMS_ARGS := \ + -ignorePath aarch64 \ + -ignorePath aix \ + -ignorePath arm \ + -ignorePath bsd \ + -ignorePath linux \ + -ignorePath posix \ + -ignorePath ppc \ + -ignorePath shark \ + -ignorePath solaris \ + -ignorePath sparc \ + -ignorePath x86_32 \ + -ignorePath zero \ + # + + ################################################################################ + # Build the ProjectCreator java tool. + + TOOLS_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/support/tools_classes + + $(eval $(call SetupJavaCompilation, BUILD_PROJECT_CREATOR, \ + SETUP := GENERATE_OLDBYTECODE, \ + ADD_JAVAC_FLAGS := -Xlint:-auxiliaryclass, \ + SRC := $(HOTSPOT_TOPDIR)/makefiles/src/classes, \ + BIN := $(TOOLS_OUTPUTDIR), \ + )) + + TARGETS += $(BUILD_PROJECT_CREATOR) + + # Run the ProjectCreator tool + PROJECT_CREATOR_TOOL := $(JAVA_SMALL) -cp $(TOOLS_OUTPUTDIR) build.tools.projectcreator.ProjectCreator + + IDE_OUTPUTDIR := $(BUILD_OUTPUT)/ide/hotspot-visualstudio + + VCPROJ_FILE := $(IDE_OUTPUTDIR)/jvm.vcxproj + + PROJECT_CREATOR_CLASS := build.tools.projectcreator.WinGammaPlatformVC10 + + # We hard-code gensrc dir to server (since this includes adfiles) + PROJECT_CREATOR_ARGS := \ + -sourceBase $(call FixPath, $(HOTSPOT_TOPDIR)) \ + -startAt src \ + -relativeSrcInclude src \ + -hidePath .hg \ + -hidePath .jcheck \ + -hidePath jdk.hotspot.agent \ + -hidePath jdk.vm.ci \ + -hidePath jdk.jfr \ + -compiler VC10 \ + -jdkTargetRoot $(call FixPath, $(JDK_OUTPUTDIR)) \ + -platformName x64 \ + -buildBase $(call FixPath, $(IDE_OUTPUTDIR)/vs-output) \ + -buildSpace $(call FixPath, $(IDE_OUTPUTDIR)) \ + -makeBinary $(call FixPath, $(MAKE)) \ + -makeOutput $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-%f/libjvm) \ + -absoluteInclude $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-server/gensrc) \ + -absoluteSrcInclude $(call FixPath, $(HOTSPOT_OUTPUTDIR)/variant-server/gensrc) \ + $(EXTRACTED_DEFINES_client) \ + $(EXTRACTED_INCLUDES_client) \ + $(ADDITIONAL_VARIANT_ARGS) \ + $(IGNORED_PLATFORMS_ARGS) \ + # + + VCPROJ_VARDEPS := $(PROJECT_CREATOR_CLASS) $(PROJECT_CREATOR_ARGS) + VCPROJ_VARDEPS_FILE := $(call DependOnVariable, VCPROJ_VARDEPS, \ + $(VCPROJ_FILE).vardeps) + + $(VCPROJ_FILE): $(BUILD_PROJECT_CREATOR) $(VCPROJ_VARDEPS_FILE) + $(call MakeDir, $(@D)) + $(call ExecuteWithLog, $@, \ + $(PROJECT_CREATOR_TOOL) $(PROJECT_CREATOR_CLASS) \ + $(PROJECT_CREATOR_ARGS) -projectFileName $(call FixPath, $@)) \ + $(LOG_INFO) + + TARGETS += $(VCPROJ_FILE) + + all: $(TARGETS) + +else + all: + $(info Hotspot Visual Studio generation only supported on Windows) +endif + +.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/lib/CompileDtracePostJvm.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,217 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +################################################################################ +# Support for dtrace integration with libjvm, and stand-alone dtrace library +# compilation. + +ifeq ($(call check-jvm-feature, dtrace), true) + ############################################################################## + + ifeq ($(OPENJDK_TARGET_OS), solaris) + ############################################################################ + # Integrate with libjvm. Here we generate three object files which are + # linked with libjvm.so. This step is complicated from a dependency + # perspective, since it needs the rest of the compiled object files from the + # libjvm compilation, but the output is object files that are to be included + # when linking libjvm.so. So this generation must happen as a part of the + # libjvm compilation. + + # First we need to generate the dtraceGenOffsets tool. When run, this will + # produce more header files and a C++ file. + + # Note that generateJvmOffsets.cpp must be compiled as if it were a file + # in the libjvm.so, using JVM_CFLAGS as setup in CompileJvm.gmk. Otherwise + # this would preferrably have been done as a part of GensrcDtrace.gmk. + $(eval $(call SetupNativeCompilation, BUILD_DTRACE_GEN_OFFSETS, \ + SRC := $(HOTSPOT_TOPDIR)/src/os/$(OPENJDK_TARGET_OS)/dtrace, \ + INCLUDE_FILES := generateJvmOffsets.cpp generateJvmOffsetsMain.c, \ + CC := $(BUILD_CXX), \ + CXX := $(BUILD_CXX), \ + LDEXE := $(BUILD_CXX), \ + generateJvmOffsets.cpp_CXXFLAGS := $(JVM_CFLAGS) -mt -xnolib -norunpath, \ + generateJvmOffsetsMain.c_CFLAGS := -library=%none -mt -m64 -norunpath -z nodefs, \ + LDFLAGS := -m64, \ + LIBS := -lc, \ + OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets/objs, \ + OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets, \ + PROGRAM := dtraceGenOffsets, \ + )) + + DTRACE_GEN_OFFSETS_TOOL := $(BUILD_DTRACE_GEN_OFFSETS_TARGET) + + # Argument 1: Output filename + # Argument 2: dtrace-gen-offset tool command line option + define SetupDtraceOffsetsGeneration + $1: $$(BUILD_DTRACE_GEN_OFFSETS) + $$(call LogInfo, Generating dtrace $2 file $$(@F)) + $$(call MakeDir, $$(@D)) + $$(call ExecuteWithLog, $$@, $$(DTRACE_GEN_OFFSETS_TOOL) -$$(strip $2) > $$@) + + TARGETS += $1 + endef + + JVM_OFFSETS_H := $(DTRACE_SUPPORT_DIR)/JvmOffsets.h + JVM_OFFSETS_CPP := $(DTRACE_SUPPORT_DIR)/JvmOffsets.cpp + JVM_OFFSETS_INDEX_H := $(DTRACE_SUPPORT_DIR)/JvmOffsetsIndex.h + + # Run the dtrace-gen-offset tool to generate these three files. + $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_H), header)) + $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_INDEX_H), index)) + $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_CPP), table)) + + ############################################################################ + # Compile JVM_OFFSETS_OBJ which is linked with libjvm.so. + + # JvmOffsets.cpp is compiled without the common JVM_CFLAGS. Otherwise, the + # natural way would have been to included this source code in BUILD_LIBJVM. + JVM_OFFSETS_CFLAGS := -m64 + ifeq ($(OPENJDK_TARGET_CPU), sparcv9) + JVM_OFFSETS_CFLAGS += -xarch=sparc + endif + + $(JVM_OFFSETS_OBJ): $(JVM_OFFSETS_CPP) $(JVM_OFFSETS_H) + $(call LogInfo, Compiling dtrace file JvmOffsets.cpp (for libjvm.so)) + $(call ExecuteWithLog, $@, $(CXX) -c -I$(<D) -o $@ $(JVM_OFFSETS_CFLAGS) $<) + + ############################################################################ + # Generate DTRACE_OBJ which is linked with libjvm.so. + + # Concatenate all *.d files into a single file + DTRACE_SOURCE_FILES := $(addprefix $(HOTSPOT_TOPDIR)/src/os/posix/dtrace/, \ + hotspot_jni.d \ + hotspot.d \ + hs_private.d \ + ) + + $(JVM_OUTPUTDIR)/objs/dtrace.d: $(DTRACE_SOURCE_FILES) + $(call LogInfo, Generating $(@F)) + $(call MakeDir, $(@D)) + $(CAT) $^ > $@ + + DTRACE_INSTRUMENTED_OBJS := $(addprefix $(JVM_OUTPUTDIR)/objs/, \ + ciEnv.o \ + classLoadingService.o \ + compileBroker.o \ + hashtable.o \ + instanceKlass.o \ + java.o \ + jni.o \ + jvm.o \ + memoryManager.o \ + nmethod.o \ + objectMonitor.o \ + runtimeService.o \ + sharedRuntime.o \ + synchronizer.o \ + thread.o \ + unsafe.o \ + vmThread.o \ + vmGCOperations.o \ + ) + + ifeq ($(call check-jvm-feature, all-gcs), true) + DTRACE_INSTRUMENTED_OBJS += $(addprefix $(JVM_OUTPUTDIR)/objs/, \ + vmCMSOperations.o \ + vmPSOperations.o \ + ) + endif + + DTRACE_FLAGS := -64 -G + DTRACE_CPP_FLAGS := -D_LP64 + + # Make sure we run our selected compiler for preprocessing instead of letting + # the dtrace tool pick it on it's own. + $(DTRACE_OBJ): $(JVM_OUTPUTDIR)/objs/dtrace.d $(DTRACE_INSTRUMENTED_OBJS) + $(call LogInfo, Generating $(@F) from $(<F) and object files) + $(call MakeDir, $(DTRACE_SUPPORT_DIR)) + $(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E \ + $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d) + $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -xlazyload -o $@ \ + -s $(DTRACE_SUPPORT_DIR)/$(@F).d $(sort $(DTRACE_INSTRUMENTED_OBJS))) + + ############################################################################ + # Generate DTRACE_JHELPER_OBJ which is linked with libjvm.so. + + # Unfortunately dtrace generates incorrect types for some symbols in + # dtrace_jhelper.o, resulting in "warning: symbol X has differing types" + # This is tracked in JDK-6890703. + $(DTRACE_JHELPER_OBJ): $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace/jhelper.d \ + $(JVM_OFFSETS_INDEX_H) + $(call LogInfo, Running dtrace for $(<F)) + $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) $(DTRACE_CPP_FLAGS) -C \ + -I$(DTRACE_SUPPORT_DIR) -o $@ -s $<) + + # NOTE: We should really do something like this, but unfortunately this + # results in a compilation error. :-( + # $(call MakeDir, $(DTRACE_SUPPORT_DIR)) + # $(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E \ + # $(DTRACE_CPP_FLAGS) -I$(DTRACE_SUPPORT_DIR) $^ \ + # > $(DTRACE_SUPPORT_DIR)/$(@F).d) + # $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -o $@ \ + # -s $(DTRACE_SUPPORT_DIR)/$(@F).d) + + ############################################################################ + # Build the stand-alone dtrace libraries + + LIBJVM_DTRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_dtrace + + $(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DTRACE, \ + LIBRARY := jvm_dtrace, \ + OUTPUT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR), \ + SRC := $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace, \ + INCLUDE_FILES := jvm_dtrace.c, \ + CFLAGS := -m64 -G -mt -KPIC, \ + LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \ + LIBS := $(LIBDL) -lc -lthread -ldoor, \ + MAPFILE := $(HOTSPOT_TOPDIR)/makefiles/mapfiles/libjvm_dtrace/mapfile-vers, \ + OBJECT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR)/objs, \ + STRIP_SYMBOLS := true, \ + )) + + LIBJVM_DB_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_db + + # Note that libjvm_db.c has tests for COMPILER2, but this was never set by + # the old build. + $(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DB, \ + LIBRARY := jvm_db, \ + OUTPUT_DIR := $(LIBJVM_DB_OUTPUTDIR), \ + SRC := $(HOTSPOT_TOPDIR)/src/os/solaris/dtrace, \ + INCLUDE_FILES := libjvm_db.c, \ + CFLAGS := -I$(JVM_VARIANT_OUTPUTDIR)/gensrc -I$(DTRACE_SUPPORT_DIR) \ + -m64 -G -mt -KPIC, \ + LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \ + LIBS := -lc, \ + MAPFILE := $(HOTSPOT_TOPDIR)/makefiles/mapfiles/libjvm_db/mapfile-vers, \ + OBJECT_DIR := $(LIBJVM_DB_OUTPUTDIR)/objs, \ + STRIP_SYMBOLS := true, \ + )) + + # We need the generated JvmOffsets.h before we can compile the libjvm_db source code. + $(BUILD_LIBJVM_DB_ALL_OBJS): $(JVM_OFFSETS_H) + + TARGETS += $(BUILD_LIBJVM_DTRACE) $(BUILD_LIBJVM_DB) + endif +endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/lib/CompileDtracePreJvm.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,36 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +ifeq ($(call check-jvm-feature, dtrace), true) + ifeq ($(OPENJDK_TARGET_OS), solaris) + # These files are are generated by CompileDtrace.gmk but consumed by + # CompileJvm.gmk + DTRACE_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace.o + DTRACE_JHELPER_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace_jhelper.o + JVM_OFFSETS_OBJ := $(JVM_OUTPUTDIR)/objs/JvmOffsets.o + + DTRACE_EXTRA_OBJECT_FILES := $(DTRACE_OBJ) $(DTRACE_JHELPER_OBJ) $(JVM_OFFSETS_OBJ) + endif +endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/lib/CompileJvm.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,242 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# Include support files that will setup compiler flags due to the selected +# jvm feature set, and specific file overrides. +include lib/JvmFeatures.gmk +include lib/JvmOverrideFiles.gmk + +$(eval $(call IncludeCustomExtension, hotspot, lib/CompileJvm.gmk)) + +################################################################################ +# Setup compilation of the main Hotspot native library (libjvm). + +JVM_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm +JVM_MAPFILE := $(JVM_OUTPUTDIR)/mapfile + +################################################################################ +# Platform independent setup + +# This variable may be added to by a custom extension +JVM_SRC_ROOTS += $(HOTSPOT_TOPDIR)/src + +JVM_SRC_DIRS += $(call uniq, $(wildcard $(foreach d, $(JVM_SRC_ROOTS), \ + $d/share/vm \ + $d/os/$(HOTSPOT_TARGET_OS)/vm \ + $d/os/$(HOTSPOT_TARGET_OS_TYPE)/vm \ + $d/cpu/$(HOTSPOT_TARGET_CPU_ARCH)/vm \ + $d/os_cpu/$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH)/vm \ + ))) \ + $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles \ + $(JVM_VARIANT_OUTPUTDIR)/gensrc/tracefiles \ + # + +JVM_CFLAGS_INCLUDES += \ + $(patsubst %,-I%,$(filter-out $(JVM_VARIANT_OUTPUTDIR)/gensrc/%, $(JVM_SRC_DIRS))) \ + -I$(JVM_VARIANT_OUTPUTDIR)/gensrc \ + -I$(HOTSPOT_TOPDIR)/src/share/vm/precompiled \ + -I$(HOTSPOT_TOPDIR)/src/share/vm/prims \ + # + +JVM_CFLAGS_TARGET_DEFINES += \ + -DTARGET_OS_FAMILY_$(HOTSPOT_TARGET_OS) \ + -DTARGET_ARCH_MODEL_$(HOTSPOT_TARGET_CPU) \ + -DTARGET_ARCH_$(HOTSPOT_TARGET_CPU_ARCH) \ + -DTARGET_OS_ARCH_MODEL_$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU) \ + -DTARGET_OS_ARCH_$(HOTSPOT_TARGET_OS)_$(HOTSPOT_TARGET_CPU_ARCH) \ + -DTARGET_COMPILER_$(HOTSPOT_TOOLCHAIN_TYPE) \ + -D$(HOTSPOT_TARGET_CPU_DEFINE) \ + -DHOTSPOT_LIB_ARCH='"$(OPENJDK_TARGET_CPU_LEGACY_LIB)"' \ + # + +ifeq ($(DEBUG_LEVEL), release) + # For hotspot, release builds differ internally between "optimized" and "product" + # in that "optimize" does not define PRODUCT. + ifneq ($(HOTSPOT_DEBUG_LEVEL), optimized) + JVM_CFLAGS_DEBUGLEVEL := -DPRODUCT + endif +else ifeq ($(DEBUG_LEVEL), fastdebug) + JVM_CFLAGS_DEBUGLEVEL := -DASSERT + ifeq ($(filter $(OPENJDK_TARGET_OS), windows aix), ) + # NOTE: Old build did not define CHECK_UNHANDLED_OOPS on Windows and AIX. + JVM_CFLAGS_DEBUGLEVEL += -DCHECK_UNHANDLED_OOPS + endif +else ifeq ($(DEBUG_LEVEL), slowdebug) + # _NMT_NOINLINE_ informs NMT that no inlining is done by the compiler + JVM_CFLAGS_DEBUGLEVEL := -DASSERT -D_NMT_NOINLINE_ +endif + +JVM_CFLAGS += \ + $(JVM_CFLAGS_DEBUGLEVEL) \ + $(JVM_CFLAGS_TARGET_DEFINES) \ + $(JVM_CFLAGS_FEATURES) \ + $(JVM_CFLAGS_INCLUDES) \ + $(EXTRA_CFLAGS) \ + # + +JVM_LDFLAGS += \ + $(SHARED_LIBRARY_FLAGS) \ + $(JVM_LDFLAGS_FEATURES) \ + $(EXTRA_LDFLAGS) \ + # + +JVM_LIBS += \ + $(JVM_LIBS_FEATURES) \ + # + +# These files and directories are always excluded +JVM_EXCLUDE_FILES += jsig.c jvmtiEnvRecommended.cpp jvmtiEnvStub.cpp args.cc +JVM_EXCLUDES += adlc + +# Needed by vm_version.cpp +ifeq ($(OPENJDK_TARGET_CPU), x86_64) + OPENJDK_TARGET_CPU_VM_VERSION := amd64 +else ifeq ($(OPENJDK_TARGET_CPU), sparcv9) + OPENJDK_TARGET_CPU_VM_VERSION := sparc +else + OPENJDK_TARGET_CPU_VM_VERSION := $(OPENJDK_TARGET_CPU) +endif + +CFLAGS_VM_VERSION := \ + $(VERSION_CFLAGS) \ + -DHOTSPOT_VERSION_STRING='"$(VERSION_STRING)"' \ + -DDEBUG_LEVEL='"$(DEBUG_LEVEL)"' \ + -DHOTSPOT_BUILD_USER='"$(USERNAME)"' \ + -DHOTSPOT_VM_DISTRO='"$(HOTSPOT_VM_DISTRO)"' \ + -DCPU='"$(OPENJDK_TARGET_CPU_VM_VERSION)"' \ + # + +# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp. +ifeq ($(USE_PRECOMPILED_HEADER), 0) + JVM_CFLAGS += -DDONT_USE_PRECOMPILED_HEADER +endif + +################################################################################ +# Platform specific setup + +ifneq ($(filter $(OPENJDK_TARGET_OS), linux macosx windows), ) + JVM_PRECOMPILED_HEADER := $(HOTSPOT_TOPDIR)/src/share/vm/precompiled/precompiled.hpp +endif + +ifneq ($(filter $(OPENJDK_TARGET_OS), macosx aix solaris), ) + # On macosx, aix and solaris we have to link with the C++ compiler + JVM_TOOLCHAIN := TOOLCHAIN_LINK_CXX +else + JVM_TOOLCHAIN := TOOLCHAIN_DEFAULT +endif + +ifeq ($(OPENJDK_TARGET_CPU), x86) + JVM_EXCLUDE_PATTERNS += x86_64 +else ifeq ($(OPENJDK_TARGET_CPU), x86_64) + JVM_EXCLUDE_PATTERNS += x86_32 +endif + +# Inline assembly for solaris +ifeq ($(OPENJDK_TARGET_OS), solaris) + ifeq ($(OPENJDK_TARGET_CPU), x86_64) + JVM_CFLAGS += $(HOTSPOT_TOPDIR)/src/os_cpu/solaris_x86/vm/solaris_x86_64.il + else ifeq ($(OPENJDK_TARGET_CPU), sparcv9) + JVM_CFLAGS += $(HOTSPOT_TOPDIR)/src/os_cpu/solaris_sparc/vm/solaris_sparc.il + endif +endif + +ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), solaris-sparcv9) + ifeq ($(COMPILE_WITH_DEBUG_SYMBOLS), false) + # NOTE: In the old build, we weirdly enough set -g/-g0 always, regardless + # of if debug symbols were needed. Without it, compilation fails on + # sparc! :-( + JVM_CFLAGS += -g0 + endif +endif + +ifeq ($(OPENJDK_TARGET_OS), windows) + ifeq ($(OPENJDK_TARGET_CPU_BITS), 64) + RC_DESC := 64-Bit$(SPACE) + endif + JVM_RCFLAGS += -D"HS_FILEDESC=$(HOTSPOT_VM_DISTRO) $(RC_DESC)$(JVM_VARIANT) VM" +endif + +ifeq ($(OPENJDK_TARGET_OS), macosx) + # NOTE: The old build did not strip binaries on macosx. + JVM_STRIP_SYMBOLS := false +else + JVM_STRIP_SYMBOLS := true +endif + +JVM_OPTIMIZATION ?= HIGHEST_JVM + +################################################################################ +# Now set up the actual compilation of the main hotspot native library + +$(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \ + TOOLCHAIN := $(JVM_TOOLCHAIN), \ + LIBRARY := jvm, \ + OUTPUT_DIR := $(JVM_OUTPUTDIR), \ + SRC := $(JVM_SRC_DIRS), \ + EXCLUDES := $(JVM_EXCLUDES), \ + EXCLUDE_FILES := $(JVM_EXCLUDE_FILES), \ + EXCLUDE_PATTERNS := $(JVM_EXCLUDE_PATTERNS), \ + EXTRA_OBJECT_FILES := $(DTRACE_EXTRA_OBJECT_FILES), \ + CFLAGS := $(JVM_CFLAGS), \ + CFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \ + CXXFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \ + vm_version.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \ + DISABLED_WARNINGS_clang := delete-non-virtual-dtor dynamic-class-memaccess \ + empty-body format logical-op-parentheses parentheses \ + parentheses-equality switch tautological-compare, \ + DISABLED_WARNINGS_xlc := 1540-0216 1540-0198 1540-1090 1540-1639 \ + 1540-1088 1500-010, \ + ASFLAGS := $(JVM_ASFLAGS), \ + LDFLAGS := $(JVM_LDFLAGS), \ + LIBS := $(JVM_LIBS), \ + OPTIMIZATION := $(JVM_OPTIMIZATION), \ + OBJECT_DIR := $(JVM_OUTPUTDIR)/objs, \ + MAPFILE := $(JVM_MAPFILE), \ + USE_MAPFILE_FOR_SYMBOLS := true, \ + STRIP_SYMBOLS := $(JVM_STRIP_SYMBOLS), \ + EMBED_MANIFEST := true, \ + RC_FLAGS := $(JVM_RCFLAGS), \ + VERSIONINFO_RESOURCE := $(HOTSPOT_TOPDIR)/src/os/windows/vm/version.rc, \ + PRECOMPILED_HEADER := $(JVM_PRECOMPILED_HEADER), \ + PRECOMPILED_HEADER_EXCLUDE := $(JVM_PRECOMPILED_HEADER_EXCLUDE), \ +)) + +# AIX warning explanation: +# 1500-010 : (W) WARNING in ...: Infinite loop. Program may not stop. +# There are several infinite loops in the vm, so better suppress. +# 1540-0198 : (W) The omitted keyword "private" is assumed for base class "...". +# 1540-0216 : (W) An expression of type .. cannot be converted to type .. +# In hotspot this fires for functionpointer to pointer conversions +# 1540-1088 : (W) The exception specification is being ignored. +# In hotspot this is caused by throw() in declaration of new() in nmethod.hpp. +# 1540-1090 : (I) The destructor of "..." might not be called. +# 1540-1639 : (I) The behavior of long type bit fields has changed ... + +# Include mapfile generation. It relies on BUILD_LIBJVM_ALL_OBJS which is only +# defined after the above call to BUILD_LIBJVM. Mapfile will be generated +# after all object files are built, but before the jvm library is linked. +include lib/JvmMapfile.gmk + +TARGETS += $(BUILD_LIBJVM)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/lib/CompileLibjsig.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,106 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +################################################################################ +# Create the libjsig.so shared library + +default: all + +include $(SPEC) +include MakeBase.gmk +include NativeCompilation.gmk + +ifneq ($(OPENJDK_TARGET_OS), windows) + ifeq ($(STATIC_BUILD), false) + LIBJSIG_STRIP_SYMBOLS := true + ifeq ($(OPENJDK_TARGET_OS), linux) + LIBJSIG_CFLAGS := -fPIC -D_GNU_SOURCE -D_REENTRANT $(EXTRA_CFLAGS) + LIBJSIG_LDFLAGS := $(LDFLAGS_HASH_STYLE) $(EXTRA_CFLAGS) + LIBJSIG_LIBS := $(LIBDL) + + # NOTE: The old build compiled this library without -soname. + # To emulate this, we need to clear out SET_SHARED_LIBRARY_NAME. + SET_SHARED_LIBRARY_NAME := + + # Flags for other CPUs can be provided in EXTRA_CFLAGS + ifeq ($(OPENJDK_TARGET_CPU), x86_64) + LIBJSIG_CPU_FLAGS := -m64 + else ifeq ($(OPENJDK_TARGET_CPU), x86) + LIBJSIG_CPU_FLAGS := -m32 -march=i586 + endif + + else ifeq ($(OPENJDK_TARGET_OS), solaris) + LIBJSIG_CFLAGS := -m64 -KPIC -mt + LIBJSIG_LDFLAGS := -m64 -mt -xnolib + LIBJSIG_LIBS := $(LIBDL) + + # NOTE: The old build compiled this library without -soname. + # To emulate this, we need to clear out SET_SHARED_LIBRARY_NAME. + SET_SHARED_LIBRARY_NAME := + + else ifeq ($(OPENJDK_TARGET_OS), aix) + LIBJSIG_CFLAGS := -q64 -D_GNU_SOURCE -D_REENTRANT -qpic=large + LIBJSIG_LDFLAGS := -b64 -bexpall -G -bnoentry -qmkshrobj -brtl -bnolibpath -bernotok + LIBJSIG_LIBS := $(LIBDL) + + # NOTE: The old build compiled this library without -soname. + # To emulate this, we need to clear out SET_SHARED_LIBRARY_NAME. + SET_SHARED_LIBRARY_NAME := + + else ifeq ($(OPENJDK_TARGET_OS), macosx) + LIBJSIG_CFLAGS := -m64 -D_GNU_SOURCE -pthread -mno-omit-leaf-frame-pointer -mstack-alignment=16 -fPIC + LIBJSIG_LDFLAGS := $(LDFLAGS_HASH_STYLE) + # NOTE: This lib is not stripped on macosx in old build. Looks like a mistake. + LIBJSIG_STRIP_SYMBOLS := false + else + $(error Unknown target OS $(OPENJDK_TARGET_OS) in CompileLibjsig.gmk) + endif + + LIBJSIG_SRC_FILE := $(HOTSPOT_TOPDIR)/src/os/$(HOTSPOT_TARGET_OS)/vm/jsig.c + LIBJSIG_MAPFILE := $(wildcard $(HOTSPOT_TOPDIR)/makefiles/mapfiles/libjsig/mapfile-vers-$(OPENJDK_TARGET_OS)) + LIBJSIG_OUTPUTDIR := $(HOTSPOT_OUTPUTDIR)/libjsig + + LIBJSIG_LDFLAGS += $(SHARED_LIBRARY_FLAGS) + + $(eval $(call SetupNativeCompilation, BUILD_LIBJSIG, \ + LIBRARY := jsig, \ + EXTRA_FILES := $(LIBJSIG_SRC_FILE), \ + OUTPUT_DIR := $(LIBJSIG_OUTPUTDIR), \ + LANG := C, \ + CFLAGS := $(LIBJSIG_CFLAGS) $(LIBJSIG_CPU_FLAGS), \ + LDFLAGS := $(LIBJSIG_LDFLAGS) $(LIBJSIG_CPU_FLAGS), \ + LIBS := $(LIBJSIG_LIBS), \ + MAPFILE := $(LIBJSIG_MAPFILE), \ + OBJECT_DIR := $(LIBJSIG_OUTPUTDIR)/objs, \ + STRIP_SYMBOLS := $(LIBJSIG_STRIP_SYMBOLS), \ + )) + + TARGETS += $(BUILD_LIBJSIG) + endif +endif + +all: $(TARGETS) + +.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/lib/CompileLibraries.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,42 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +default: all + +include $(SPEC) +include MakeBase.gmk +include NativeCompilation.gmk + +include HotspotCommon.gmk + +# The dtrace setup must be done both before and after CompileJvm.gmk, due to +# intricate dependencies. +include lib/CompileDtracePreJvm.gmk +include lib/CompileJvm.gmk +include lib/CompileDtracePostJvm.gmk + +all: $(TARGETS) + +.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/lib/JvmFeatures.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,144 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +$(eval $(call IncludeCustomExtension, hotspot, lib/JvmFeatures.gmk)) + +################################################################################ +# Setup CFLAGS and EXCLUDES for the libjvm compilation, depending on which +# jvm features are selected for this jvm variant. + +ifeq ($(call check-jvm-feature, compiler1), true) + JVM_CFLAGS_FEATURES += -DCOMPILER1 +else + JVM_EXCLUDE_PATTERNS += c1_ +endif + +ifeq ($(call check-jvm-feature, compiler2), true) + JVM_CFLAGS_FEATURES += -DCOMPILER2 + JVM_SRC_DIRS += $(JVM_VARIANT_OUTPUTDIR)/gensrc/adfiles +else + JVM_EXCLUDES += opto libadt + JVM_EXCLUDE_FILES += bcEscapeAnalyzer.cpp ciTypeFlow.cpp + JVM_EXCLUDE_PATTERNS += c2_ runtime_ +endif + +ifeq ($(call check-jvm-feature, zero), true) + JVM_CFLAGS_FEATURES += -DZERO -DCC_INTERP -DZERO_LIBARCH='"$(OPENJDK_TARGET_CPU_LEGACY_LIB)"' $(LIBFFI_CFLAGS) + JVM_LIBS_FEATURES += $(LIBFFI_LIBS) +endif + +ifeq ($(call check-jvm-feature, shark), true) + JVM_CFLAGS_FEATURES += -DSHARK $(LLVM_CFLAGS) + JVM_LDFLAGS_FEATURES += $(LLVM_LDFLAGS) + JVM_LIBS_FEATURES += $(LLVM_LIBS) +else + JVM_EXCLUDES += shark +endif + +ifeq ($(call check-jvm-feature, minimal), true) + JVM_CFLAGS_FEATURES += -DMINIMAL_JVM -DVMTYPE=\"Minimal\" +endif + +ifeq ($(call check-jvm-feature, dtrace), true) + JVM_CFLAGS_FEATURES += -DDTRACE_ENABLED +endif + +ifeq ($(call check-jvm-feature, static-build), true) + JVM_CFLAGS_FEATURES += -DSTATIC_BUILD=1 +endif + +ifneq ($(call check-jvm-feature, jvmti), true) + JVM_CFLAGS_FEATURES += -DINCLUDE_JVMTI=0 + JVM_EXCLUDE_FILES += jvmtiGetLoadedClasses.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \ + jvmtiImpl.cpp jvmtiManageCapabilities.cpp jvmtiRawMonitor.cpp jvmtiUtil.cpp jvmtiTrace.cpp \ + jvmtiCodeBlobEvents.cpp jvmtiEnv.cpp jvmtiRedefineClasses.cpp jvmtiEnvBase.cpp jvmtiEnvThreadState.cpp \ + jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp \ + jvmtiClassFileReconstituter.cpp +endif + +ifneq ($(call check-jvm-feature, jvmci), true) + JVM_CFLAGS_FEATURES += -DINCLUDE_JVMCI=0 + JVM_EXCLUDES += jvmci + JVM_EXCLUDE_FILES += jvmciCodeInstaller_$(HOTSPOT_TARGET_CPU_ARCH).cpp +endif + +ifneq ($(call check-jvm-feature, fprof), true) + JVM_CFLAGS_FEATURES += -DINCLUDE_FPROF=0 + JVM_EXCLUDE_FILES += fprofiler.cpp +endif + +ifneq ($(call check-jvm-feature, vm-structs), true) + JVM_CFLAGS_FEATURES += -DINCLUDE_VM_STRUCTS=0 + JVM_EXCLUDE_FILES += vmStructs.cpp +endif + +ifneq ($(call check-jvm-feature, jni-check), true) + JVM_CFLAGS_FEATURES += -DINCLUDE_JNI_CHECK=0 + JVM_EXCLUDE_FILES += jniCheck.cpp +endif + +ifneq ($(call check-jvm-feature, services), true) + JVM_CFLAGS_FEATURES += -DINCLUDE_SERVICES=0 + JVM_EXCLUDE_FILES += heapDumper.cpp heapInspection.cpp \ + attachListener_$(HOTSPOT_TARGET_OS).cpp attachListener.cpp +endif + +ifneq ($(call check-jvm-feature, management), true) + JVM_CFLAGS_FEATURES += -DINCLUDE_MANAGEMENT=0 +endif + +ifneq ($(call check-jvm-feature, cds), true) + JVM_CFLAGS_FEATURES += -DINCLUDE_CDS=0 + JVM_EXCLUDE_FILES += \ + classListParser.cpp \ + classLoaderExt.cpp \ + filemap.cpp \ + metaspaceShared.cpp \ + metaspaceShared_$(HOTSPOT_TARGET_CPU).cpp \ + metaspaceShared_$(HOTSPOT_TARGET_CPU_ARCH).cpp \ + sharedClassUtil.cpp \ + sharedPathsMiscInfo.cpp \ + systemDictionaryShared.cpp \ + # +endif + +ifneq ($(call check-jvm-feature, all-gcs), true) + JVM_CFLAGS_FEATURES += -DINCLUDE_ALL_GCS=0 + JVM_EXCLUDE_PATTERNS += \ + cms/ g1/ parallel/ + JVM_EXCLUDE_FILES += \ + concurrentGCThread.cpp \ + plab.cpp + JVM_EXCLUDE_FILES += \ + g1MemoryPool.cpp \ + psMemoryPool.cpp +endif + +ifneq ($(call check-jvm-feature, nmt), true) + JVM_CFLAGS_FEATURES += -DINCLUDE_NMT=0 + JVM_EXCLUDE_FILES += \ + memBaseline.cpp memReporter.cpp mallocTracker.cpp virtualMemoryTracker.cpp nmtCommon.cpp \ + memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp +endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/lib/JvmMapfile.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,172 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +$(eval $(call IncludeCustomExtension, hotspot, lib/JvmMapfile.gmk)) + +################################################################################ +# Combine a list of static symbols + +ifneq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU), windows-x86_64) + # On Windows x86_64, we should not have any symbols at all, since that + # results in duplicate warnings from the linker (JDK-8043491). + SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-shared +endif + +ifeq ($(OPENJDK_TARGET_OS_TYPE), unix) + SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-unix +endif + +ifneq ($(wildcard $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS)), ) + SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS) +endif + +ifneq ($(findstring debug, $(DEBUG_LEVEL)), ) + ifneq ($(wildcard $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS)-debug), ) + SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-$(OPENJDK_TARGET_OS)-debug + endif +endif + +ifeq ($(OPENJDK_TARGET_OS), solaris) + ifeq ($(call check-jvm-feature, dtrace), true) + # Additional mapfiles that are only used when dtrace is enabled + ifeq ($(call check-jvm-feature, compiler2), true) + # This also covers the case of compiler1+compiler2. + SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-solaris-dtrace-compiler2 + else ifeq ($(call check-jvm-feature, compiler1), true) + SYMBOLS_SRC += $(HOTSPOT_TOPDIR)/makefiles/symbols/symbols-solaris-dtrace-compiler1 + endif + endif +endif + +################################################################################ +# Create a dynamic list of symbols from the built object files. This is highly +# platform dependent. + +ifeq ($(OPENJDK_TARGET_OS), linux) + DUMP_SYMBOLS_CMD := $(NM) --defined-only *.o + ifneq ($(FILTER_SYMBOLS_PATTERN), ) + FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)| + endif + FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)^_ZTV|^gHotSpotVM|^UseSharedSpaces$$ + FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|^_ZN9Arguments17SharedArchivePathE$$ + FILTER_SYMBOLS_AWK_SCRIPT := \ + '{ \ + if ($$3 ~ /$(FILTER_SYMBOLS_PATTERN)/) print $$3; \ + }' + +else ifeq ($(OPENJDK_TARGET_OS), solaris) + DUMP_SYMBOLS_CMD := $(NM) -p *.o + ifneq ($(FILTER_SYMBOLS_PATTERN), ) + FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)| + endif + FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)^__1c.*__vtbl_$$|^gHotSpotVM + FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|^UseSharedSpaces$$ + FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|^__1cJArgumentsRSharedArchivePath_$$ + FILTER_SYMBOLS_AWK_SCRIPT := \ + '{ \ + if ($$2 == "U") next; \ + if ($$3 ~ /$(FILTER_SYMBOLS_PATTERN)/) print $$3; \ + }' + +else ifeq ($(OPENJDK_TARGET_OS), macosx) + # nm on macosx prints out "warning: nm: no name list" to stderr for + # files without symbols. Hide this, even at the expense of hiding real errors. + DUMP_SYMBOLS_CMD := $(NM) -Uj *.o 2> /dev/null + ifneq ($(FILTER_SYMBOLS_PATTERN), ) + FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)| + endif + FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)^_ZTV|^gHotSpotVM + FILTER_SYMBOLS_AWK_SCRIPT := \ + '{ \ + if ($$3 ~ /$(FILTER_SYMBOLS_PATTERN)/) print $$3; \ + }' + +# NOTE: The script is from the old build. It is broken and finds no symbols. +# The script below might be what was intended, but it failes to link with tons +# of 'cannot export hidden symbol vtable for X'. +# '{ if ($$1 ~ /^__ZTV/ || $$1 ~ /^_gHotSpotVM/) print substr($$1, 2) }' +else ifeq ($(OPENJDK_TARGET_OS), aix) + # NOTE: The old build had the solution below. This should to be fixed in + # configure instead. + + # On AIX we have to prevent that we pick up the 'nm' version from the GNU binutils + # which may be installed under /opt/freeware/bin. So better use an absolute path here! + # NM=/usr/bin/nm + + DUMP_SYMBOLS_CMD := $(NM) -X64 -B -C *.o + FILTER_SYMBOLS_AWK_SCRIPT := \ + '{ \ + if (($$2="d" || $$2="D") && ($$3 ~ /^__vft/ || $$3 ~ /^gHotSpotVM/)) print $$3; \ + if ($$3 ~ /^UseSharedSpaces$$/) print $$3; \ + if ($$3 ~ /^SharedArchivePath__9Arguments$$/) print $$3; \ + }' + +else ifeq ($(OPENJDK_TARGET_OS), windows) + DUMP_SYMBOLS_CMD := $(DUMPBIN) -symbols *.obj + FILTER_SYMBOLS_AWK_SCRIPT := \ + '{ \ + if ($$7 ~ /??_7.*@@6B@/ && $$7 !~ /type_info/) print $$7; \ + }' + +else + $(error Unknown target OS $(OPENJDK_TARGET_OS) in JvmMapfile.gmk) +endif + +# A more correct solution would be to send BUILD_LIBJVM_ALL_OBJS instead of +# cd && *.o, but this will result in very long command lines, which is +# problematic on some platforms. +$(JVM_OUTPUTDIR)/symbols-objects: $(BUILD_LIBJVM_ALL_OBJS) + $(call LogInfo, Generating symbol list from object files) + $(CD) $(JVM_OUTPUTDIR)/objs && \ + $(DUMP_SYMBOLS_CMD) | $(NAWK) $(FILTER_SYMBOLS_AWK_SCRIPT) | $(SORT) -u > $@ + +SYMBOLS_SRC += $(JVM_OUTPUTDIR)/symbols-objects + +################################################################################ +# Now concatenate all symbol lists into a single file and remove comments. + +$(JVM_OUTPUTDIR)/symbols: $(SYMBOLS_SRC) + $(SED) -e '/^#/d' $^ > $@ + +################################################################################ +# Finally convert the symbol list into a platform-specific mapfile + +$(JVM_MAPFILE): $(JVM_OUTPUTDIR)/symbols + $(call LogInfo, Creating mapfile) + $(RM) $@ + ifeq ($(OPENJDK_TARGET_OS), macosx) + # On macosx, we need to add a leading underscore + $(AWK) '{ if ($$0 ~ ".") { print " _" $$0 } }' < $^ > $@.tmp + else ifeq ($(OPENJDK_TARGET_OS), windows) + # On windows, add an 'EXPORTS' header + $(ECHO) "EXPORTS" > $@.tmp + $(AWK) '{ if ($$0 ~ ".") { print " " $$0 } }' < $^ >> $@.tmp + else + # Assume standard linker script + $(PRINTF) "SUNWprivate_1.1 { \n global: \n" > $@.tmp + $(AWK) '{ if ($$0 ~ ".") { print " " $$0 ";" } }' < $^ >> $@.tmp + $(PRINTF) " local: \n *; \n }; \n" >> $@.tmp + endif + $(MV) $@.tmp $@
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/lib/JvmOverrideFiles.gmk Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,168 @@ +# +# Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. 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. +# + +$(eval $(call IncludeCustomExtension, hotspot, lib/JvmOverrideFiles.gmk)) + +################################################################################ +# This file contains explicit overrides of CFLAGS and/or precompiled header +# status for individual files on specific platforms. + +ifeq ($(TOOLCHAIN_TYPE), gcc) + BUILD_LIBJVM_vmStructs.cpp_CXXFLAGS := -fno-var-tracking-assignments -O0 +endif + +ifeq ($(OPENJDK_TARGET_OS), linux) + BUILD_LIBJVM_ostream.cpp_CXXFLAGS := -D_FILE_OFFSET_BITS=64 + + ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86) + BUILD_LIBJVM_sharedRuntimeTrig.cpp_CXXFLAGS := -DNO_PCH $(CXX_O_FLAG_NONE) + BUILD_LIBJVM_sharedRuntimeTrans.cpp_CXXFLAGS := -DNO_PCH $(CXX_O_FLAG_NONE) + + ifeq ($(TOOLCHAIN_TYPE), clang) + JVM_PRECOMPILED_HEADER_EXCLUDE := \ + sharedRuntimeTrig.cpp \ + sharedRuntimeTrans.cpp \ + # + endif + endif + + ifeq ($(OPENJDK_TARGET_CPU), x86) + # Performance measurements show that by compiling GC related code, we could + # significantly reduce the GC pause time on 32 bit Linux/Unix platforms by + # compiling without the PIC flag (-fPIC on linux). + # See 6454213 for more details. + ALL_SRC := $(filter %.cpp, $(call CacheFind, $(HOTSPOT_TOPDIR)/src/share/vm)) + NONPIC_FILTER := $(addsuffix %, $(addprefix $(HOTSPOT_TOPDIR)/src/share/vm/, \ + memory oops gc)) + # Due to what looks like a bug in the old build implementation of this, add a + # couple of more files that were accidentally matched as substrings of GC related + # files. + NONPIC_SRC := $(filter $(NONPIC_FILTER), $(ALL_SRC)) globals.cpp location.cpp + # Declare variables for each source file that needs the pic flag like this: + # BUILD_JVM_<srcfile>_CXXFLAGS := -fno-PIC + # This will get implicitly picked up by SetupNativeCompilation below. + $(foreach s, $(NONPIC_SRC), $(eval BUILD_LIBJVM_$(notdir $s)_CXXFLAGS := -fno-PIC)) + endif + +else ifeq ($(OPENJDK_TARGET_OS), solaris) + ifneq ($(DEBUG_LEVEL), slowdebug) + # Workaround for a bug in dtrace. If ciEnv::post_compiled_method_load_event() + # is inlined, the resulting dtrace object file needs a reference to this + # function, whose symbol name is too long for dtrace. So disable inlining + # for this method for now. (fix this when dtrace bug 6258412 is fixed) + BUILD_LIBJVM_ciEnv.cpp_CXXFLAGS := \ + -xinline=no%__1cFciEnvbFpost_compiled_method_load_event6MpnHnmethod__v_ + # dtrace cannot handle tail call optimization (6672627, 6693876) + BUILD_LIBJVM_jni.cpp_CXXFLAGS := -Qoption ube -O~yz + BUILD_LIBJVM_stubGenerator_$(HOTSPOT_TARGET_CPU).cpp_CXXFLAGS := -xspace + + ifeq ($(OPENJDK_TARGET_CPU), x86_64) + # Temporary until SS10 C++ compiler is fixed + BUILD_LIBJVM_generateOptoStub.cpp_CXXFLAGS := -xO2 + # Temporary util SS12u1 C++ compiler is fixed + BUILD_LIBJVM_c1_LinearScan.cpp_CXXFLAGS := -xO2 + endif + endif + + # Need extra inlining to get oop_ps_push_contents functions to perform well enough. + ifeq ($(DEBUG_LEVEL),release) + BUILD_LIBJVM_psPromotionManager.cpp_CXXFLAGS := -W2,-Ainline:inc=1000 + endif + + ifeq ($(DEBUG_LEVEL), fastdebug) + # this hangs in iropt now (7113504) + BUILD_LIBJVM_compileBroker.cpp_CXXFLAGS := -xO2 + + # Frame size > 100k if we allow inlining via -g0! + BUILD_LIBJVM_bytecodeInterpreter.cpp_CXXFLAGS := +d + BUILD_LIBJVM_bytecodeInterpreterWithChecks.cpp_CXXFLAGS := +d + + ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86) + # ube explodes on x86 + BUILD_LIBJVM_bytecodeInterpreter.cpp_CXXFLAGS += -xO1 + BUILD_LIBJVM_bytecodeInterpreterWithChecks.cpp_CXXFLAGS += -xO1 + endif + + endif + +else ifeq ($(OPENJDK_TARGET_OS), macosx) + # The copied fdlibm routines in these files must not be optimized + BUILD_LIBJVM_sharedRuntimeTrans.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE) + BUILD_LIBJVM_sharedRuntimeTrig.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE) + ifeq ($(TOOLCHAIN_TYPE), clang) + # NOTE: The old build tested clang version to make sure this workaround + # for the clang bug was still needed. + BUILD_LIBJVM_loopTransform.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE) + ifneq ($(DEBUG_LEVEL), slowdebug) + BUILD_LIBJVM_unsafe.cpp_CXXFLAGS := -O1 + endif + + # The following files are compiled at various optimization + # levels due to optimization issues encountered at the + # default level. The Clang compiler issues a compile + # time error if there is an optimization level specification + # skew between the PCH file and the C++ file. Especially if the + # PCH file is compiled at a higher optimization level than + # the C++ file. One solution might be to prepare extra optimization + # level specific PCH files for the opt build and use them here, but + # it's probably not worth the effort as long as only a few files + # need this special handling. + JVM_PRECOMPILED_HEADER_EXCLUDE := \ + sharedRuntimeTrig.cpp \ + sharedRuntimeTrans.cpp \ + loopTransform.cpp \ + unsafe.cpp \ + jvmciCompilerToVM.cpp \ + # + endif + +else ifeq ($(OPENJDK_TARGET_OS), aix) + BUILD_LIBJVM_synchronizer.cpp_CXXFLAGS := -qnoinline + BUILD_LIBJVM_sharedRuntimeTrans.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE) + # Disable aggressive optimizations for functions in sharedRuntimeTrig.cpp + # and sharedRuntimeTrans.cpp on ppc64. + # -qstrict turns off the following optimizations: + # * Performing code motion and scheduling on computations such as loads + # and floating-point computations that may trigger an exception. + # * Relaxing conformance to IEEE rules. + # * Reassociating floating-point expressions. + # When using '-qstrict' there still remains one problem + # in javasoft.sqe.tests.api.java.lang.Math.sin5Tests when run in compile-all + # mode, so don't optimize sharedRuntimeTrig.cpp at all. + BUILD_LIBJVM_sharedRuntimeTrig.cpp_CXXFLAGS := $(CXX_O_FLAG_NONE) + + # Disable ELF decoder on AIX (AIX uses XCOFF). + JVM_EXCLUDE_PATTERNS += elf + +else ifeq ($(OPENJDK_TARGET_OS), windows) + JVM_PRECOMPILED_HEADER_EXCLUDE := \ + bytecodeInterpreter.cpp \ + bytecodeInterpreterWithChecks.cpp \ + opcodes.cpp \ + os_windows.cpp \ + os_windows_x86.cpp \ + osThread_windows.cpp \ + # +endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/mapfiles/libjsig/mapfile-vers-solaris Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,38 @@ +# +# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# + +# Define library interface. + +SUNWprivate_1.1 { + global: + JVM_begin_signal_setting; + JVM_end_signal_setting; + JVM_get_libjsig_version; + JVM_get_signal_action; + sigaction; + signal; + sigset; + local: + *; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/mapfiles/libjvm_db/mapfile-vers Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,38 @@ +# + +# +# Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# + +# Define library interface. + +SUNWprivate_1.1 { + global: + Jagent_create; + Jagent_destroy; + Jframe_iter; + #Jget_vframe; + #Jlookup_by_regs; + local: + *; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/mapfiles/libjvm_dtrace/mapfile-vers Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,37 @@ +# + +# +# Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# + +# Define library interface for JVM-DTrace interface + +SUNWprivate_1.1 { + global: + jvm_attach; + jvm_get_last_error; + jvm_enable_dtprobes; + jvm_detach; + local: + *; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/symbols/symbols-aix Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,27 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +JVM_handle_linux_signal +numa_error +numa_warn +sysThreadAvailableStackWithSlack
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/symbols/symbols-aix-debug Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,26 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +JVM_AccessVMBooleanFlag +JVM_AccessVMIntFlag +JVM_VMBreakPoint
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/symbols/symbols-linux Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,27 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +JVM_handle_linux_signal +numa_error +numa_warn +sysThreadAvailableStackWithSlack
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/symbols/symbols-macosx Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,24 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +JVM_handle_bsd_signal
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/symbols/symbols-shared Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,35 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +AsyncGetCallTrace +jio_fprintf +jio_printf +jio_snprintf +jio_vfprintf +jio_vsnprintf +JNI_CreateJavaVM +JNI_GetCreatedJavaVMs +JNI_GetDefaultJavaVMInitArgs +JVM_FindClassFromBootLoader +JVM_GetVersionInfo +JVM_InitAgentProperties
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/symbols/symbols-solaris Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,25 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +JVM_handle_solaris_signal +sysThreadAvailableStackWithSlack
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/symbols/symbols-solaris-dtrace-compiler1 Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,34 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +__1cGMethodG__vtbl_ +__1cHnmethodG__vtbl_ +__1cICodeBlobG__vtbl_ +__1cIUniverseO_collectedHeap_ +__1cJCodeCacheG_heaps_ +__1cKBufferBlobG__vtbl_ +__1cLRuntimeStubG__vtbl_ +__1cNSafepointBlobG__vtbl_ +__1cSDeoptimizationBlobG__vtbl_ + +__JvmOffsets
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/symbols/symbols-solaris-dtrace-compiler2 Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,36 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +__1cGMethodG__vtbl_ +__1cHnmethodG__vtbl_ +__1cICodeBlobG__vtbl_ +__1cIUniverseO_collectedHeap_ +__1cJCodeCacheG_heaps_ +__1cKBufferBlobG__vtbl_ +__1cLRuntimeStubG__vtbl_ +__1cNSafepointBlobG__vtbl_ +__1cSDeoptimizationBlobG__vtbl_ +__1cNExceptionBlobG__vtbl_ +__1cQUncommonTrapBlobG__vtbl_ + +__JvmOffsets
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/makefiles/symbols/symbols-unix Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,194 @@ +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +JVM_ActiveProcessorCount +JVM_ArrayCopy +JVM_AssertionStatusDirectives +JVM_CallStackWalk +JVM_ClassDepth +JVM_ClassLoaderDepth +JVM_Clone +JVM_ConstantPoolGetClassAt +JVM_ConstantPoolGetClassAtIfLoaded +JVM_ConstantPoolGetClassRefIndexAt +JVM_ConstantPoolGetDoubleAt +JVM_ConstantPoolGetFieldAt +JVM_ConstantPoolGetFieldAtIfLoaded +JVM_ConstantPoolGetFloatAt +JVM_ConstantPoolGetIntAt +JVM_ConstantPoolGetLongAt +JVM_ConstantPoolGetMemberRefInfoAt +JVM_ConstantPoolGetMethodAt +JVM_ConstantPoolGetMethodAtIfLoaded +JVM_ConstantPoolGetNameAndTypeRefIndexAt +JVM_ConstantPoolGetNameAndTypeRefInfoAt +JVM_ConstantPoolGetSize +JVM_ConstantPoolGetStringAt +JVM_ConstantPoolGetTagAt +JVM_ConstantPoolGetUTF8At +JVM_CountStackFrames +JVM_CurrentClassLoader +JVM_CurrentLoadedClass +JVM_CurrentThread +JVM_CurrentTimeMillis +JVM_DefineClass +JVM_DefineClassWithSource +JVM_DesiredAssertionStatus +JVM_DoPrivileged +JVM_DumpAllStacks +JVM_DumpThreads +JVM_FillInStackTrace +JVM_FindClassFromCaller +JVM_FindClassFromClass +JVM_FindLibraryEntry +JVM_FindLoadedClass +JVM_FindPrimitiveClass +JVM_FindSignal +JVM_FreeMemory +JVM_GC +JVM_GetAllThreads +JVM_GetArrayElement +JVM_GetArrayLength +JVM_GetCallerClass +JVM_GetClassAccessFlags +JVM_GetClassAnnotations +JVM_GetClassConstantPool +JVM_GetClassContext +JVM_GetClassCPEntriesCount +JVM_GetClassCPTypes +JVM_GetClassDeclaredConstructors +JVM_GetClassDeclaredFields +JVM_GetClassDeclaredMethods +JVM_GetClassFieldsCount +JVM_GetClassInterfaces +JVM_GetClassMethodsCount +JVM_GetClassModifiers +JVM_GetClassName +JVM_GetClassNameUTF +JVM_GetClassSignature +JVM_GetClassSigners +JVM_GetClassTypeAnnotations +JVM_GetCPClassNameUTF +JVM_GetCPFieldClassNameUTF +JVM_GetCPFieldModifiers +JVM_GetCPFieldNameUTF +JVM_GetCPFieldSignatureUTF +JVM_GetCPMethodClassNameUTF +JVM_GetCPMethodModifiers +JVM_GetCPMethodNameUTF +JVM_GetCPMethodSignatureUTF +JVM_GetDeclaredClasses +JVM_GetDeclaringClass +JVM_GetEnclosingMethodInfo +JVM_GetFieldIxModifiers +JVM_GetFieldTypeAnnotations +JVM_GetInheritedAccessControlContext +JVM_GetInterfaceVersion +JVM_GetManagement +JVM_GetMethodIxArgsSize +JVM_GetMethodIxByteCode +JVM_GetMethodIxByteCodeLength +JVM_GetMethodIxExceptionIndexes +JVM_GetMethodIxExceptionsCount +JVM_GetMethodIxExceptionTableEntry +JVM_GetMethodIxExceptionTableLength +JVM_GetMethodIxLocalsCount +JVM_GetMethodIxMaxStack +JVM_GetMethodIxModifiers +JVM_GetMethodIxNameUTF +JVM_GetMethodIxSignatureUTF +JVM_GetMethodParameters +JVM_GetMethodTypeAnnotations +JVM_GetNanoTimeAdjustment +JVM_GetPrimitiveArrayElement +JVM_GetProtectionDomain +JVM_GetSimpleBinaryName +JVM_GetStackAccessControlContext +JVM_GetStackTraceElements +JVM_GetSystemPackage +JVM_GetSystemPackages +JVM_GetTemporaryDirectory +JVM_GetVmArguments +JVM_Halt +JVM_HoldsLock +JVM_IHashCode +JVM_InitProperties +JVM_InternString +JVM_Interrupt +JVM_InvokeMethod +JVM_IsArrayClass +JVM_IsConstructorIx +JVM_IsInterface +JVM_IsInterrupted +JVM_IsPrimitiveClass +JVM_IsSameClassPackage +JVM_IsSupportedJNIVersion +JVM_IsThreadAlive +JVM_IsVMGeneratedMethodIx +JVM_LatestUserDefinedLoader +JVM_LoadLibrary +JVM_MaxMemory +JVM_MaxObjectInspectionAge +JVM_MonitorNotify +JVM_MonitorNotifyAll +JVM_MonitorWait +JVM_MoreStackWalk +JVM_NanoTime +JVM_NativePath +JVM_NewArray +JVM_NewInstanceFromConstructor +JVM_NewMultiArray +JVM_RaiseSignal +JVM_RawMonitorCreate +JVM_RawMonitorDestroy +JVM_RawMonitorEnter +JVM_RawMonitorExit +JVM_RegisterSignal +JVM_ReleaseUTF +JVM_ResumeThread +JVM_SetArrayElement +JVM_SetClassSigners +JVM_SetNativeThreadName +JVM_SetPrimitiveArrayElement +JVM_SetThreadPriority +JVM_Sleep +JVM_StartThread +JVM_StopThread +JVM_SupportsCX8 +JVM_SuspendThread +JVM_ToStackTraceElement +JVM_TotalMemory +JVM_UnloadLibrary +JVM_Yield + +# Module related API's +JVM_AddModuleExports +JVM_AddModuleExportsToAll +JVM_AddModuleExportsToAllUnnamed +JVM_AddModulePackage +JVM_AddReadsModule +JVM_CanReadModule +JVM_DefineModule +JVM_IsExportedToModule +JVM_SetBootLoaderUnnamedModule +JVM_GetModuleByPackageName
--- a/hotspot/src/cpu/aarch64/vm/debug_aarch64.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/aarch64/vm/debug_aarch64.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -30,6 +30,5 @@ #include "runtime/init.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" -#include "utilities/top.hpp" void pd_ps(frame f) {}
--- a/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/aarch64/vm/frame_aarch64.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -27,7 +27,6 @@ #define CPU_AARCH64_VM_FRAME_AARCH64_HPP #include "runtime/synchronizer.hpp" -#include "utilities/top.hpp" // A frame represents a physical stack frame (an activation). Frames can be // C or Java frames, and the Java frames can be interpreted or compiled.
--- a/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -30,7 +30,6 @@ #include "memory/allocation.hpp" #include "runtime/icache.hpp" #include "runtime/os.hpp" -#include "utilities/top.hpp" // We have interfaces for the following instructions: // - NativeInstruction
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -198,6 +198,16 @@ bool SharedRuntime::is_wide_vector(int size) { return size > 8; } + +size_t SharedRuntime::trampoline_size() { + return 16; +} + +void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) { + __ mov(rscratch1, destination); + __ br(rscratch1); +} + // The java_calling_convention describes stack locations as ideal slots on // a frame with no abi restrictions. Since we must observe abi restrictions // (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -39,7 +39,6 @@ #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" -#include "utilities/top.hpp" #ifdef COMPILER2 #include "opto/runtime.hpp" #endif
--- a/hotspot/src/cpu/ppc/vm/debug_ppc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/ppc/vm/debug_ppc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -30,6 +30,5 @@ #include "runtime/init.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" -#include "utilities/top.hpp" void pd_ps(frame f) {}
--- a/hotspot/src/cpu/ppc/vm/frame_ppc.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/ppc/vm/frame_ppc.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -27,7 +27,6 @@ #define CPU_PPC_VM_FRAME_PPC_HPP #include "runtime/synchronizer.hpp" -#include "utilities/top.hpp" // C frame layout on PPC-64. //
--- a/hotspot/src/cpu/ppc/vm/nativeInst_ppc.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/ppc/vm/nativeInst_ppc.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -31,7 +31,6 @@ #include "memory/allocation.hpp" #include "runtime/icache.hpp" #include "runtime/os.hpp" -#include "utilities/top.hpp" // We have interfaces for the following instructions: //
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -483,6 +483,18 @@ assert(size <= 8, "%d bytes vectors are not supported", size); return size > 8; } + +size_t SharedRuntime::trampoline_size() { + return Assembler::load_const_size + 8; +} + +void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) { + Register Rtemp = R12; + __ load_const(Rtemp, destination); + __ mtctr(Rtemp); + __ bctr(); +} + #ifdef COMPILER2 static int reg2slot(VMReg r) { return r->reg2stack() + SharedRuntime::out_preserve_stack_slots();
--- a/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/ppc/vm/stubGenerator_ppc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -37,7 +37,6 @@ #include "runtime/sharedRuntime.hpp" #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" -#include "utilities/top.hpp" #include "runtime/thread.inline.hpp" #define __ _masm->
--- a/hotspot/src/cpu/sparc/vm/debug_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/sparc/vm/debug_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -29,7 +29,6 @@ #include "runtime/init.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" -#include "utilities/top.hpp" #ifndef PRODUCT
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/sparc/vm/frame_sparc.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -26,7 +26,6 @@ #define CPU_SPARC_VM_FRAME_SPARC_HPP #include "runtime/synchronizer.hpp" -#include "utilities/top.hpp" // A frame represents a physical stack frame (an activation). Frames can be // C or Java frames, and the Java frames can be interpreted or compiled.
--- a/hotspot/src/cpu/sparc/vm/metaspaceShared_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/sparc/vm/metaspaceShared_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -65,8 +65,6 @@ *vtable = dummy_vtable; *md_top += vtable_bytes; - guarantee(*md_top <= md_end, "Insufficient space for vtables."); - // Get ready to generate dummy methods. CodeBuffer cb((unsigned char*)*mc_top, mc_end - *mc_top);
--- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -29,7 +29,6 @@ #include "memory/allocation.hpp" #include "runtime/icache.hpp" #include "runtime/os.hpp" -#include "utilities/top.hpp" // We have interface for the following instructions: // - NativeInstruction
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -324,6 +324,16 @@ return size > 8; } +size_t SharedRuntime::trampoline_size() { + return 40; +} + +void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) { + __ set((intptr_t)destination, G3_scratch); + __ JMP(G3_scratch, 0); + __ delayed()->nop(); +} + // The java_calling_convention describes stack locations as ideal slots on // a frame with no abi restrictions. Since we must observe abi restrictions // (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -37,7 +37,6 @@ #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" -#include "utilities/top.hpp" #ifdef COMPILER2 #include "opto/runtime.hpp" #endif
--- a/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -616,7 +616,7 @@ // compute the beginning of the protected zone minus the requested frame size __ sub( Rscratch, Rscratch2, Rscratch ); - __ set( JavaThread::stack_red_zone_size() + JavaThread::stack_yellow_zone_size(), Rscratch2 ); + __ set(MAX2(JavaThread::stack_shadow_zone_size(), JavaThread::stack_guard_zone_size()), Rscratch2 ); __ add( Rscratch, Rscratch2, Rscratch ); // Add in the size of the frame (which is the same as subtracting it from the
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" +#include "logging/log.hpp" #include "memory/resourceArea.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" @@ -368,36 +369,38 @@ FLAG_SET_DEFAULT(UseUnalignedAccesses, false); } - if (PrintMiscellaneous && Verbose) { - tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size()); - tty->print_cr("L2 data cache line size: %u", L2_data_cache_line_size()); - tty->print("Allocation"); + if (log_is_enabled(Info, os, cpu)) { + ResourceMark rm; + outputStream* log = Log(os, cpu)::info_stream(); + log->print_cr("L1 data cache line size: %u", L1_data_cache_line_size()); + log->print_cr("L2 data cache line size: %u", L2_data_cache_line_size()); + log->print("Allocation"); if (AllocatePrefetchStyle <= 0) { - tty->print_cr(": no prefetching"); + log->print(": no prefetching"); } else { - tty->print(" prefetching: "); + log->print(" prefetching: "); if (AllocatePrefetchInstr == 0) { - tty->print("PREFETCH"); + log->print("PREFETCH"); } else if (AllocatePrefetchInstr == 1) { - tty->print("BIS"); + log->print("BIS"); } if (AllocatePrefetchLines > 1) { - tty->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize); + log->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize); } else { - tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize); + log->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize); } } if (PrefetchCopyIntervalInBytes > 0) { - tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes); + log->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes); } if (PrefetchScanIntervalInBytes > 0) { - tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes); + log->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes); } if (PrefetchFieldsAhead > 0) { - tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead); + log->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead); } if (ContendedPaddingWidth > 0) { - tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth); + log->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth); } } } @@ -408,7 +411,7 @@ int VM_Version::determine_features() { if (UseV8InstrsOnly) { - if (PrintMiscellaneous && Verbose) { tty->print_cr("Version is Forced-V8"); } + log_info(os, cpu)("Version is Forced-V8"); return generic_v8_m; } @@ -416,7 +419,7 @@ if (features == unknown_m) { features = generic_v9_m; - warning("Cannot recognize SPARC version. Default to V9"); + log_info(os)("Cannot recognize SPARC version. Default to V9"); } assert(is_T_family(features) == is_niagara(features), "Niagara should be T series"); @@ -424,12 +427,12 @@ if (is_T_family(features)) { // Happy to accomodate... } else { - if (PrintMiscellaneous && Verbose) { tty->print_cr("Version is Forced-Niagara"); } + log_info(os, cpu)("Version is Forced-Niagara"); features |= T_family_m; } } else { if (is_T_family(features) && !FLAG_IS_DEFAULT(UseNiagaraInstrs)) { - if (PrintMiscellaneous && Verbose) { tty->print_cr("Version is Forced-Not-Niagara"); } + log_info(os, cpu)("Version is Forced-Not-Niagara"); features &= ~(T_family_m | T1_model_m); } else { // Happy to accomodate...
--- a/hotspot/src/cpu/x86/vm/debug_x86.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/x86/vm/debug_x86.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -29,6 +29,5 @@ #include "runtime/init.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" -#include "utilities/top.hpp" void pd_ps(frame f) {}
--- a/hotspot/src/cpu/x86/vm/frame_x86.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/x86/vm/frame_x86.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -26,7 +26,6 @@ #define CPU_X86_VM_FRAME_X86_HPP #include "runtime/synchronizer.hpp" -#include "utilities/top.hpp" // A frame represents a physical stack frame (an activation). Frames can be // C or Java frames, and the Java frames can be interpreted or compiled.
--- a/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/x86/vm/nativeInst_x86.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -29,7 +29,6 @@ #include "memory/allocation.hpp" #include "runtime/icache.hpp" #include "runtime/os.hpp" -#include "utilities/top.hpp" // We have interfaces for the following instructions: // - NativeInstruction
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -355,6 +355,14 @@ return size > 16; } +size_t SharedRuntime::trampoline_size() { + return 16; +} + +void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) { + __ jump(RuntimeAddress(destination)); +} + // The java_calling_convention describes stack locations as ideal slots on // a frame with no abi restrictions. Since we must observe abi restrictions // (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -391,6 +391,14 @@ return size > 16; } +size_t SharedRuntime::trampoline_size() { + return 16; +} + +void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) { + __ jump(RuntimeAddress(destination)); +} + // The java_calling_convention describes stack locations as ideal slots on // a frame with no abi restrictions. Since we must observe abi restrictions // (like the placement of the register window) the slots must be biased by
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -38,7 +38,6 @@ #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" -#include "utilities/top.hpp" #ifdef COMPILER2 #include "opto/runtime.hpp" #endif
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -38,7 +38,6 @@ #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" -#include "utilities/top.hpp" #ifdef COMPILER2 #include "opto/runtime.hpp" #endif
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" +#include "logging/log.hpp" #include "memory/resourceArea.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" @@ -1223,59 +1224,60 @@ } #ifndef PRODUCT - if (PrintMiscellaneous && Verbose) { - tty->print_cr("Logical CPUs per core: %u", + if (log_is_enabled(Info, os, cpu)) { + outputStream* log = Log(os, cpu)::info_stream(); + log->print_cr("Logical CPUs per core: %u", logical_processors_per_package()); - tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size()); - tty->print("UseSSE=%d", (int) UseSSE); + log->print_cr("L1 data cache line size: %u", L1_data_cache_line_size()); + log->print("UseSSE=%d", (int) UseSSE); if (UseAVX > 0) { - tty->print(" UseAVX=%d", (int) UseAVX); + log->print(" UseAVX=%d", (int) UseAVX); } if (UseAES) { - tty->print(" UseAES=1"); + log->print(" UseAES=1"); } #ifdef COMPILER2 if (MaxVectorSize > 0) { - tty->print(" MaxVectorSize=%d", (int) MaxVectorSize); + log->print(" MaxVectorSize=%d", (int) MaxVectorSize); } #endif - tty->cr(); - tty->print("Allocation"); + log->cr(); + log->print("Allocation"); if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow_prefetch()) { - tty->print_cr(": no prefetching"); + log->print_cr(": no prefetching"); } else { - tty->print(" prefetching: "); + log->print(" prefetching: "); if (UseSSE == 0 && supports_3dnow_prefetch()) { - tty->print("PREFETCHW"); + log->print("PREFETCHW"); } else if (UseSSE >= 1) { if (AllocatePrefetchInstr == 0) { - tty->print("PREFETCHNTA"); + log->print("PREFETCHNTA"); } else if (AllocatePrefetchInstr == 1) { - tty->print("PREFETCHT0"); + log->print("PREFETCHT0"); } else if (AllocatePrefetchInstr == 2) { - tty->print("PREFETCHT2"); + log->print("PREFETCHT2"); } else if (AllocatePrefetchInstr == 3) { - tty->print("PREFETCHW"); + log->print("PREFETCHW"); } } if (AllocatePrefetchLines > 1) { - tty->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize); + log->print_cr(" at distance %d, %d lines of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchLines, (int) AllocatePrefetchStepSize); } else { - tty->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize); + log->print_cr(" at distance %d, one line of %d bytes", (int) AllocatePrefetchDistance, (int) AllocatePrefetchStepSize); } } if (PrefetchCopyIntervalInBytes > 0) { - tty->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes); + log->print_cr("PrefetchCopyIntervalInBytes %d", (int) PrefetchCopyIntervalInBytes); } if (PrefetchScanIntervalInBytes > 0) { - tty->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes); + log->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes); } if (PrefetchFieldsAhead > 0) { - tty->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead); + log->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead); } if (ContendedPaddingWidth > 0) { - tty->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth); + log->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth); } } #endif // !PRODUCT
--- a/hotspot/src/cpu/zero/vm/debug_zero.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/zero/vm/debug_zero.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -30,7 +30,6 @@ #include "runtime/init.hpp" #include "runtime/os.hpp" #include "utilities/debug.hpp" -#include "utilities/top.hpp" void pd_ps(frame f) { ShouldNotCallThis();
--- a/hotspot/src/cpu/zero/vm/frame_zero.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/zero/vm/frame_zero.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -27,7 +27,6 @@ #define CPU_ZERO_VM_FRAME_ZERO_HPP #include "runtime/synchronizer.hpp" -#include "utilities/top.hpp" // A frame represents a physical stack frame on the Zero stack.
--- a/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/zero/vm/nativeInst_zero.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -30,7 +30,6 @@ #include "memory/allocation.hpp" #include "runtime/icache.hpp" #include "runtime/os.hpp" -#include "utilities/top.hpp" // We have interfaces for the following instructions: // - NativeInstruction
--- a/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -132,6 +132,15 @@ return generate_empty_runtime_stub("resolve_blob"); } +size_t SharedRuntime::trampoline_size() { + ShouldNotCallThis(); + return 0; +} + +void SharedRuntime::generate_trampoline(MacroAssembler *masm, address destination) { + ShouldNotCallThis(); + return; +} int SharedRuntime::c_calling_convention(const BasicType *sig_bt, VMRegPair *regs,
--- a/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -40,7 +40,6 @@ #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" #include "stack_zero.inline.hpp" -#include "utilities/top.hpp" #ifdef COMPILER2 #include "opto/runtime.hpp" #endif
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SAGetopt.java Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SAGetopt.java Thu Apr 14 19:55:39 2016 -0700 @@ -55,11 +55,11 @@ private void extractOptarg(String opt) { // Argument expected if (_optind > _argv.length) { - throw new RuntimeException("Not enough arguments for '" + opt + "'"); + throw new SAGetoptException("Not enough arguments for '" + opt + "'"); } if (! _argv[_optind].isEmpty() && _argv[_optind].charAt(0) == '-') { - throw new RuntimeException("Argument is expected for '" + opt + "'"); + throw new SAGetoptException("Argument is expected for '" + opt + "'"); } _optarg = _argv[_optind]; @@ -72,7 +72,7 @@ if (los.contains(ca[0])) { if (ca.length > 1) { - throw new RuntimeException("Argument is not expected for '" + ca[0] + "'"); + throw new SAGetoptException("Argument is not expected for '" + ca[0] + "'"); } return carg; } @@ -87,14 +87,14 @@ try { extractOptarg(ca[0]); } catch (ArrayIndexOutOfBoundsException e) { - throw new RuntimeException("Argument is expected for '" + ca[0] + "'"); + throw new SAGetoptException("Argument is expected for '" + ca[0] + "'"); } } return ca[0]; } - throw new RuntimeException("Invalid option '" + ca[0] + "'"); + throw new SAGetoptException("Invalid option '" + ca[0] + "'"); } public String next(String optStr, String[] longOptStr) { @@ -148,7 +148,7 @@ int chIndex = optStr.indexOf(ch); if (chIndex == -1) { - throw new RuntimeException("Invalid option '" + ch + "'"); + throw new SAGetoptException("Invalid option '" + ch + "'"); } if (_optopt >= carg.length()) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SAGetoptException.java Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot; + +public class SAGetoptException extends IllegalArgumentException { + + public SAGetoptException(String message) { + super(message); + } + +}
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncher.java Thu Apr 14 19:55:39 2016 -0700 @@ -111,34 +111,31 @@ return launcherHelp(); } - private static void buildAttachArgs(ArrayList<String> newArgs, - String pid, String exe, String core) { - if ((pid == null) && (exe == null)) { - throw new IllegalArgumentException( - "You have to set --pid or --exe."); + private static void buildAttachArgs(ArrayList<String> newArgs, String pid, + String exe, String core, boolean allowEmpty) { + if (!allowEmpty && (pid == null) && (exe == null)) { + throw new SAGetoptException("You have to set --pid or --exe."); } if (pid != null) { // Attach to live process if (exe != null) { - throw new IllegalArgumentException( - "Unnecessary argument: --exe"); + throw new SAGetoptException("Unnecessary argument: --exe"); } else if (core != null) { - throw new IllegalArgumentException( - "Unnecessary argument: --core"); + throw new SAGetoptException("Unnecessary argument: --core"); } else if (!pid.matches("^\\d+$")) { - throw new IllegalArgumentException("Invalid pid: " + pid); + throw new SAGetoptException("Invalid pid: " + pid); } newArgs.add(pid); - } else { + } else if (exe != null) { if (exe.length() == 0) { - throw new IllegalArgumentException("You have to set --exe."); + throw new SAGetoptException("You have to set --exe."); } newArgs.add(exe); if ((core == null) || (core.length() == 0)) { - throw new IllegalArgumentException("You have to set --core."); + throw new SAGetoptException("You have to set --core."); } newArgs.add(core); @@ -170,7 +167,7 @@ } } - buildAttachArgs(newArgs, pid, exe, core); + buildAttachArgs(newArgs, pid, exe, core, true); CLHSDB.main(newArgs.toArray(new String[newArgs.size()])); } @@ -199,7 +196,7 @@ } } - buildAttachArgs(newArgs, pid, exe, core); + buildAttachArgs(newArgs, pid, exe, core, true); HSDB.main(newArgs.toArray(new String[newArgs.size()])); } @@ -237,7 +234,7 @@ } } - buildAttachArgs(newArgs, pid, exe, core); + buildAttachArgs(newArgs, pid, exe, core, false); JStack.main(newArgs.toArray(new String[newArgs.size()])); } @@ -287,7 +284,7 @@ } } - buildAttachArgs(newArgs, pid, exe, core); + buildAttachArgs(newArgs, pid, exe, core, false); JMap.main(newArgs.toArray(new String[newArgs.size()])); } @@ -325,7 +322,7 @@ } } - buildAttachArgs(newArgs, pid, exe, core); + buildAttachArgs(newArgs, pid, exe, core, false); JInfo.main(newArgs.toArray(new String[newArgs.size()])); } @@ -358,7 +355,7 @@ } } - buildAttachArgs(newArgs, pid, exe, core); + buildAttachArgs(newArgs, pid, exe, core, false); JSnap.main(newArgs.toArray(new String[newArgs.size()])); } @@ -416,8 +413,8 @@ return; } - throw new IllegalArgumentException("Unknown tool: " + args[0]); - } catch (Exception e) { + throw new SAGetoptException("Unknown tool: " + args[0]); + } catch (SAGetoptException e) { System.err.println(e.getMessage()); toolHelp(args[0]); }
--- a/hotspot/src/os/aix/vm/os_aix.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -3612,14 +3612,12 @@ struct rlimit nbr_files; int status = getrlimit(RLIMIT_NOFILE, &nbr_files); if (status != 0) { - if (PrintMiscellaneous && (Verbose || WizardMode)) - perror("os::init_2 getrlimit failed"); + log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno)); } else { nbr_files.rlim_cur = nbr_files.rlim_max; status = setrlimit(RLIMIT_NOFILE, &nbr_files); if (status != 0) { - if (PrintMiscellaneous && (Verbose || WizardMode)) - perror("os::init_2 setrlimit failed"); + log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno)); } } }
--- a/hotspot/src/os/aix/vm/perfMemory_aix.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os/aix/vm/perfMemory_aix.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -956,7 +956,7 @@ #ifdef O_NOFOLLOW RESTARTABLE(::open(filename, oflags), result); #else - open_o_nofollow(filename, oflags); + result = open_o_nofollow(filename, oflags); #endif if (result == OS_ERR) {
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -3459,25 +3459,13 @@ guarantee(polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page"); os::set_polling_page(polling_page); - -#ifndef PRODUCT - if (Verbose && PrintMiscellaneous) { - tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", - (intptr_t)polling_page); - } -#endif + log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page)); if (!UseMembar) { address mem_serialize_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); guarantee(mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page"); os::set_memory_serialize_page(mem_serialize_page); - -#ifndef PRODUCT - if (Verbose && PrintMiscellaneous) { - tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", - (intptr_t)mem_serialize_page); - } -#endif + log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page)); } // initialize suspend/resume support - must do this before signal_sets_init() @@ -3519,9 +3507,7 @@ struct rlimit nbr_files; int status = getrlimit(RLIMIT_NOFILE, &nbr_files); if (status != 0) { - if (PrintMiscellaneous && (Verbose || WizardMode)) { - perror("os::init_2 getrlimit failed"); - } + log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno)); } else { nbr_files.rlim_cur = nbr_files.rlim_max; @@ -3534,9 +3520,7 @@ status = setrlimit(RLIMIT_NOFILE, &nbr_files); if (status != 0) { - if (PrintMiscellaneous && (Verbose || WizardMode)) { - perror("os::init_2 setrlimit failed"); - } + log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno)); } } } @@ -3748,6 +3732,28 @@ return ::stat(pathbuf, sbuf); } +static inline struct timespec get_mtime(const char* filename) { + struct stat st; + int ret = os::stat(filename, &st); + assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno)); +#ifdef __APPLE__ + return st.st_mtimespec; +#else + return st.st_mtim; +#endif +} + +int os::compare_file_modified_times(const char* file1, const char* file2) { + struct timespec filetime1 = get_mtime(file1); + struct timespec filetime2 = get_mtime(file2); + int diff = filetime1.tv_sec - filetime2.tv_sec; + if (diff == 0) { + return filetime1.tv_nsec - filetime2.tv_nsec; + } + return diff; +} + + bool os::check_heap(bool force) { return true; }
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -2163,7 +2163,7 @@ bool model_name_printed = false; if (strstr(buf, "model name") != NULL) { if (!model_name_printed) { - st->print_raw("\nCPU Model and flags from /proc/cpuinfo:\n"); + st->print_raw("CPU Model and flags from /proc/cpuinfo:\n"); st->print_raw(buf); model_name_printed = true; } else { @@ -4671,25 +4671,13 @@ guarantee(polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page"); os::set_polling_page(polling_page); - -#ifndef PRODUCT - if (Verbose && PrintMiscellaneous) { - tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", - (intptr_t)polling_page); - } -#endif + log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page)); if (!UseMembar) { address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); guarantee(mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page"); os::set_memory_serialize_page(mem_serialize_page); - -#ifndef PRODUCT - if (Verbose && PrintMiscellaneous) { - tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", - (intptr_t)mem_serialize_page); - } -#endif + log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page)); } // initialize suspend/resume support - must do this before signal_sets_init() @@ -4732,10 +4720,8 @@ #endif Linux::libpthread_init(); - if (PrintMiscellaneous && (Verbose || WizardMode)) { - tty->print_cr("[HotSpot is running with %s, %s]\n", - Linux::glibc_version(), Linux::libpthread_version()); - } + log_info(os)("HotSpot is running with %s, %s", + Linux::glibc_version(), Linux::libpthread_version()); if (UseNUMA) { if (!Linux::libnuma_init()) { @@ -4776,16 +4762,12 @@ struct rlimit nbr_files; int status = getrlimit(RLIMIT_NOFILE, &nbr_files); if (status != 0) { - if (PrintMiscellaneous && (Verbose || WizardMode)) { - perror("os::init_2 getrlimit failed"); - } + log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno)); } else { nbr_files.rlim_cur = nbr_files.rlim_max; status = setrlimit(RLIMIT_NOFILE, &nbr_files); if (status != 0) { - if (PrintMiscellaneous && (Verbose || WizardMode)) { - perror("os::init_2 setrlimit failed"); - } + log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno)); } } } @@ -6026,7 +6008,22 @@ return yes; } - +static inline struct timespec get_mtime(const char* filename) { + struct stat st; + int ret = os::stat(filename, &st); + assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno)); + return st.st_mtim; +} + +int os::compare_file_modified_times(const char* file1, const char* file2) { + struct timespec filetime1 = get_mtime(file1); + struct timespec filetime2 = get_mtime(file2); + int diff = filetime1.tv_sec - filetime2.tv_sec; + if (diff == 0) { + return filetime1.tv_nsec - filetime2.tv_nsec; + } + return diff; +} /////////////// Unit tests ///////////////
--- a/hotspot/src/os/posix/vm/os_posix.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os/posix/vm/os_posix.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -181,6 +181,10 @@ return vsnprintf(buf, len, fmt, args); } +int os::fileno(FILE* fp) { + return ::fileno(fp); +} + void os::Posix::print_load_average(outputStream* st) { st->print("load average:"); double loadavg[3];
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -161,6 +161,7 @@ address os::Solaris::_main_stack_base = NULL; // 4352906 workaround +os::Solaris::pthread_setname_np_func_t os::Solaris::_pthread_setname_np = NULL; // "default" initializers for missing libc APIs extern "C" { @@ -441,8 +442,15 @@ } void os::set_native_thread_name(const char *name) { - // Not yet implemented. - return; + if (Solaris::_pthread_setname_np != NULL) { + // Only the first 31 bytes of 'name' are processed by pthread_setname_np + // but we explicitly copy into a size-limited buffer to avoid any + // possible overflow. + char buf[32]; + snprintf(buf, sizeof(buf), "%s", name); + buf[sizeof(buf) - 1] = '\0'; + Solaris::_pthread_setname_np(pthread_self(), buf); + } } bool os::distribute_processes(uint length, uint* distribution) { @@ -1819,6 +1827,19 @@ return ::stat(pathbuf, sbuf); } +static inline time_t get_mtime(const char* filename) { + struct stat st; + int ret = os::stat(filename, &st); + assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno)); + return st.st_mtime; +} + +int os::compare_file_modified_times(const char* file1, const char* file2) { + time_t t1 = get_mtime(file1); + time_t t2 = get_mtime(file2); + return t1 - t2; +} + static bool _print_ascii_file(const char* filename, outputStream* st) { int fd = ::open(filename, O_RDONLY); if (fd == -1) { @@ -2754,13 +2775,13 @@ pd_unmap_memory(addr, bytes); } - if (PrintMiscellaneous && Verbose) { + if (log_is_enabled(Warning, os)) { char buf[256]; buf[0] = '\0'; if (addr == NULL) { jio_snprintf(buf, sizeof(buf), ": %s", os::strerror(err)); } - warning("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at " + log_info(os)("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at " PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT "%s", bytes, requested_addr, addr, buf); } @@ -2790,9 +2811,7 @@ assert(i > 0, "gap adjustment code problem"); have_adjusted_gap = true; // adjust the gap only once, just in case gap = actual_gap; - if (PrintMiscellaneous && Verbose) { - warning("attempt_reserve_memory_at: adjusted gap to 0x%lx", gap); - } + log_info(os)("attempt_reserve_memory_at: adjusted gap to 0x%lx", gap); unmap_memory(base[i], bytes); unmap_memory(base[i-1], size[i-1]); i-=2; @@ -2824,8 +2843,8 @@ } else { size_t bottom_overlap = base[i] + bytes - requested_addr; if (bottom_overlap >= 0 && bottom_overlap < bytes) { - if (PrintMiscellaneous && Verbose && bottom_overlap == 0) { - warning("attempt_reserve_memory_at: possible alignment bug"); + if (bottom_overlap == 0) { + log_info(os)("attempt_reserve_memory_at: possible alignment bug"); } unmap_memory(requested_addr, bottom_overlap); size[i] = bytes - bottom_overlap; @@ -4355,8 +4374,8 @@ void init_pset_getloadavg_ptr(void) { pset_getloadavg_ptr = (pset_getloadavg_type)dlsym(RTLD_DEFAULT, "pset_getloadavg"); - if (PrintMiscellaneous && Verbose && pset_getloadavg_ptr == NULL) { - warning("pset_getloadavg function not found"); + if (pset_getloadavg_ptr == NULL) { + log_warning(os)("pset_getloadavg function not found"); } } @@ -4412,6 +4431,13 @@ // the minimum of what the OS supports (thr_min_stack()), and // enough to allow the thread to get to user bytecode execution. Solaris::min_stack_allowed = MAX2(thr_min_stack(), Solaris::min_stack_allowed); + + // retrieve entry point for pthread_setname_np + void * handle = dlopen("libc.so.1", RTLD_LAZY); + if (handle != NULL) { + Solaris::_pthread_setname_np = + (Solaris::pthread_setname_np_func_t)dlsym(handle, "pthread_setname_np"); + } } // To install functions for atexit system call @@ -4439,25 +4465,13 @@ } os::set_polling_page(polling_page); - -#ifndef PRODUCT - if (Verbose && PrintMiscellaneous) { - tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", - (intptr_t)polling_page); - } -#endif + log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page)); if (!UseMembar) { address mem_serialize_page = (address)Solaris::mmap_chunk(NULL, page_size, MAP_PRIVATE, PROT_READ | PROT_WRITE); guarantee(mem_serialize_page != NULL, "mmap Failed for memory serialize page"); os::set_memory_serialize_page(mem_serialize_page); - -#ifndef PRODUCT - if (Verbose && PrintMiscellaneous) { - tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", - (intptr_t)mem_serialize_page); - } -#endif + log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page)); } // Check minimum allowable stack size for thread creation and to initialize @@ -4537,16 +4551,12 @@ struct rlimit nbr_files; int status = getrlimit(RLIMIT_NOFILE, &nbr_files); if (status != 0) { - if (PrintMiscellaneous && (Verbose || WizardMode)) { - perror("os::init_2 getrlimit failed"); - } + log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno)); } else { nbr_files.rlim_cur = nbr_files.rlim_max; status = setrlimit(RLIMIT_NOFILE, &nbr_files); if (status != 0) { - if (PrintMiscellaneous && (Verbose || WizardMode)) { - perror("os::init_2 setrlimit failed"); - } + log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno)); } } }
--- a/hotspot/src/os/solaris/vm/os_solaris.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os/solaris/vm/os_solaris.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,6 +122,9 @@ static int _SIGasync; // user-overridable ASYNC_SIGNAL static void set_SIGasync(int newsig) { _SIGasync = newsig; } + typedef int (*pthread_setname_np_func_t)(pthread_t, const char*); + static pthread_setname_np_func_t _pthread_setname_np; + public: // Large Page Support--ISM. static bool largepage_range(char* addr, size_t size);
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1594,6 +1594,19 @@ return ret; } +static inline time_t get_mtime(const char* filename) { + struct stat st; + int ret = os::stat(filename, &st); + assert(ret == 0, "failed to stat() file '%s': %s", filename, strerror(errno)); + return st.st_mtime; +} + +int os::compare_file_modified_times(const char* file1, const char* file2) { + time_t t1 = get_mtime(file1); + time_t t2 = get_mtime(file2); + return t1 - t2; +} + void os::print_os_info_brief(outputStream* st) { os::print_os_info(st); } @@ -2436,14 +2449,10 @@ bool res = os::protect_memory((char*) page_start, page_size, os::MEM_PROT_RWX); - if (PrintMiscellaneous && Verbose) { - char buf[256]; - jio_snprintf(buf, sizeof(buf), "Execution protection violation " - "at " INTPTR_FORMAT - ", unguarding " INTPTR_FORMAT ": %s", addr, - page_start, (res ? "success" : os::strerror(errno))); - tty->print_raw_cr(buf); - } + log_debug(os)("Execution protection violation " + "at " INTPTR_FORMAT + ", unguarding " INTPTR_FORMAT ": %s", p2i(addr), + p2i(page_start), (res ? "success" : os::strerror(errno))); // Set last_addr so if we fault again at the same address, we don't // end up in an endless loop. @@ -2896,12 +2905,12 @@ NUMAInterleaveGranularity = align_size_up(NUMAInterleaveGranularity, min_interleave_granularity); if (numa_node_list_holder.build()) { - if (PrintMiscellaneous && Verbose) { - tty->print("NUMA UsedNodeCount=%d, namely ", numa_node_list_holder.get_count()); + if (log_is_enabled(Debug, os, cpu)) { + Log(os, cpu) log; + log.debug("NUMA UsedNodeCount=%d, namely ", numa_node_list_holder.get_count()); for (int i = 0; i < numa_node_list_holder.get_count(); i++) { - tty->print("%d ", numa_node_list_holder.get_node_list_entry(i)); + log.debug(" %d ", numa_node_list_holder.get_node_list_entry(i)); } - tty->print("\n"); } success = true; } else { @@ -3010,9 +3019,7 @@ } #ifdef ASSERT if (should_inject_error) { - if (TracePageSizes && Verbose) { - tty->print_cr("Reserving pages individually failed."); - } + log_develop_debug(pagesize)("Reserving pages individually failed."); } #endif return NULL; @@ -3196,9 +3203,8 @@ // 1) the UseLargePagesIndividualAllocation flag is set (set by default on WS2003) // 2) NUMA Interleaving is enabled, in which case we use a different node for each page if (UseLargePagesIndividualAllocation || UseNUMAInterleaving) { - if (TracePageSizes && Verbose) { - tty->print_cr("Reserving large pages individually."); - } + log_debug(pagesize)("Reserving large pages individually."); + char * p_buf = allocate_pages_individually(bytes, addr, flags, prot, LargePagesIndividualAllocationInjectError); if (p_buf == NULL) { // give an appropriate warning message @@ -3215,9 +3221,8 @@ return p_buf; } else { - if (TracePageSizes && Verbose) { - tty->print_cr("Reserving large pages in a single large chunk."); - } + log_debug(pagesize)("Reserving large pages in a single large chunk."); + // normal policy just allocate it all at once DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; char * res = (char *)VirtualAlloc(addr, bytes, flag, prot); @@ -4119,13 +4124,7 @@ guarantee(return_page != NULL, "Commit Failed for polling page"); os::set_polling_page(polling_page); - -#ifndef PRODUCT - if (Verbose && PrintMiscellaneous) { - tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", - (intptr_t)polling_page); - } -#endif + log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page)); if (!UseMembar) { address mem_serialize_page = (address)VirtualAlloc(NULL, os::vm_page_size(), MEM_RESERVE, PAGE_READWRITE); @@ -4135,13 +4134,7 @@ guarantee(return_page != NULL, "Commit Failed for memory serialize page"); os::set_memory_serialize_page(mem_serialize_page); - -#ifndef PRODUCT - if (Verbose && PrintMiscellaneous) { - tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", - (intptr_t)mem_serialize_page); - } -#endif + log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page)); } // Setup Windows Exceptions @@ -4609,6 +4602,9 @@ return 0; } +int os::fileno(FILE* fp) { + return _fileno(fp); +} // This code is a copy of JDK's sysSync // from src/windows/hpi/src/sys_api_md.c @@ -4769,10 +4765,7 @@ hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == NULL) { - if (PrintMiscellaneous && Verbose) { - DWORD err = GetLastError(); - tty->print_cr("CreateFile() failed: GetLastError->%ld.", err); - } + log_info(os)("CreateFile() failed: GetLastError->%ld.", GetLastError()); return NULL; } @@ -4790,10 +4783,7 @@ base = (char*) VirtualAlloc(addr, bytes, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (base == NULL) { - if (PrintMiscellaneous && Verbose) { - DWORD err = GetLastError(); - tty->print_cr("VirtualAlloc() failed: GetLastError->%ld.", err); - } + log_info(os)("VirtualAlloc() failed: GetLastError->%ld.", GetLastError()); CloseHandle(hFile); return NULL; } @@ -4807,10 +4797,7 @@ // number of bytes were read before returning. bool res = ReadFile(hFile, base, (DWORD)bytes, &bytes_read, &overlapped) != 0; if (!res) { - if (PrintMiscellaneous && Verbose) { - DWORD err = GetLastError(); - tty->print_cr("ReadFile() failed: GetLastError->%ld.", err); - } + log_info(os)("ReadFile() failed: GetLastError->%ld.", GetLastError()); release_memory(base, bytes); CloseHandle(hFile); return NULL; @@ -4819,10 +4806,7 @@ HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0, NULL /* file_name */); if (hMap == NULL) { - if (PrintMiscellaneous && Verbose) { - DWORD err = GetLastError(); - tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.", err); - } + log_info(os)("CreateFileMapping() failed: GetLastError->%ld.", GetLastError()); CloseHandle(hFile); return NULL; } @@ -4831,20 +4815,14 @@ base = (char*)MapViewOfFileEx(hMap, access, 0, (DWORD)file_offset, (DWORD)bytes, addr); if (base == NULL) { - if (PrintMiscellaneous && Verbose) { - DWORD err = GetLastError(); - tty->print_cr("MapViewOfFileEx() failed: GetLastError->%ld.", err); - } + log_info(os)("MapViewOfFileEx() failed: GetLastError->%ld.", GetLastError()); CloseHandle(hMap); CloseHandle(hFile); return NULL; } if (CloseHandle(hMap) == 0) { - if (PrintMiscellaneous && Verbose) { - DWORD err = GetLastError(); - tty->print_cr("CloseHandle(hMap) failed: GetLastError->%ld.", err); - } + log_info(os)("CloseHandle(hMap) failed: GetLastError->%ld.", GetLastError()); CloseHandle(hFile); return base; } @@ -4856,10 +4834,7 @@ bool res = VirtualProtect(base, bytes, exec_access, &old_protect) != 0; if (!res) { - if (PrintMiscellaneous && Verbose) { - DWORD err = GetLastError(); - tty->print_cr("VirtualProtect() failed: GetLastError->%ld.", err); - } + log_info(os)("VirtualProtect() failed: GetLastError->%ld.", GetLastError()); // Don't consider this a hard error, on IA32 even if the // VirtualProtect fails, we should still be able to execute CloseHandle(hFile); @@ -4868,10 +4843,7 @@ } if (CloseHandle(hFile) == 0) { - if (PrintMiscellaneous && Verbose) { - DWORD err = GetLastError(); - tty->print_cr("CloseHandle(hFile) failed: GetLastError->%ld.", err); - } + log_info(os)("CloseHandle(hFile) failed: GetLastError->%ld.", GetLastError()); return base; } @@ -4904,10 +4876,7 @@ bool os::pd_unmap_memory(char* addr, size_t bytes) { MEMORY_BASIC_INFORMATION mem_info; if (VirtualQuery(addr, &mem_info, sizeof(mem_info)) == 0) { - if (PrintMiscellaneous && Verbose) { - DWORD err = GetLastError(); - tty->print_cr("VirtualQuery() failed: GetLastError->%ld.", err); - } + log_info(os)("VirtualQuery() failed: GetLastError->%ld.", GetLastError()); return false; } @@ -4924,10 +4893,7 @@ BOOL result = UnmapViewOfFile(addr); if (result == 0) { - if (PrintMiscellaneous && Verbose) { - DWORD err = GetLastError(); - tty->print_cr("UnmapViewOfFile() failed: GetLastError->%ld.", err); - } + log_info(os)("UnmapViewOfFile() failed: GetLastError->%ld.", GetLastError()); return false; } return true;
--- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -184,9 +184,7 @@ if (os::Aix::chained_handler(sig, info, ucVoid)) { return 1; } else { - if (PrintMiscellaneous && (WizardMode || Verbose)) { - warning("Ignoring SIGPIPE - see bug 4229104"); - } + // Ignoring SIGPIPE - see bugs 4229104 return 1; } }
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -469,11 +469,7 @@ if (os::Bsd::chained_handler(sig, info, ucVoid)) { return true; } else { - if (PrintMiscellaneous && (WizardMode || Verbose)) { - char buf[64]; - warning("Ignoring %s - see bugs 4229104 or 646499219", - os::exception_name(sig, buf, sizeof(buf))); - } + // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219 return true; } } @@ -728,14 +724,10 @@ bool res = os::protect_memory((char*) page_start, page_size, os::MEM_PROT_RWX); - if (PrintMiscellaneous && Verbose) { - char buf[256]; - jio_snprintf(buf, sizeof(buf), "Execution protection violation " - "at " INTPTR_FORMAT - ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr, - page_start, (res ? "success" : "failed"), errno); - tty->print_raw_cr(buf); - } + log_debug(os)("Execution protection violation " + "at " INTPTR_FORMAT + ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr), + p2i(page_start), (res ? "success" : "failed"), errno); stub = pc; // Set last_addr so if we fault again at the same address, we don't end
--- a/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "memory/metaspaceShared.hpp" #include "runtime/frame.inline.hpp" #include "runtime/thread.inline.hpp" @@ -64,6 +65,14 @@ return false; } +#if INCLUDE_CDS + if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) { + // In the middle of a trampoline call. Bail out for safety. + // This happens rarely so shouldn't affect profiling. + return false; + } +#endif + frame ret_frame(ret_sp, ret_fp, addr.pc()); if (!ret_frame.safe_for_sender(jt)) { #if defined(COMPILER2) || INCLUDE_JVMCI
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -159,11 +159,7 @@ if (os::Bsd::chained_handler(sig, info, ucVoid)) { return true; } else { - if (PrintMiscellaneous && (WizardMode || Verbose)) { - char buf[64]; - warning("Ignoring %s - see bugs 4229104 or 646499219", - os::exception_name(sig, buf, sizeof(buf))); - } + // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219 return true; } }
--- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -270,11 +270,7 @@ if (os::Linux::chained_handler(sig, info, ucVoid)) { return true; } else { - if (PrintMiscellaneous && (WizardMode || Verbose)) { - char buf[64]; - warning("Ignoring %s - see bugs 4229104 or 646499219", - os::exception_name(sig, buf, sizeof(buf))); - } + // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219 return true; } }
--- a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -24,6 +24,7 @@ */ #include "precompiled.hpp" +#include "memory/metaspaceShared.hpp" #include "runtime/frame.inline.hpp" #include "runtime/thread.inline.hpp" @@ -66,6 +67,14 @@ return false; } +#if INCLUDE_CDS + if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) { + // In the middle of a trampoline call. Bail out for safety. + // This happens rarely so shouldn't affect profiling. + return false; + } +#endif + frame ret_frame(ret_sp, ret_fp, addr.pc()); if (!ret_frame.safe_for_sender(jt)) { #ifdef COMPILER2
--- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -198,9 +198,7 @@ if (os::Linux::chained_handler(sig, info, ucVoid)) { return true; } else { - if (PrintMiscellaneous && (WizardMode || Verbose)) { - warning("Ignoring SIGPIPE - see bug 4229104"); - } + // Ignoring SIGPIPE - see bugs 4229104 return true; } }
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -561,11 +561,7 @@ if (os::Linux::chained_handler(sig, info, ucVoid)) { return true; } else { - if (PrintMiscellaneous && (WizardMode || Verbose)) { - char buf[64]; - warning("Ignoring %s - see bugs 4229104 or 646499219", - os::exception_name(sig, buf, sizeof(buf))); - } + // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219 return true; } }
--- a/hotspot/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/linux_sparc/vm/thread_linux_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "memory/metaspaceShared.hpp" #include "runtime/frame.inline.hpp" #include "runtime/thread.inline.hpp" @@ -64,6 +65,14 @@ return false; } +#if INCLUDE_CDS + if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) { + // In the middle of a trampoline call. Bail out for safety. + // This happens rarely so shouldn't affect profiling. + return false; + } +#endif + // we were running Java code when SIGPROF came in if (isInJava) { // If we have a last_Java_sp, then the SIGPROF signal caught us
--- a/hotspot/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/linux_sparc/vm/vm_version_linux_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,12 +66,12 @@ features = generic_v9_m; if (detect_niagara()) { - if (PrintMiscellaneous && Verbose) { tty->print_cr("Detected Linux on Niagara"); } + log_info(os, cpu)("Detected Linux on Niagara"); features = niagara1_m | T_family_m; } if (detect_M_family()) { - if (PrintMiscellaneous && Verbose) { tty->print_cr("Detected Linux on M family"); } + log_info(os, cpu)("Detected Linux on M family"); features = sun4v_m | generic_v9_m | M_family_m | T_family_m; }
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -287,11 +287,7 @@ if (os::Linux::chained_handler(sig, info, ucVoid)) { return true; } else { - if (PrintMiscellaneous && (WizardMode || Verbose)) { - char buf[64]; - warning("Ignoring %s - see bugs 4229104 or 646499219", - os::exception_name(sig, buf, sizeof(buf))); - } + // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219 return true; } } @@ -542,14 +538,10 @@ bool res = os::protect_memory((char*) page_start, page_size, os::MEM_PROT_RWX); - if (PrintMiscellaneous && Verbose) { - char buf[256]; - jio_snprintf(buf, sizeof(buf), "Execution protection violation " - "at " INTPTR_FORMAT - ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr, - page_start, (res ? "success" : "failed"), errno); - tty->print_raw_cr(buf); - } + log_debug(os)("Execution protection violation " + "at " INTPTR_FORMAT + ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr), + p2i(page_start), (res ? "success" : "failed"), errno); stub = pc; // Set last_addr so if we fault again at the same address, we don't end @@ -645,12 +637,8 @@ int major = strtol(uts.release,&minor_string,10); int minor = strtol(minor_string+1,NULL,10); bool result = (major > 2 || (major==2 && minor >= 4)); -#ifndef PRODUCT - if (PrintMiscellaneous && Verbose) { - tty->print("OS version is %d.%d, which %s support SSE/SSE2\n", + log_info(os)("OS version is %d.%d, which %s support SSE/SSE2", major,minor, result ? "DOES" : "does NOT"); - } -#endif return result; #endif // AMD64 } @@ -939,9 +927,7 @@ MemTracker::record_virtual_memory_type((address)codebuf, mtInternal); - if (PrintMiscellaneous && (Verbose || WizardMode)) { - tty->print_cr("[CS limit NX emulation work-around, exec code at: %p]", codebuf); - } + log_info(os)("[CS limit NX emulation work-around, exec code at: %p]", codebuf); // Some code to exec: the 'ret' instruction codebuf[0] = 0xC3;
--- a/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/linux_x86/vm/thread_linux_x86.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "memory/metaspaceShared.hpp" #include "runtime/frame.inline.hpp" #include "runtime/thread.inline.hpp" @@ -65,6 +66,14 @@ return false; } +#if INCLUDE_CDS + if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) { + // In the middle of a trampoline call. Bail out for safety. + // This happens rarely so shouldn't affect profiling. + return false; + } +#endif + frame ret_frame(ret_sp, ret_fp, addr.pc()); if (!ret_frame.safe_for_sender(jt)) { #if defined(COMPILER2) || INCLUDE_JVMCI
--- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -154,11 +154,7 @@ if (os::Linux::chained_handler(sig, info, ucVoid)) { return true; } else { - if (PrintMiscellaneous && (WizardMode || Verbose)) { - char buf[64]; - warning("Ignoring %s - see bugs 4229104 or 646499219", - os::exception_name(sig, buf, sizeof(buf))); - } + // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219 return true; } }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -338,12 +338,7 @@ if (os::Solaris::chained_handler(sig, info, ucVoid)) { return true; } else { - if (PrintMiscellaneous && (WizardMode || Verbose)) { - char buf[64]; - warning("Ignoring %s - see 4229104 or 6499219", - os::exception_name(sig, buf, sizeof(buf))); - - } + // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219 return true; } }
--- a/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "memory/metaspaceShared.hpp" #include "runtime/frame.inline.hpp" #include "runtime/thread.inline.hpp" @@ -77,6 +78,14 @@ return false; } +#if INCLUDE_CDS + if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) { + // In the middle of a trampoline call. Bail out for safety. + // This happens rarely so shouldn't affect profiling. + return false; + } +#endif + frame ret_frame(ret_sp, frame::unpatchable, addr.pc()); // we were running Java code when SIGPROF came in
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "logging/log.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "runtime/os.hpp" @@ -361,15 +362,10 @@ assert(avn <= 2, "should return two or less av's"); uint_t av = avs[0]; -#ifndef PRODUCT - if (PrintMiscellaneous && Verbose) { - tty->print("getisax(2) returned: " PTR32_FORMAT, av); - if (avn > 1) { - tty->print(", " PTR32_FORMAT, avs[1]); - } - tty->cr(); + log_info(os, cpu)("getisax(2) returned: " PTR32_FORMAT, av); + if (avn > 1) { + log_info(os, cpu)(" " PTR32_FORMAT, avs[1]); } -#endif if (av & AV_SPARC_MUL32) features |= hardware_mul32_m; if (av & AV_SPARC_DIV32) features |= hardware_div32_m; @@ -464,11 +460,7 @@ if (strcmp((const char*)&(knm[i].name),"implementation") == 0) { implementation = KSTAT_NAMED_STR_PTR(&knm[i]); has_implementation = true; -#ifndef PRODUCT - if (PrintMiscellaneous && Verbose) { - tty->print_cr("cpu_info.implementation: %s", implementation); - } -#endif + log_info(os, cpu)("cpu_info.implementation: %s", implementation); features |= parse_features(implementation); break; }
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -403,12 +403,7 @@ if (os::Solaris::chained_handler(sig, info, ucVoid)) { return true; } else { - if (PrintMiscellaneous && (WizardMode || Verbose)) { - char buf[64]; - warning("Ignoring %s - see 4229104 or 6499219", - os::exception_name(sig, buf, sizeof(buf))); - - } + // Ignoring SIGPIPE/SIGXFSZ - see bugs 4229104 or 6499219 return true; } } @@ -640,14 +635,10 @@ bool res = os::protect_memory((char*) page_start, page_size, os::MEM_PROT_RWX); - if (PrintMiscellaneous && Verbose) { - char buf[256]; - jio_snprintf(buf, sizeof(buf), "Execution protection violation " - "at " INTPTR_FORMAT - ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr, - page_start, (res ? "success" : "failed"), errno); - tty->print_raw_cr(buf); - } + log_debug(os)("Execution protection violation " + "at " INTPTR_FORMAT + ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr), + p2i(page_start), (res ? "success" : "failed"), errno); stub = pc; // Set last_addr so if we fault again at the same address, we don't end
--- a/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/solaris_x86/vm/thread_solaris_x86.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "memory/metaspaceShared.hpp" #include "runtime/frame.inline.hpp" #include "runtime/thread.inline.hpp" @@ -70,6 +71,14 @@ return false; } +#if INCLUDE_CDS + if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) { + // In the middle of a trampoline call. Bail out for safety. + // This happens rarely so shouldn't affect profiling. + return false; + } +#endif + // If sp and fp are nonsense just leave them out if (!jt->on_local_stack((address)ret_sp)) {
--- a/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/os_cpu/windows_x86/vm/thread_windows_x86.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "memory/metaspaceShared.hpp" #include "runtime/frame.inline.hpp" #include "runtime/thread.inline.hpp" @@ -72,6 +73,14 @@ return false; } +#if INCLUDE_CDS + if (UseSharedSpaces && MetaspaceShared::is_in_shared_region(addr.pc(), MetaspaceShared::md)) { + // In the middle of a trampoline call. Bail out for safety. + // This happens rarely so shouldn't affect profiling. + return false; + } +#endif + frame ret_frame(ret_sp, ret_fp, addr.pc()); if (!ret_frame.safe_for_sender(jt)) { #if defined(COMPILER2) || INCLUDE_JVMCI
--- a/hotspot/src/share/vm/asm/assembler.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/asm/assembler.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -33,7 +33,6 @@ #include "runtime/vm_version.hpp" #include "utilities/debug.hpp" #include "utilities/growableArray.hpp" -#include "utilities/top.hpp" // This file contains platform-independent assembler declarations.
--- a/hotspot/src/share/vm/asm/register.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/asm/register.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -25,7 +25,8 @@ #ifndef SHARE_VM_ASM_REGISTER_HPP #define SHARE_VM_ASM_REGISTER_HPP -#include "utilities/top.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" // Use AbstractRegister as shortcut class AbstractRegisterImpl;
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -28,7 +28,6 @@ #include "c1/c1_CodeStubs.hpp" #include "ci/ciMethodData.hpp" #include "oops/methodData.hpp" -#include "utilities/top.hpp" class Compilation; class ScopeValue;
--- a/hotspot/src/share/vm/ci/ciFlags.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/ci/ciFlags.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -29,6 +29,7 @@ #include "memory/allocation.hpp" #include "prims/jvm.h" #include "utilities/accessFlags.hpp" +#include "utilities/ostream.hpp" // ciFlags //
--- a/hotspot/src/share/vm/classfile/classFileStream.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/classfile/classFileStream.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -25,8 +25,9 @@ #ifndef SHARE_VM_CLASSFILE_CLASSFILESTREAM_HPP #define SHARE_VM_CLASSFILE_CLASSFILESTREAM_HPP +#include "memory/allocation.hpp" #include "utilities/bytes.hpp" -#include "utilities/top.hpp" +#include "utilities/exceptions.hpp" // Input stream for reading .class file //
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/classfile/classLoader.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -233,6 +233,7 @@ strcpy(copy, zip_name); _zip_name = copy; _is_boot_append = is_boot_append; + _multi_versioned = _unknown; } ClassPathZipEntry::~ClassPathZipEntry() { @@ -330,13 +331,20 @@ bool ClassPathZipEntry::is_multiple_versioned(TRAPS) { assert(DumpSharedSpaces, "called only at dump time"); + if (_multi_versioned != _unknown) { + return (_multi_versioned == _yes) ? true : false; + } jint size; - char* buffer = (char*)open_entry("META-INF/MANIFEST.MF", &size, false, CHECK_false); + char* buffer = (char*)open_entry("META-INF/MANIFEST.MF", &size, true, CHECK_false); if (buffer != NULL) { - if (strstr(buffer, "Multi-Release: true") != NULL) { + char* p = buffer; + for ( ; *p; ++p) *p = tolower(*p); + if (strstr(buffer, "multi-release: true") != NULL) { + _multi_versioned = _yes; return true; } } + _multi_versioned = _no; return false; } #endif // INCLUDE_CDS
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/classfile/classLoader.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -101,10 +101,17 @@ class ClassPathZipEntry: public ClassPathEntry { + enum { + _unknown = 0, + _yes = 1, + _no = 2 + }; private: jzfile* _zip; // The zip archive const char* _zip_name; // Name of zip archive bool _is_boot_append; // entry coming from -Xbootclasspath/a + u1 _multi_versioned; // indicates if the jar file has multi-versioned entries. + // It can have value of "_unknown", "_yes", or "_no" public: bool is_jrt() { return false; } bool is_jar_file() const { return true; }
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -373,13 +373,10 @@ // Lazily create the package entry table at first request. if (_packages == NULL) { MutexLockerEx m1(metaspace_lock(), Mutex::_no_safepoint_check_flag); - // Check again if _packages has been allocated while we were getting this lock. - if (_packages != NULL) { - return _packages; + // Check if _packages got allocated while we were waiting for this lock. + if (_packages == NULL) { + _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size); } - // Ensure _packages is stable, since it is examined without a lock - OrderAccess::storestore(); - _packages = new PackageEntryTable(PackageEntryTable::_packagetable_entry_size); } return _packages; }
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -2187,43 +2187,19 @@ } Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* holder, TRAPS) { - if (MemberNameInStackFrame) { - Handle mname(THREAD, stackFrame->obj_field(_memberName_offset)); - Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mname()); - // we should expand MemberName::name when Throwable uses StackTrace - // MethodHandles::expand_MemberName(mname, MethodHandles::_suppress_defc|MethodHandles::_suppress_type, CHECK_NULL); - return method; - } else { - short mid = stackFrame->short_field(_mid_offset); - short version = stackFrame->short_field(_version_offset); - return holder->method_with_orig_idnum(mid, version); - } -} - -Symbol* java_lang_StackFrameInfo::get_file_name(Handle stackFrame, InstanceKlass* holder) { - if (MemberNameInStackFrame) { - return holder->source_file_name(); - } else { - short version = stackFrame->short_field(_version_offset); - return Backtrace::get_source_file_name(holder, version); - } + Handle mname(THREAD, stackFrame->obj_field(_memberName_offset)); + Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mname()); + // we should expand MemberName::name when Throwable uses StackTrace + // MethodHandles::expand_MemberName(mname, MethodHandles::_suppress_defc|MethodHandles::_suppress_type, CHECK_NULL); + return method; } void java_lang_StackFrameInfo::set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci) { // set Method* or mid/cpref - if (MemberNameInStackFrame) { - oop mname = stackFrame->obj_field(_memberName_offset); - InstanceKlass* ik = method->method_holder(); - CallInfo info(method(), ik); - MethodHandles::init_method_MemberName(mname, info); - } else { - int mid = method->orig_method_idnum(); - int cpref = method->name_index(); - assert((jushort)mid == mid, "mid should be short"); - assert((jushort)cpref == cpref, "cpref should be short"); - java_lang_StackFrameInfo::set_mid(stackFrame(), (short)mid); - java_lang_StackFrameInfo::set_cpref(stackFrame(), (short)cpref); - } + oop mname = stackFrame->obj_field(_memberName_offset); + InstanceKlass* ik = method->method_holder(); + CallInfo info(method(), ik); + MethodHandles::init_method_MemberName(mname, info); // set bci java_lang_StackFrameInfo::set_bci(stackFrame(), bci); // method may be redefined; store the version @@ -2232,52 +2208,23 @@ java_lang_StackFrameInfo::set_version(stackFrame(), (short)version); } -void java_lang_StackFrameInfo::fill_methodInfo(Handle stackFrame, TRAPS) { +void java_lang_StackFrameInfo::to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS) { ResourceMark rm(THREAD); - oop k = stackFrame->obj_field(_declaringClass_offset); - InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k)); + Handle k (THREAD, stackFrame->obj_field(_declaringClass_offset)); + InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k())); Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK); - int bci = stackFrame->int_field(_bci_offset); - - // The method can be NULL if the requested class version is gone - Symbol* sym = (method != NULL) ? method->name() : NULL; - if (MemberNameInStackFrame) { - assert(sym != NULL, "MemberName must have method name"); - } else { - // The method can be NULL if the requested class version is gone - if (sym == NULL) { - short cpref = stackFrame->short_field(_cpref_offset); - sym = holder->constants()->symbol_at(cpref); - } - } - - // set method name - oop methodname = StringTable::intern(sym, CHECK); - java_lang_StackFrameInfo::set_methodName(stackFrame(), methodname); - - // set file name and line number - Symbol* source = get_file_name(stackFrame, holder); - if (source != NULL) { - oop filename = StringTable::intern(source, CHECK); - java_lang_StackFrameInfo::set_fileName(stackFrame(), filename); - } - - // if the method has been redefined, the bci is no longer applicable + short version = stackFrame->short_field(_version_offset); - if (version_matches(method, version)) { - int line_number = Backtrace::get_line_number(method, bci); - java_lang_StackFrameInfo::set_lineNumber(stackFrame(), line_number); - } + short bci = stackFrame->short_field(_bci_offset); + int cpref = method->name_index(); + java_lang_StackTraceElement::fill_in(stack_trace_element, holder, method, version, bci, cpref, CHECK); } void java_lang_StackFrameInfo::compute_offsets() { Klass* k = SystemDictionary::StackFrameInfo_klass(); compute_offset(_declaringClass_offset, k, vmSymbols::declaringClass_name(), vmSymbols::class_signature()); compute_offset(_memberName_offset, k, vmSymbols::memberName_name(), vmSymbols::object_signature()); - compute_offset(_bci_offset, k, vmSymbols::bci_name(), vmSymbols::int_signature()); - compute_offset(_methodName_offset, k, vmSymbols::methodName_name(), vmSymbols::string_signature()); - compute_offset(_fileName_offset, k, vmSymbols::fileName_name(), vmSymbols::string_signature()); - compute_offset(_lineNumber_offset, k, vmSymbols::lineNumber_name(), vmSymbols::int_signature()); + compute_offset(_bci_offset, k, vmSymbols::bci_name(), vmSymbols::short_signature()); STACKFRAMEINFO_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); } @@ -3690,12 +3637,7 @@ int java_lang_StackFrameInfo::_declaringClass_offset; int java_lang_StackFrameInfo::_memberName_offset; int java_lang_StackFrameInfo::_bci_offset; -int java_lang_StackFrameInfo::_methodName_offset; -int java_lang_StackFrameInfo::_fileName_offset; -int java_lang_StackFrameInfo::_lineNumber_offset; -int java_lang_StackFrameInfo::_mid_offset; int java_lang_StackFrameInfo::_version_offset; -int java_lang_StackFrameInfo::_cpref_offset; int java_lang_LiveStackFrameInfo::_monitors_offset; int java_lang_LiveStackFrameInfo::_locals_offset; int java_lang_LiveStackFrameInfo::_operands_offset; @@ -3741,34 +3683,14 @@ element->obj_field_put(_declaringClass_offset, value); } -void java_lang_StackFrameInfo::set_mid(oop element, short value) { - element->short_field_put(_mid_offset, value); -} - void java_lang_StackFrameInfo::set_version(oop element, short value) { element->short_field_put(_version_offset, value); } -void java_lang_StackFrameInfo::set_cpref(oop element, short value) { - element->short_field_put(_cpref_offset, value); -} - void java_lang_StackFrameInfo::set_bci(oop element, int value) { element->int_field_put(_bci_offset, value); } -void java_lang_StackFrameInfo::set_fileName(oop element, oop value) { - element->obj_field_put(_fileName_offset, value); -} - -void java_lang_StackFrameInfo::set_methodName(oop element, oop value) { - element->obj_field_put(_methodName_offset, value); -} - -void java_lang_StackFrameInfo::set_lineNumber(oop element, int value) { - element->int_field_put(_lineNumber_offset, value); -} - void java_lang_LiveStackFrameInfo::set_monitors(oop element, oop value) { element->obj_field_put(_monitors_offset, value); }
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -1364,25 +1364,16 @@ // Interface to java.lang.StackFrameInfo objects #define STACKFRAMEINFO_INJECTED_FIELDS(macro) \ - macro(java_lang_StackFrameInfo, mid, short_signature, false) \ - macro(java_lang_StackFrameInfo, version, short_signature, false) \ - macro(java_lang_StackFrameInfo, cpref, short_signature, false) + macro(java_lang_StackFrameInfo, version, short_signature, false) class java_lang_StackFrameInfo: AllStatic { private: static int _declaringClass_offset; static int _memberName_offset; static int _bci_offset; - static int _methodName_offset; - static int _fileName_offset; - static int _lineNumber_offset; - - static int _mid_offset; static int _version_offset; - static int _cpref_offset; static Method* get_method(Handle stackFrame, InstanceKlass* holder, TRAPS); - static Symbol* get_file_name(Handle stackFrame, InstanceKlass* holder); public: // Setters @@ -1390,19 +1381,12 @@ static void set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci); static void set_bci(oop info, int value); - // set method info in an instance of StackFrameInfo - static void fill_methodInfo(Handle info, TRAPS); - static void set_methodName(oop info, oop value); - static void set_fileName(oop info, oop value); - static void set_lineNumber(oop info, int value); - - // these injected fields are only used if -XX:-MemberNameInStackFrame set - static void set_mid(oop info, short value); static void set_version(oop info, short value); - static void set_cpref(oop info, short value); static void compute_offsets(); + static void to_stack_trace_element(Handle stackFrame, Handle stack_trace_element, TRAPS); + // Debugging friend class JavaClasses; };
--- a/hotspot/src/share/vm/classfile/javaClasses.inline.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/classfile/javaClasses.inline.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -222,20 +222,17 @@ return line_number; } -/* - * Returns the source file name of a given InstanceKlass and version - */ inline Symbol* Backtrace::get_source_file_name(InstanceKlass* holder, int version) { - // Find the specific ik version that contains this source_file_name_index - // via the previous versions list, but use the current version's - // constant pool to look it up. The previous version's index has been - // merged for the current constant pool. - InstanceKlass* ik = holder->get_klass_version(version); - // This version has been cleaned up. - if (ik == NULL) return NULL; - int source_file_name_index = ik->source_file_name_index(); - return (source_file_name_index == 0) ? - (Symbol*)NULL : holder->constants()->symbol_at(source_file_name_index); + // RedefineClasses() currently permits redefine operations to + // happen in parallel using a "last one wins" philosophy. That + // spec laxness allows the constant pool entry associated with + // the source_file_name_index for any older constant pool version + // to be unstable so we shouldn't try to use it. + if (holder->constants()->version() != version) { + return NULL; + } else { + return holder->source_file_name(); + } } #endif // SHARE_VM_CLASSFILE_JAVACLASSES_INLINE_HPP
--- a/hotspot/src/share/vm/code/relocInfo.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/code/relocInfo.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -26,8 +26,9 @@ #define SHARE_VM_CODE_RELOCINFO_HPP #include "memory/allocation.hpp" -#include "utilities/top.hpp" +#include "runtime/os.hpp" +class Metadata; class NativeMovConstReg; // Types in this file:
--- a/hotspot/src/share/vm/code/vmreg.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/code/vmreg.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -28,10 +28,9 @@ #include "asm/register.hpp" #include "memory/allocation.hpp" #include "utilities/globalDefinitions.hpp" - +#include "utilities/ostream.hpp" #ifdef COMPILER2 #include "opto/adlcVMDeps.hpp" -#include "utilities/ostream.hpp" #endif //------------------------------VMReg------------------------------------------
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -32,6 +32,7 @@ #include "gc/shared/genCollectedHeap.hpp" #include "gc/shared/space.inline.hpp" #include "gc/shared/spaceDecorator.hpp" +#include "logging/logStream.inline.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.inline.hpp" @@ -505,10 +506,13 @@ return; } log.debug("%s", title); - _dictionary->report_statistics(log.debug_stream()); + + LogStream out(log.debug()); + _dictionary->report_statistics(&out); + if (log.is_trace()) { - ResourceMark rm; - reportIndexedFreeListStatistics(log.trace_stream()); + LogStream trace_out(log.trace()); + reportIndexedFreeListStatistics(&trace_out); size_t total_size = totalSizeInIndexedFreeLists() + _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock())); log.trace(" free=" SIZE_FORMAT " frag=%1.4f", total_size, flsFrag()); @@ -2836,6 +2840,11 @@ par_get_chunk_of_blocks_dictionary(word_sz, n, fl); } +const size_t CompactibleFreeListSpace::max_flag_size_for_task_size() const { + const size_t ergo_max = _old_gen->reserved().word_size() / (CardTableModRefBS::card_size_in_words * BitsPerWord); + return ergo_max; +} + // Set up the space's par_seq_tasks structure for work claiming // for parallel rescan. See CMSParRemarkTask where this is currently used. // XXX Need to suitably abstract and generalize this and the next
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -345,6 +345,8 @@ // Support for parallelization of rescan and marking. const size_t rescan_task_size() const { return _rescan_task_size; } const size_t marking_task_size() const { return _marking_task_size; } + // Return ergonomic max size for CMSRescanMultiple and CMSConcMarkMultiple. + const size_t max_flag_size_for_task_size() const; SequentialSubTasksDone* conc_par_seq_tasks() {return &_conc_par_seq_tasks; } void initialize_sequential_subtasks_for_rescan(int n_threads); void initialize_sequential_subtasks_for_marking(int n_threads,
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -425,7 +425,7 @@ st->print(",cms_consumption_rate=%g,time_until_full=%g", cms_consumption_rate(), time_until_cms_gen_full()); } - st->print(" "); + st->cr(); } #endif // #ifndef PRODUCT @@ -1108,8 +1108,10 @@ } bool CMSCollector::shouldConcurrentCollect() { + LogTarget(Trace, gc) log; + if (_full_gc_requested) { - log_trace(gc)("CMSCollector: collect because of explicit gc request (or GCLocker)"); + log.print("CMSCollector: collect because of explicit gc request (or GCLocker)"); return true; } @@ -1117,21 +1119,22 @@ // ------------------------------------------------------------------ // Print out lots of information which affects the initiation of // a collection. - Log(gc) log; - if (log.is_trace() && stats().valid()) { - log.trace("CMSCollector shouldConcurrentCollect: "); - ResourceMark rm; - stats().print_on(log.debug_stream()); - log.trace("time_until_cms_gen_full %3.7f", stats().time_until_cms_gen_full()); - log.trace("free=" SIZE_FORMAT, _cmsGen->free()); - log.trace("contiguous_available=" SIZE_FORMAT, _cmsGen->contiguous_available()); - log.trace("promotion_rate=%g", stats().promotion_rate()); - log.trace("cms_allocation_rate=%g", stats().cms_allocation_rate()); - log.trace("occupancy=%3.7f", _cmsGen->occupancy()); - log.trace("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy()); - log.trace("cms_time_since_begin=%3.7f", stats().cms_time_since_begin()); - log.trace("cms_time_since_end=%3.7f", stats().cms_time_since_end()); - log.trace("metadata initialized %d", MetaspaceGC::should_concurrent_collect()); + if (log.is_enabled() && stats().valid()) { + log.print("CMSCollector shouldConcurrentCollect: "); + + LogStream out(log); + stats().print_on(&out); + + log.print("time_until_cms_gen_full %3.7f", stats().time_until_cms_gen_full()); + log.print("free=" SIZE_FORMAT, _cmsGen->free()); + log.print("contiguous_available=" SIZE_FORMAT, _cmsGen->contiguous_available()); + log.print("promotion_rate=%g", stats().promotion_rate()); + log.print("cms_allocation_rate=%g", stats().cms_allocation_rate()); + log.print("occupancy=%3.7f", _cmsGen->occupancy()); + log.print("initiatingOccupancy=%3.7f", _cmsGen->initiating_occupancy()); + log.print("cms_time_since_begin=%3.7f", stats().cms_time_since_begin()); + log.print("cms_time_since_end=%3.7f", stats().cms_time_since_end()); + log.print("metadata initialized %d", MetaspaceGC::should_concurrent_collect()); } // ------------------------------------------------------------------ @@ -1149,8 +1152,8 @@ // this branch will not fire after the first successful CMS // collection because the stats should then be valid. if (_cmsGen->occupancy() >= _bootstrap_occupancy) { - log_trace(gc)(" CMSCollector: collect for bootstrapping statistics: occupancy = %f, boot occupancy = %f", - _cmsGen->occupancy(), _bootstrap_occupancy); + log.print(" CMSCollector: collect for bootstrapping statistics: occupancy = %f, boot occupancy = %f", + _cmsGen->occupancy(), _bootstrap_occupancy); return true; } } @@ -1162,7 +1165,7 @@ // XXX We need to make sure that the gen expansion // criterion dovetails well with this. XXX NEED TO FIX THIS if (_cmsGen->should_concurrent_collect()) { - log_trace(gc)("CMS old gen initiated"); + log.print("CMS old gen initiated"); return true; } @@ -1173,12 +1176,12 @@ assert(gch->collector_policy()->is_generation_policy(), "You may want to check the correctness of the following"); if (gch->incremental_collection_will_fail(true /* consult_young */)) { - log_trace(gc)("CMSCollector: collect because incremental collection will fail "); + log.print("CMSCollector: collect because incremental collection will fail "); return true; } if (MetaspaceGC::should_concurrent_collect()) { - log_trace(gc)("CMSCollector: collect for metadata allocation "); + log.print("CMSCollector: collect for metadata allocation "); return true; } @@ -1193,10 +1196,10 @@ // as we want to be able to trigger the first CMS cycle as well) if (stats().cms_time_since_begin() >= (CMSTriggerInterval / ((double) MILLIUNITS))) { if (stats().valid()) { - log_trace(gc)("CMSCollector: collect because of trigger interval (time since last begin %3.7f secs)", - stats().cms_time_since_begin()); + log.print("CMSCollector: collect because of trigger interval (time since last begin %3.7f secs)", + stats().cms_time_since_begin()); } else { - log_trace(gc)("CMSCollector: collect because of trigger interval (first collection)"); + log.print("CMSCollector: collect because of trigger interval (first collection)"); } return true; } @@ -3598,7 +3601,7 @@ size_t capacity = get_eden_capacity(); // Don't start sampling unless we will get sufficiently // many samples. - if (used < (capacity/(CMSScheduleRemarkSamplingRatio * 100) + if (used < (((capacity / CMSScheduleRemarkSamplingRatio) / 100) * CMSScheduleRemarkEdenPenetration)) { _start_sampling = true; } else {
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -28,6 +28,7 @@ #include "gc/g1/g1Analytics.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectorPolicy.hpp" +#include "gc/g1/g1ConcurrentMark.inline.hpp" #include "gc/g1/g1MMUTracker.hpp" #include "gc/g1/suspendibleThreadSet.hpp" #include "gc/g1/vm_operations_g1.hpp" @@ -183,6 +184,11 @@ } } while (cm()->restart_for_overflow()); + if (!cm()->has_aborted()) { + G1ConcPhaseTimer t(_cm, "Concurrent Create Live Data"); + cm()->create_live_data(); + } + double end_time = os::elapsedVTime(); // Update the total virtual time before doing this, since it will try // to measure it to get the vtime for this marking. We purposely
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,558 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1ConcurrentMark.inline.hpp" +#include "gc/g1/g1CardLiveData.inline.hpp" +#include "gc/g1/suspendibleThreadSet.hpp" +#include "gc/shared/workgroup.hpp" +#include "memory/universe.hpp" +#include "runtime/atomic.inline.hpp" +#include "runtime/globals.hpp" +#include "runtime/os.hpp" +#include "utilities/bitMap.inline.hpp" +#include "utilities/debug.hpp" + +G1CardLiveData::G1CardLiveData() : + _max_capacity(0), + _cards_per_region(0), + _live_regions(NULL), + _live_regions_size_in_bits(0), + _live_cards(NULL), + _live_cards_size_in_bits(0) { +} + +G1CardLiveData::~G1CardLiveData() { + free_large_bitmap(_live_cards, _live_cards_size_in_bits); + free_large_bitmap(_live_regions, _live_regions_size_in_bits); +} + +G1CardLiveData::bm_word_t* G1CardLiveData::allocate_large_bitmap(size_t size_in_bits) { + size_t size_in_words = BitMap::calc_size_in_words(size_in_bits); + + bm_word_t* map = MmapArrayAllocator<bm_word_t, mtGC>::allocate(size_in_words); + + return map; +} + +void G1CardLiveData::free_large_bitmap(bm_word_t* bitmap, size_t size_in_bits) { + MmapArrayAllocator<bm_word_t, mtGC>::free(bitmap, size_in_bits / BitsPerWord); +} + +void G1CardLiveData::initialize(size_t max_capacity, uint num_max_regions) { + assert(max_capacity % num_max_regions == 0, + "Given capacity must be evenly divisible by region size."); + size_t region_size = max_capacity / num_max_regions; + assert(region_size % (G1SATBCardTableModRefBS::card_size * BitsPerWord) == 0, + "Region size must be evenly divisible by area covered by a single word."); + _max_capacity = max_capacity; + _cards_per_region = region_size / G1SATBCardTableModRefBS::card_size; + + _live_regions_size_in_bits = live_region_bitmap_size_in_bits(); + _live_regions = allocate_large_bitmap(_live_regions_size_in_bits); + _live_cards_size_in_bits = live_card_bitmap_size_in_bits(); + _live_cards = allocate_large_bitmap(_live_cards_size_in_bits); +} + +void G1CardLiveData::pretouch() { + live_cards_bm().pretouch(); + live_regions_bm().pretouch(); +} + +size_t G1CardLiveData::live_region_bitmap_size_in_bits() const { + return _max_capacity / (_cards_per_region << G1SATBCardTableModRefBS::card_shift); +} + +size_t G1CardLiveData::live_card_bitmap_size_in_bits() const { + return _max_capacity >> G1SATBCardTableModRefBS::card_shift; +} + +// Helper class that provides functionality to generate the Live Data Count +// information. +class G1CardLiveDataHelper VALUE_OBJ_CLASS_SPEC { +private: + BitMap _region_bm; + BitMap _card_bm; + + // The card number of the bottom of the G1 heap. + // Used in biasing indices into accounting card bitmaps. + BitMap::idx_t _heap_card_bias; + + // Utility routine to set an exclusive range of bits on the given + // bitmap, optimized for very small ranges. + // There must be at least one bit to set. + void set_card_bitmap_range(BitMap::idx_t start_idx, + BitMap::idx_t end_idx) { + + // Set the exclusive bit range [start_idx, end_idx). + assert((end_idx - start_idx) > 0, "at least one bit"); + + // For small ranges use a simple loop; otherwise use set_range. + // The range is made up of the cards that are spanned by an object/mem + // region so 8 cards will allow up to object sizes up to 4K to be handled + // using the loop. + if ((end_idx - start_idx) <= 8) { + for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) { + _card_bm.set_bit(i); + } + } else { + _card_bm.set_range(start_idx, end_idx); + } + } + + // We cache the last mark set. This avoids setting the same bit multiple times. + // This is particularly interesting for dense bitmaps, as this avoids doing + // lots of work most of the time. + BitMap::idx_t _last_marked_bit_idx; + + // Mark the card liveness bitmap for the object spanning from start to end. + void mark_card_bitmap_range(HeapWord* start, HeapWord* end) { + BitMap::idx_t start_idx = card_live_bitmap_index_for(start); + BitMap::idx_t end_idx = card_live_bitmap_index_for((HeapWord*)align_ptr_up(end, CardTableModRefBS::card_size)); + + assert((end_idx - start_idx) > 0, "Trying to mark zero sized range."); + + if (start_idx == _last_marked_bit_idx) { + start_idx++; + } + if (start_idx == end_idx) { + return; + } + + // Set the bits in the card bitmap for the cards spanned by this object. + set_card_bitmap_range(start_idx, end_idx); + _last_marked_bit_idx = end_idx - 1; + } + + void reset_mark_cache() { + _last_marked_bit_idx = (BitMap::idx_t)-1; + } + +public: + // Returns the index in the per-card liveness count bitmap + // for the given address + inline BitMap::idx_t card_live_bitmap_index_for(HeapWord* addr) { + // Below, the term "card num" means the result of shifting an address + // by the card shift -- address 0 corresponds to card number 0. One + // must subtract the card num of the bottom of the heap to obtain a + // card table index. + BitMap::idx_t card_num = uintptr_t(addr) >> CardTableModRefBS::card_shift; + return card_num - _heap_card_bias; + } + + // Takes a region that's not empty (i.e., it has at least one + // live object in it and sets its corresponding bit on the region + // bitmap to 1. + void set_bit_for_region(HeapRegion* hr) { + _region_bm.par_set_bit(hr->hrm_index()); + } + + // Mark the range of bits covered by allocations done since the last marking + // in the given heap region, i.e. from NTAMS to top of the given region. + // Returns if there has been some allocation in this region since the last marking. + bool mark_allocated_since_marking(HeapRegion* hr) { + reset_mark_cache(); + + HeapWord* ntams = hr->next_top_at_mark_start(); + HeapWord* top = hr->top(); + + assert(hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions."); + + // Mark the allocated-since-marking portion... + if (ntams < top) { + mark_card_bitmap_range(ntams, top); + return true; + } else { + return false; + } + } + + // Mark the range of bits covered by live objects on the mark bitmap between + // bottom and NTAMS of the given region. + // Returns the number of live bytes marked within that area for the given + // heap region. + size_t mark_marked_during_marking(G1CMBitMap* mark_bitmap, HeapRegion* hr) { + reset_mark_cache(); + + size_t marked_bytes = 0; + + HeapWord* ntams = hr->next_top_at_mark_start(); + HeapWord* start = hr->bottom(); + + if (ntams <= start) { + // Skip empty regions. + return 0; + } + if (hr->is_humongous()) { + HeapRegion* start_region = hr->humongous_start_region(); + if (mark_bitmap->isMarked(start_region->bottom())) { + mark_card_bitmap_range(start, hr->top()); + return pointer_delta(hr->top(), start, 1); + } else { + // Humongous start object was actually dead. + return 0; + } + } + + assert(start <= hr->end() && start <= ntams && ntams <= hr->end(), + "Preconditions not met - " + "start: " PTR_FORMAT ", ntams: " PTR_FORMAT ", end: " PTR_FORMAT, + p2i(start), p2i(ntams), p2i(hr->end())); + + // Find the first marked object at or after "start". + start = mark_bitmap->getNextMarkedWordAddress(start, ntams); + while (start < ntams) { + oop obj = oop(start); + size_t obj_size = obj->size(); + HeapWord* obj_end = start + obj_size; + + assert(obj_end <= hr->end(), "Humongous objects must have been handled elsewhere."); + + mark_card_bitmap_range(start, obj_end); + + // Add the size of this object to the number of marked bytes. + marked_bytes += obj_size * HeapWordSize; + + // Find the next marked object after this one. + start = mark_bitmap->getNextMarkedWordAddress(obj_end, ntams); + } + + return marked_bytes; + } + + G1CardLiveDataHelper(G1CardLiveData* live_data, HeapWord* base_address) : + _region_bm(live_data->live_regions_bm()), + _card_bm(live_data->live_cards_bm()) { + // Calculate the card number for the bottom of the heap. Used + // in biasing indexes into the accounting card bitmaps. + _heap_card_bias = + uintptr_t(base_address) >> CardTableModRefBS::card_shift; + } +}; + +class G1CreateCardLiveDataTask: public AbstractGangTask { + // Aggregate the counting data that was constructed concurrently + // with marking. + class G1CreateLiveDataClosure : public HeapRegionClosure { + G1CardLiveDataHelper _helper; + + G1CMBitMap* _mark_bitmap; + + G1ConcurrentMark* _cm; + public: + G1CreateLiveDataClosure(G1CollectedHeap* g1h, + G1ConcurrentMark* cm, + G1CMBitMap* mark_bitmap, + G1CardLiveData* live_data) : + HeapRegionClosure(), + _helper(live_data, g1h->reserved_region().start()), + _mark_bitmap(mark_bitmap), + _cm(cm) { } + + bool doHeapRegion(HeapRegion* hr) { + size_t marked_bytes = _helper.mark_marked_during_marking(_mark_bitmap, hr); + if (marked_bytes > 0) { + hr->add_to_marked_bytes(marked_bytes); + } + + return (_cm->do_yield_check() && _cm->has_aborted()); + } + }; + + G1ConcurrentMark* _cm; + G1CardLiveData* _live_data; + HeapRegionClaimer _hr_claimer; + +public: + G1CreateCardLiveDataTask(G1CMBitMap* bitmap, + G1CardLiveData* live_data, + uint n_workers) : + AbstractGangTask("G1 Create Live Data"), + _live_data(live_data), + _hr_claimer(n_workers) { + } + + void work(uint worker_id) { + SuspendibleThreadSetJoiner sts_join; + + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + G1ConcurrentMark* cm = g1h->concurrent_mark(); + G1CreateLiveDataClosure cl(g1h, cm, cm->nextMarkBitMap(), _live_data); + g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer); + } +}; + +void G1CardLiveData::create(WorkGang* workers, G1CMBitMap* mark_bitmap) { + uint n_workers = workers->active_workers(); + + G1CreateCardLiveDataTask cl(mark_bitmap, + this, + n_workers); + workers->run_task(&cl); +} + +class G1FinalizeCardLiveDataTask: public AbstractGangTask { + // Finalizes the liveness counting data. + // Sets the bits corresponding to the interval [NTAMS, top] + // (which contains the implicitly live objects) in the + // card liveness bitmap. Also sets the bit for each region + // containing live data, in the region liveness bitmap. + class G1FinalizeCardLiveDataClosure: public HeapRegionClosure { + private: + G1CardLiveDataHelper _helper; + public: + G1FinalizeCardLiveDataClosure(G1CollectedHeap* g1h, + G1CMBitMap* bitmap, + G1CardLiveData* live_data) : + HeapRegionClosure(), + _helper(live_data, g1h->reserved_region().start()) { } + + bool doHeapRegion(HeapRegion* hr) { + bool allocated_since_marking = _helper.mark_allocated_since_marking(hr); + if (allocated_since_marking || hr->next_marked_bytes() > 0) { + _helper.set_bit_for_region(hr); + } + return false; + } + }; + + G1CMBitMap* _bitmap; + + G1CardLiveData* _live_data; + + HeapRegionClaimer _hr_claimer; + +public: + G1FinalizeCardLiveDataTask(G1CMBitMap* bitmap, G1CardLiveData* live_data, uint n_workers) : + AbstractGangTask("G1 Finalize Card Live Data"), + _bitmap(bitmap), + _live_data(live_data), + _hr_claimer(n_workers) { + } + + void work(uint worker_id) { + G1FinalizeCardLiveDataClosure cl(G1CollectedHeap::heap(), _bitmap, _live_data); + + G1CollectedHeap::heap()->heap_region_par_iterate(&cl, worker_id, &_hr_claimer); + } +}; + +void G1CardLiveData::finalize(WorkGang* workers, G1CMBitMap* mark_bitmap) { + // Finalize the live data. + G1FinalizeCardLiveDataTask cl(mark_bitmap, + this, + workers->active_workers()); + workers->run_task(&cl); +} + +class G1ClearCardLiveDataTask : public AbstractGangTask { + BitMap _bitmap; + size_t _num_chunks; + size_t _cur_chunk; +public: + G1ClearCardLiveDataTask(BitMap bitmap, size_t num_tasks) : + AbstractGangTask("G1 Clear Card Live Data"), + _bitmap(bitmap), + _num_chunks(num_tasks), + _cur_chunk(0) { + } + + static size_t chunk_size() { return M; } + + virtual void work(uint worker_id) { + while (true) { + size_t to_process = Atomic::add(1, &_cur_chunk) - 1; + if (to_process >= _num_chunks) { + break; + } + + BitMap::idx_t start = M * BitsPerByte * to_process; + BitMap::idx_t end = MIN2(start + M * BitsPerByte, _bitmap.size()); + _bitmap.clear_range(start, end); + } + } +}; + +void G1CardLiveData::clear(WorkGang* workers) { + guarantee(Universe::is_fully_initialized(), "Should not call this during initialization."); + + size_t const num_chunks = align_size_up(live_cards_bm().size_in_bytes(), G1ClearCardLiveDataTask::chunk_size()) / G1ClearCardLiveDataTask::chunk_size(); + + G1ClearCardLiveDataTask cl(live_cards_bm(), num_chunks); + workers->run_task(&cl); + + // The region live bitmap is always very small, even for huge heaps. Clear + // directly. + live_regions_bm().clear(); +} + +class G1VerifyCardLiveDataTask: public AbstractGangTask { + // Heap region closure used for verifying the live count data + // that was created concurrently and finalized during + // the remark pause. This closure is applied to the heap + // regions during the STW cleanup pause. + class G1VerifyCardLiveDataClosure: public HeapRegionClosure { + private: + G1CollectedHeap* _g1h; + G1CMBitMap* _mark_bitmap; + G1CardLiveDataHelper _helper; + + G1CardLiveData* _act_live_data; + + G1CardLiveData* _exp_live_data; + + int _failures; + + // Completely recreates the live data count for the given heap region and + // returns the number of bytes marked. + size_t create_live_data_count(HeapRegion* hr) { + size_t bytes_marked = _helper.mark_marked_during_marking(_mark_bitmap, hr); + bool allocated_since_marking = _helper.mark_allocated_since_marking(hr); + if (allocated_since_marking || bytes_marked > 0) { + _helper.set_bit_for_region(hr); + } + return bytes_marked; + } + public: + G1VerifyCardLiveDataClosure(G1CollectedHeap* g1h, + G1CMBitMap* mark_bitmap, + G1CardLiveData* act_live_data, + G1CardLiveData* exp_live_data) : + _g1h(g1h), + _mark_bitmap(mark_bitmap), + _helper(exp_live_data, g1h->reserved_region().start()), + _act_live_data(act_live_data), + _exp_live_data(exp_live_data), + _failures(0) { } + + int failures() const { return _failures; } + + bool doHeapRegion(HeapRegion* hr) { + int failures = 0; + + // Walk the marking bitmap for this region and set the corresponding bits + // in the expected region and card bitmaps. + size_t exp_marked_bytes = create_live_data_count(hr); + size_t act_marked_bytes = hr->next_marked_bytes(); + // Verify the marked bytes for this region. + + if (exp_marked_bytes != act_marked_bytes) { + failures += 1; + } else if (exp_marked_bytes > HeapRegion::GrainBytes) { + failures += 1; + } + + // Verify the bit, for this region, in the actual and expected + // (which was just calculated) region bit maps. + // We're not OK if the bit in the calculated expected region + // bitmap is set and the bit in the actual region bitmap is not. + uint index = hr->hrm_index(); + + bool expected = _exp_live_data->is_region_live(index); + bool actual = _act_live_data->is_region_live(index); + if (expected && !actual) { + failures += 1; + } + + // Verify that the card bit maps for the cards spanned by the current + // region match. We have an error if we have a set bit in the expected + // bit map and the corresponding bit in the actual bitmap is not set. + + BitMap::idx_t start_idx = _helper.card_live_bitmap_index_for(hr->bottom()); + BitMap::idx_t end_idx = _helper.card_live_bitmap_index_for(hr->top()); + + for (BitMap::idx_t i = start_idx; i < end_idx; i+=1) { + expected = _exp_live_data->is_card_live_at(i); + actual = _act_live_data->is_card_live_at(i); + + if (expected && !actual) { + failures += 1; + } + } + + _failures += failures; + + // We could stop iteration over the heap when we + // find the first violating region by returning true. + return false; + } + }; +protected: + G1CollectedHeap* _g1h; + G1CMBitMap* _mark_bitmap; + + G1CardLiveData* _act_live_data; + + G1CardLiveData _exp_live_data; + + int _failures; + + HeapRegionClaimer _hr_claimer; + +public: + G1VerifyCardLiveDataTask(G1CMBitMap* bitmap, + G1CardLiveData* act_live_data, + uint n_workers) + : AbstractGangTask("G1 Verify Card Live Data"), + _g1h(G1CollectedHeap::heap()), + _mark_bitmap(bitmap), + _act_live_data(act_live_data), + _exp_live_data(), + _failures(0), + _hr_claimer(n_workers) { + assert(VerifyDuringGC, "don't call this otherwise"); + _exp_live_data.initialize(_g1h->max_capacity(), _g1h->max_regions()); + } + + void work(uint worker_id) { + G1VerifyCardLiveDataClosure cl(_g1h, + _mark_bitmap, + _act_live_data, + &_exp_live_data); + _g1h->heap_region_par_iterate(&cl, worker_id, &_hr_claimer); + + Atomic::add(cl.failures(), &_failures); + } + + int failures() const { return _failures; } +}; + +void G1CardLiveData::verify(WorkGang* workers, G1CMBitMap* actual_bitmap) { + ResourceMark rm; + + G1VerifyCardLiveDataTask cl(actual_bitmap, + this, + workers->active_workers()); + workers->run_task(&cl); + + guarantee(cl.failures() == 0, "Unexpected accounting failures"); +} + +#ifndef PRODUCT +void G1CardLiveData::verify_is_clear() { + assert(live_cards_bm().count_one_bits() == 0, "Live cards bitmap must be clear."); + assert(live_regions_bm().count_one_bits() == 0, "Live regions bitmap must be clear."); +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_G1_G1CARDLIVEDATA_HPP +#define SHARE_VM_GC_G1_G1CARDLIVEDATA_HPP + +#include "gc/g1/g1CollectedHeap.hpp" +#include "utilities/bitMap.hpp" +#include "utilities/globalDefinitions.hpp" + +class G1CollectedHeap; +class G1CMBitMap; +class WorkGang; + +// Information about object liveness on the Java heap on a "card" basis. +// Can be used for various purposes, like as remembered set for completely +// coarsened remembered sets, scrubbing remembered sets or estimating liveness. +// This information is created as part of the concurrent marking cycle. +class G1CardLiveData VALUE_OBJ_CLASS_SPEC { + friend class G1CardLiveDataHelper; + friend class G1VerifyCardLiveDataTask; +private: + typedef BitMap::bm_word_t bm_word_t; + // Store some additional information about the covered area to be able to test. + size_t _max_capacity; + size_t _cards_per_region; + + // The per-card liveness bitmap. + bm_word_t* _live_cards; + size_t _live_cards_size_in_bits; + // The per-region liveness bitmap. + bm_word_t* _live_regions; + size_t _live_regions_size_in_bits; + // The bits in this bitmap contain for every card whether it contains + // at least part of at least one live object. + BitMap live_cards_bm() const { return BitMap(_live_cards, _live_cards_size_in_bits); } + // The bits in this bitmap indicate that a given region contains some live objects. + BitMap live_regions_bm() const { return BitMap(_live_regions, _live_regions_size_in_bits); } + + // Allocate a "large" bitmap from virtual memory with the given size in bits. + bm_word_t* allocate_large_bitmap(size_t size_in_bits); + void free_large_bitmap(bm_word_t* map, size_t size_in_bits); + + inline BitMap live_card_bitmap(uint region); + + inline bool is_card_live_at(BitMap::idx_t idx) const; + + size_t live_region_bitmap_size_in_bits() const; + size_t live_card_bitmap_size_in_bits() const; +public: + inline bool is_region_live(uint region) const; + + inline void remove_nonlive_cards(uint region, BitMap* bm); + inline void remove_nonlive_regions(BitMap* bm); + + G1CardLiveData(); + ~G1CardLiveData(); + + void initialize(size_t max_capacity, uint num_max_regions); + void pretouch(); + + // Create the initial liveness data based on the marking result from the bottom + // to the ntams of every region in the heap and the marks in the given bitmap. + void create(WorkGang* workers, G1CMBitMap* mark_bitmap); + // Finalize the liveness data. + void finalize(WorkGang* workers, G1CMBitMap* mark_bitmap); + + // Verify that the liveness count data created concurrently matches one created + // during this safepoint. + void verify(WorkGang* workers, G1CMBitMap* actual_bitmap); + // Clear all data structures, prepare for next processing. + void clear(WorkGang* workers); + + void verify_is_clear() PRODUCT_RETURN; +}; + +#endif /* SHARE_VM_GC_G1_G1CARDLIVEDATA_HPP */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.inline.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_G1_G1CARDLIVEDATA_INLINE_HPP +#define SHARE_VM_GC_G1_G1CARDLIVEDATA_INLINE_HPP + +#include "gc/g1/g1CardLiveData.hpp" +#include "utilities/bitMap.inline.hpp" +#include "utilities/globalDefinitions.hpp" + +inline BitMap G1CardLiveData::live_card_bitmap(uint region) { + return BitMap(_live_cards + ((size_t)region * _cards_per_region >> LogBitsPerWord), _cards_per_region); +} + +inline bool G1CardLiveData::is_card_live_at(BitMap::idx_t idx) const { + return live_cards_bm().at(idx); +} + +inline bool G1CardLiveData::is_region_live(uint region) const { + return live_regions_bm().at(region); +} + +inline void G1CardLiveData::remove_nonlive_cards(uint region, BitMap* bm) { + bm->set_intersection(live_card_bitmap(region)); +} + +inline void G1CardLiveData::remove_nonlive_regions(BitMap* bm) { + bm->set_intersection(live_regions_bm()); +} + +#endif /* SHARE_VM_GC_G1_G1CARDLIVEDATA_INLINE_HPP */
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -1425,6 +1425,7 @@ // the full GC has compacted objects and updated TAMS but not updated // the prev bitmap. if (G1VerifyBitmaps) { + GCTraceTime(Debug, gc)("Clear Bitmap for Verification"); _cm->clear_prev_bitmap(workers()); } _verifier->check_bitmaps("Full GC End"); @@ -1828,10 +1829,14 @@ HeapRegion::GrainBytes, translation_factor, mtGC); - if (TracePageSizes) { - tty->print_cr("G1 '%s': pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT " size=" SIZE_FORMAT " alignment=" SIZE_FORMAT " reqsize=" SIZE_FORMAT, - description, preferred_page_size, p2i(rs.base()), rs.size(), rs.alignment(), size); - } + + os::trace_page_sizes_for_requested_size(description, + size, + preferred_page_size, + rs.alignment(), + rs.base(), + rs.size()); + return result; } @@ -1905,26 +1910,28 @@ HeapRegion::GrainBytes, 1, mtJavaHeap); - os::trace_page_sizes("G1 Heap", collector_policy()->min_heap_byte_size(), - max_byte_size, page_size, + os::trace_page_sizes("Heap", + collector_policy()->min_heap_byte_size(), + max_byte_size, + page_size, heap_rs.base(), heap_rs.size()); heap_storage->set_mapping_changed_listener(&_listener); // Create storage for the BOT, card table, card counts table (hot card cache) and the bitmaps. G1RegionToSpaceMapper* bot_storage = - create_aux_memory_mapper("Block offset table", + create_aux_memory_mapper("Block Offset Table", G1BlockOffsetTable::compute_size(g1_rs.size() / HeapWordSize), G1BlockOffsetTable::heap_map_factor()); ReservedSpace cardtable_rs(G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize)); G1RegionToSpaceMapper* cardtable_storage = - create_aux_memory_mapper("Card table", + create_aux_memory_mapper("Card Table", G1SATBCardTableLoggingModRefBS::compute_size(g1_rs.size() / HeapWordSize), G1SATBCardTableLoggingModRefBS::heap_map_factor()); G1RegionToSpaceMapper* card_counts_storage = - create_aux_memory_mapper("Card counts table", + create_aux_memory_mapper("Card Counts Table", G1CardCounts::compute_size(g1_rs.size() / HeapWordSize), G1CardCounts::heap_map_factor()); @@ -1944,7 +1951,7 @@ const uint max_region_idx = (1U << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1; guarantee((max_regions() - 1) <= max_region_idx, "too many regions"); - G1RemSet::initialize(max_regions()); + g1_rem_set()->initialize(max_capacity(), max_regions()); size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1; guarantee(HeapRegion::CardsPerRegion > 0, "make sure it's initialized"); @@ -2735,7 +2742,7 @@ _cmThread->print_on(st); st->cr(); _cm->print_worker_threads_on(st); - _cg1r->print_worker_threads_on(st); + _cg1r->print_worker_threads_on(st); // also prints the sample thread if (G1StringDedup::is_enabled()) { G1StringDedup::print_worker_threads_on(st); } @@ -2744,7 +2751,8 @@ void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const { workers()->threads_do(tc); tc->do_thread(_cmThread); - _cg1r->threads_do(tc); + _cm->threads_do(tc); + _cg1r->threads_do(tc); // also iterates over the sample thread if (G1StringDedup::is_enabled()) { G1StringDedup::threads_do(tc); } @@ -2939,13 +2947,17 @@ : rset->is_empty(); } - bool is_typeArray_region(HeapRegion* region) const { - return oop(region->bottom())->is_typeArray(); - } - bool humongous_region_is_candidate(G1CollectedHeap* heap, HeapRegion* region) const { assert(region->is_starts_humongous(), "Must start a humongous object"); + oop obj = oop(region->bottom()); + + // Dead objects cannot be eager reclaim candidates. Due to class + // unloading it is unsafe to query their classes so we return early. + if (heap->is_obj_dead(obj, region)) { + return false; + } + // Candidate selection must satisfy the following constraints // while concurrent marking is in progress: // @@ -2982,7 +2994,7 @@ // important use case for eager reclaim, and this special handling // may reduce needed headroom. - return is_typeArray_region(region) && is_remset_small(region); + return obj->is_typeArray() && is_remset_small(region); } public: @@ -4787,27 +4799,23 @@ class G1ParScrubRemSetTask: public AbstractGangTask { protected: G1RemSet* _g1rs; - BitMap* _region_bm; - BitMap* _card_bm; HeapRegionClaimer _hrclaimer; public: - G1ParScrubRemSetTask(G1RemSet* g1_rs, BitMap* region_bm, BitMap* card_bm, uint num_workers) : + G1ParScrubRemSetTask(G1RemSet* g1_rs, uint num_workers) : AbstractGangTask("G1 ScrubRS"), _g1rs(g1_rs), - _region_bm(region_bm), - _card_bm(card_bm), _hrclaimer(num_workers) { } void work(uint worker_id) { - _g1rs->scrub(_region_bm, _card_bm, worker_id, &_hrclaimer); + _g1rs->scrub(worker_id, &_hrclaimer); } }; -void G1CollectedHeap::scrub_rem_set(BitMap* region_bm, BitMap* card_bm) { +void G1CollectedHeap::scrub_rem_set() { uint num_workers = workers()->active_workers(); - G1ParScrubRemSetTask g1_par_scrub_rs_task(g1_rem_set(), region_bm, card_bm, num_workers); + G1ParScrubRemSetTask g1_par_scrub_rs_task(g1_rem_set(), num_workers); workers()->run_task(&g1_par_scrub_rs_task); } @@ -4821,6 +4829,9 @@ workers()->run_task(&cleanup_task); #ifndef PRODUCT + // Need to synchronize with concurrent cleanup since it needs to + // finish its card table clearing before we can verify. + wait_while_free_regions_coming(); _verifier->verify_card_table_cleanup(); #endif }
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -992,7 +992,8 @@ // The rem set and barrier set. G1RemSet* g1_rem_set() const { return _g1_rem_set; } - void scrub_rem_set(BitMap* region_bm, BitMap* card_bm); + // Try to minimize the remembered set. + void scrub_rem_set(); unsigned get_gc_time_stamp() { return _gc_time_stamp;
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.inline.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -28,7 +28,7 @@ #include "gc/g1/g1CollectedHeap.hpp" #include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorState.hpp" -#include "gc/g1/g1ConcurrentMark.hpp" +#include "gc/g1/g1ConcurrentMark.inline.hpp" #include "gc/g1/g1SATBCardTableModRefBS.hpp" #include "gc/g1/heapRegionManager.inline.hpp" #include "gc/g1/heapRegionSet.inline.hpp"
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -33,6 +33,7 @@ #include "gc/g1/g1ConcurrentMark.inline.hpp" #include "gc/g1/g1HeapVerifier.hpp" #include "gc/g1/g1OopClosures.inline.hpp" +#include "gc/g1/g1CardLiveData.inline.hpp" #include "gc/g1/g1StringDedup.hpp" #include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" @@ -355,10 +356,6 @@ _sleep_factor(0.0), _marking_task_overhead(1.0), _cleanup_list("Cleanup List"), - _region_bm((BitMap::idx_t)(g1h->max_regions()), false /* in_resource_area*/), - _card_bm((g1h->reserved_region().byte_size() + CardTableModRefBS::card_size - 1) >> - CardTableModRefBS::card_shift, - false /* in_resource_area*/), _prevMarkBitMap(&_markBitMap1), _nextMarkBitMap(&_markBitMap2), @@ -390,8 +387,6 @@ _parallel_workers(NULL), - _count_card_bitmaps(NULL), - _count_marked_bytes(NULL), _completed_initialization(false) { _markBitMap1.initialize(g1h->reserved_region(), prev_bitmap_storage); @@ -505,40 +500,19 @@ _tasks = NEW_C_HEAP_ARRAY(G1CMTask*, _max_worker_id, mtGC); _accum_task_vtime = NEW_C_HEAP_ARRAY(double, _max_worker_id, mtGC); - _count_card_bitmaps = NEW_C_HEAP_ARRAY(BitMap, _max_worker_id, mtGC); - _count_marked_bytes = NEW_C_HEAP_ARRAY(size_t*, _max_worker_id, mtGC); - - BitMap::idx_t card_bm_size = _card_bm.size(); - // so that the assertion in MarkingTaskQueue::task_queue doesn't fail _active_tasks = _max_worker_id; - uint max_regions = _g1h->max_regions(); for (uint i = 0; i < _max_worker_id; ++i) { G1CMTaskQueue* task_queue = new G1CMTaskQueue(); task_queue->initialize(); _task_queues->register_queue(i, task_queue); - _count_card_bitmaps[i] = BitMap(card_bm_size, false); - _count_marked_bytes[i] = NEW_C_HEAP_ARRAY(size_t, max_regions, mtGC); - - _tasks[i] = new G1CMTask(i, this, - _count_marked_bytes[i], - &_count_card_bitmaps[i], - task_queue, _task_queues); + _tasks[i] = new G1CMTask(i, this, task_queue, _task_queues); _accum_task_vtime[i] = 0.0; } - // Calculate the card number for the bottom of the heap. Used - // in biasing indexes into the accounting card bitmaps. - _heap_bottom_card_num = - intptr_t(uintptr_t(_g1h->reserved_region().start()) >> - CardTableModRefBS::card_shift); - - // Clear all the liveness counting data - clear_all_count_data(); - // so that the call below can read a sensible value _heap_start = g1h->reserved_region().start(); set_non_marking_state(); @@ -716,10 +690,11 @@ clear_bitmap(_nextMarkBitMap, _parallel_workers, true); - // Clear the liveness counting data. If the marking has been aborted, the abort() + // Clear the live count data. If the marking has been aborted, the abort() // call already did that. if (!has_aborted()) { - clear_all_count_data(); + clear_live_data(_parallel_workers); + DEBUG_ONLY(verify_live_data_clear()); } // Repeat the asserts from above. @@ -901,7 +876,7 @@ double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec; _cm->clear_has_overflown(); - _cm->do_yield_check(worker_id); + _cm->do_yield_check(); jlong sleep_time_ms; if (!_cm->has_aborted() && the_task->has_aborted()) { @@ -951,10 +926,10 @@ return n_conc_workers; } -void G1ConcurrentMark::scanRootRegion(HeapRegion* hr, uint worker_id) { +void G1ConcurrentMark::scanRootRegion(HeapRegion* hr) { // Currently, only survivors can be root regions. assert(hr->next_top_at_mark_start() == hr->bottom(), "invariant"); - G1RootRegionScanClosure cl(_g1h, this, worker_id); + G1RootRegionScanClosure cl(_g1h, this); const uintx interval = PrefetchScanIntervalInBytes; HeapWord* curr = hr->bottom(); @@ -983,7 +958,7 @@ G1CMRootRegions* root_regions = _cm->root_regions(); HeapRegion* hr = root_regions->claim_next(); while (hr != NULL) { - _cm->scanRootRegion(hr, worker_id); + _cm->scanRootRegion(hr); hr = root_regions->claim_next(); } } @@ -1107,14 +1082,6 @@ // marking due to overflowing the global mark stack. reset_marking_state(); } else { - { - GCTraceTime(Debug, gc, phases) trace("Aggregate Data", _gc_timer_cm); - - // Aggregate the per-task counting data that we have accumulated - // while marking. - aggregate_count_data(); - } - SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); // We're done with marking. // This is the end of the marking cycle, we're expected all @@ -1150,363 +1117,6 @@ _gc_tracer_cm->report_object_count_after_gc(&is_alive); } -// Base class of the closures that finalize and verify the -// liveness counting data. -class G1CMCountDataClosureBase: public HeapRegionClosure { -protected: - G1CollectedHeap* _g1h; - G1ConcurrentMark* _cm; - CardTableModRefBS* _ct_bs; - - BitMap* _region_bm; - BitMap* _card_bm; - - // Takes a region that's not empty (i.e., it has at least one - // live object in it and sets its corresponding bit on the region - // bitmap to 1. - void set_bit_for_region(HeapRegion* hr) { - BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index(); - _region_bm->par_at_put(index, true); - } - -public: - G1CMCountDataClosureBase(G1CollectedHeap* g1h, - BitMap* region_bm, BitMap* card_bm): - _g1h(g1h), _cm(g1h->concurrent_mark()), - _ct_bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())), - _region_bm(region_bm), _card_bm(card_bm) { } -}; - -// Closure that calculates the # live objects per region. Used -// for verification purposes during the cleanup pause. -class CalcLiveObjectsClosure: public G1CMCountDataClosureBase { - G1CMBitMapRO* _bm; - size_t _region_marked_bytes; - -public: - CalcLiveObjectsClosure(G1CMBitMapRO *bm, G1CollectedHeap* g1h, - BitMap* region_bm, BitMap* card_bm) : - G1CMCountDataClosureBase(g1h, region_bm, card_bm), - _bm(bm), _region_marked_bytes(0) { } - - bool doHeapRegion(HeapRegion* hr) { - HeapWord* ntams = hr->next_top_at_mark_start(); - HeapWord* start = hr->bottom(); - - assert(start <= hr->end() && start <= ntams && ntams <= hr->end(), - "Preconditions not met - " - "start: " PTR_FORMAT ", ntams: " PTR_FORMAT ", end: " PTR_FORMAT, - p2i(start), p2i(ntams), p2i(hr->end())); - - // Find the first marked object at or after "start". - start = _bm->getNextMarkedWordAddress(start, ntams); - - size_t marked_bytes = 0; - - while (start < ntams) { - oop obj = oop(start); - int obj_sz = obj->size(); - HeapWord* obj_end = start + obj_sz; - - BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start); - BitMap::idx_t end_idx = _cm->card_bitmap_index_for(obj_end); - - // Note: if we're looking at the last region in heap - obj_end - // could be actually just beyond the end of the heap; end_idx - // will then correspond to a (non-existent) card that is also - // just beyond the heap. - if (_g1h->is_in_g1_reserved(obj_end) && !_ct_bs->is_card_aligned(obj_end)) { - // end of object is not card aligned - increment to cover - // all the cards spanned by the object - end_idx += 1; - } - - // Set the bits in the card BM for the cards spanned by this object. - _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */); - - // Add the size of this object to the number of marked bytes. - marked_bytes += (size_t)obj_sz * HeapWordSize; - - // This will happen if we are handling a humongous object that spans - // several heap regions. - if (obj_end > hr->end()) { - break; - } - // Find the next marked object after this one. - start = _bm->getNextMarkedWordAddress(obj_end, ntams); - } - - // Mark the allocated-since-marking portion... - HeapWord* top = hr->top(); - if (ntams < top) { - BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams); - BitMap::idx_t end_idx = _cm->card_bitmap_index_for(top); - - // Note: if we're looking at the last region in heap - top - // could be actually just beyond the end of the heap; end_idx - // will then correspond to a (non-existent) card that is also - // just beyond the heap. - if (_g1h->is_in_g1_reserved(top) && !_ct_bs->is_card_aligned(top)) { - // end of object is not card aligned - increment to cover - // all the cards spanned by the object - end_idx += 1; - } - _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */); - - // This definitely means the region has live objects. - set_bit_for_region(hr); - } - - // Update the live region bitmap. - if (marked_bytes > 0) { - set_bit_for_region(hr); - } - - // Set the marked bytes for the current region so that - // it can be queried by a calling verification routine - _region_marked_bytes = marked_bytes; - - return false; - } - - size_t region_marked_bytes() const { return _region_marked_bytes; } -}; - -// Heap region closure used for verifying the counting data -// that was accumulated concurrently and aggregated during -// the remark pause. This closure is applied to the heap -// regions during the STW cleanup pause. - -class VerifyLiveObjectDataHRClosure: public HeapRegionClosure { - G1CollectedHeap* _g1h; - G1ConcurrentMark* _cm; - CalcLiveObjectsClosure _calc_cl; - BitMap* _region_bm; // Region BM to be verified - BitMap* _card_bm; // Card BM to be verified - - BitMap* _exp_region_bm; // Expected Region BM values - BitMap* _exp_card_bm; // Expected card BM values - - int _failures; - -public: - VerifyLiveObjectDataHRClosure(G1CollectedHeap* g1h, - BitMap* region_bm, - BitMap* card_bm, - BitMap* exp_region_bm, - BitMap* exp_card_bm) : - _g1h(g1h), _cm(g1h->concurrent_mark()), - _calc_cl(_cm->nextMarkBitMap(), g1h, exp_region_bm, exp_card_bm), - _region_bm(region_bm), _card_bm(card_bm), - _exp_region_bm(exp_region_bm), _exp_card_bm(exp_card_bm), - _failures(0) { } - - int failures() const { return _failures; } - - bool doHeapRegion(HeapRegion* hr) { - int failures = 0; - - // Call the CalcLiveObjectsClosure to walk the marking bitmap for - // this region and set the corresponding bits in the expected region - // and card bitmaps. - bool res = _calc_cl.doHeapRegion(hr); - assert(res == false, "should be continuing"); - - // Verify the marked bytes for this region. - size_t exp_marked_bytes = _calc_cl.region_marked_bytes(); - size_t act_marked_bytes = hr->next_marked_bytes(); - - if (exp_marked_bytes > act_marked_bytes) { - if (hr->is_starts_humongous()) { - // For start_humongous regions, the size of the whole object will be - // in exp_marked_bytes. - HeapRegion* region = hr; - int num_regions; - for (num_regions = 0; region != NULL; num_regions++) { - region = _g1h->next_region_in_humongous(region); - } - if ((num_regions-1) * HeapRegion::GrainBytes >= exp_marked_bytes) { - failures += 1; - } else if (num_regions * HeapRegion::GrainBytes < exp_marked_bytes) { - failures += 1; - } - } else { - // We're not OK if expected marked bytes > actual marked bytes. It means - // we have missed accounting some objects during the actual marking. - failures += 1; - } - } - - // Verify the bit, for this region, in the actual and expected - // (which was just calculated) region bit maps. - // We're not OK if the bit in the calculated expected region - // bitmap is set and the bit in the actual region bitmap is not. - BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index(); - - bool expected = _exp_region_bm->at(index); - bool actual = _region_bm->at(index); - if (expected && !actual) { - failures += 1; - } - - // Verify that the card bit maps for the cards spanned by the current - // region match. We have an error if we have a set bit in the expected - // bit map and the corresponding bit in the actual bitmap is not set. - - BitMap::idx_t start_idx = _cm->card_bitmap_index_for(hr->bottom()); - BitMap::idx_t end_idx = _cm->card_bitmap_index_for(hr->top()); - - for (BitMap::idx_t i = start_idx; i < end_idx; i+=1) { - expected = _exp_card_bm->at(i); - actual = _card_bm->at(i); - - if (expected && !actual) { - failures += 1; - } - } - - _failures += failures; - - // We could stop iteration over the heap when we - // find the first violating region by returning true. - return false; - } -}; - -class G1ParVerifyFinalCountTask: public AbstractGangTask { -protected: - G1CollectedHeap* _g1h; - G1ConcurrentMark* _cm; - BitMap* _actual_region_bm; - BitMap* _actual_card_bm; - - uint _n_workers; - - BitMap* _expected_region_bm; - BitMap* _expected_card_bm; - - int _failures; - - HeapRegionClaimer _hrclaimer; - -public: - G1ParVerifyFinalCountTask(G1CollectedHeap* g1h, - BitMap* region_bm, BitMap* card_bm, - BitMap* expected_region_bm, BitMap* expected_card_bm) - : AbstractGangTask("G1 verify final counting"), - _g1h(g1h), _cm(_g1h->concurrent_mark()), - _actual_region_bm(region_bm), _actual_card_bm(card_bm), - _expected_region_bm(expected_region_bm), _expected_card_bm(expected_card_bm), - _failures(0), - _n_workers(_g1h->workers()->active_workers()), _hrclaimer(_n_workers) { - assert(VerifyDuringGC, "don't call this otherwise"); - assert(_expected_card_bm->size() == _actual_card_bm->size(), "sanity"); - assert(_expected_region_bm->size() == _actual_region_bm->size(), "sanity"); - } - - void work(uint worker_id) { - assert(worker_id < _n_workers, "invariant"); - - VerifyLiveObjectDataHRClosure verify_cl(_g1h, - _actual_region_bm, _actual_card_bm, - _expected_region_bm, - _expected_card_bm); - - _g1h->heap_region_par_iterate(&verify_cl, worker_id, &_hrclaimer); - - Atomic::add(verify_cl.failures(), &_failures); - } - - int failures() const { return _failures; } -}; - -// Closure that finalizes the liveness counting data. -// Used during the cleanup pause. -// Sets the bits corresponding to the interval [NTAMS, top] -// (which contains the implicitly live objects) in the -// card liveness bitmap. Also sets the bit for each region, -// containing live data, in the region liveness bitmap. - -class FinalCountDataUpdateClosure: public G1CMCountDataClosureBase { - public: - FinalCountDataUpdateClosure(G1CollectedHeap* g1h, - BitMap* region_bm, - BitMap* card_bm) : - G1CMCountDataClosureBase(g1h, region_bm, card_bm) { } - - bool doHeapRegion(HeapRegion* hr) { - HeapWord* ntams = hr->next_top_at_mark_start(); - HeapWord* top = hr->top(); - - assert(hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions."); - - // Mark the allocated-since-marking portion... - if (ntams < top) { - // This definitely means the region has live objects. - set_bit_for_region(hr); - - // Now set the bits in the card bitmap for [ntams, top) - BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams); - BitMap::idx_t end_idx = _cm->card_bitmap_index_for(top); - - // Note: if we're looking at the last region in heap - top - // could be actually just beyond the end of the heap; end_idx - // will then correspond to a (non-existent) card that is also - // just beyond the heap. - if (_g1h->is_in_g1_reserved(top) && !_ct_bs->is_card_aligned(top)) { - // end of object is not card aligned - increment to cover - // all the cards spanned by the object - end_idx += 1; - } - - assert(end_idx <= _card_bm->size(), - "oob: end_idx= " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT, - end_idx, _card_bm->size()); - assert(start_idx < _card_bm->size(), - "oob: start_idx= " SIZE_FORMAT ", bitmap size= " SIZE_FORMAT, - start_idx, _card_bm->size()); - - _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */); - } - - // Set the bit for the region if it contains live data - if (hr->next_marked_bytes() > 0) { - set_bit_for_region(hr); - } - - return false; - } -}; - -class G1ParFinalCountTask: public AbstractGangTask { -protected: - G1CollectedHeap* _g1h; - G1ConcurrentMark* _cm; - BitMap* _actual_region_bm; - BitMap* _actual_card_bm; - - uint _n_workers; - HeapRegionClaimer _hrclaimer; - -public: - G1ParFinalCountTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm) - : AbstractGangTask("G1 final counting"), - _g1h(g1h), _cm(_g1h->concurrent_mark()), - _actual_region_bm(region_bm), _actual_card_bm(card_bm), - _n_workers(_g1h->workers()->active_workers()), _hrclaimer(_n_workers) { - } - - void work(uint worker_id) { - assert(worker_id < _n_workers, "invariant"); - - FinalCountDataUpdateClosure final_update_cl(_g1h, - _actual_region_bm, - _actual_card_bm); - - _g1h->heap_region_par_iterate(&final_update_cl, worker_id, &_hrclaimer); - } -}; - class G1NoteEndOfConcMarkClosure : public HeapRegionClosure { G1CollectedHeap* _g1; size_t _freed_bytes; @@ -1637,31 +1247,16 @@ HeapRegionRemSet::reset_for_cleanup_tasks(); - // Do counting once more with the world stopped for good measure. - G1ParFinalCountTask g1_par_count_task(g1h, &_region_bm, &_card_bm); - - g1h->workers()->run_task(&g1_par_count_task); + { + GCTraceTime(Debug, gc)("Finalize Live Data"); + finalize_live_data(); + } if (VerifyDuringGC) { - // Verify that the counting data accumulated during marking matches - // that calculated by walking the marking bitmap. - - // Bitmaps to hold expected values - BitMap expected_region_bm(_region_bm.size(), true); - BitMap expected_card_bm(_card_bm.size(), true); - - G1ParVerifyFinalCountTask g1_par_verify_task(g1h, - &_region_bm, - &_card_bm, - &expected_region_bm, - &expected_card_bm); - - g1h->workers()->run_task(&g1_par_verify_task); - - guarantee(g1_par_verify_task.failures() == 0, "Unexpected accounting failures"); + GCTraceTime(Debug, gc)("Verify Live Data"); + verify_live_data(); } - size_t start_used_bytes = g1h->used(); g1h->collector_state()->set_mark_in_progress(false); double count_end = os::elapsedTime(); @@ -1696,7 +1291,7 @@ // regions. if (G1ScrubRemSets) { double rs_scrub_start = os::elapsedTime(); - g1h->scrub_rem_set(&_region_bm, &_card_bm); + g1h->scrub_rem_set(); _total_rs_scrub_time += (os::elapsedTime() - rs_scrub_start); } @@ -2160,7 +1755,7 @@ oop obj = static_cast<oop>(entry); assert(obj->is_oop(true /* ignore mark word */), "Invalid oop in SATB buffer: " PTR_FORMAT, p2i(obj)); - _task->make_reference_grey(obj, hr); + _task->make_reference_grey(obj); } } @@ -2401,168 +1996,28 @@ } } #endif // PRODUCT - -// Aggregate the counting data that was constructed concurrently -// with marking. -class AggregateCountDataHRClosure: public HeapRegionClosure { - G1CollectedHeap* _g1h; - G1ConcurrentMark* _cm; - CardTableModRefBS* _ct_bs; - BitMap* _cm_card_bm; - uint _max_worker_id; - - public: - AggregateCountDataHRClosure(G1CollectedHeap* g1h, - BitMap* cm_card_bm, - uint max_worker_id) : - _g1h(g1h), _cm(g1h->concurrent_mark()), - _ct_bs(barrier_set_cast<CardTableModRefBS>(g1h->barrier_set())), - _cm_card_bm(cm_card_bm), _max_worker_id(max_worker_id) { } - - bool doHeapRegion(HeapRegion* hr) { - HeapWord* start = hr->bottom(); - HeapWord* limit = hr->next_top_at_mark_start(); - HeapWord* end = hr->end(); - - assert(start <= limit && limit <= hr->top() && hr->top() <= hr->end(), - "Preconditions not met - " - "start: " PTR_FORMAT ", limit: " PTR_FORMAT ", " - "top: " PTR_FORMAT ", end: " PTR_FORMAT, - p2i(start), p2i(limit), p2i(hr->top()), p2i(hr->end())); - - assert(hr->next_marked_bytes() == 0, "Precondition"); - - if (start == limit) { - // NTAMS of this region has not been set so nothing to do. - return false; - } - - // 'start' should be in the heap. - assert(_g1h->is_in_g1_reserved(start) && _ct_bs->is_card_aligned(start), "sanity"); - // 'end' *may* be just beyond the end of the heap (if hr is the last region) - assert(!_g1h->is_in_g1_reserved(end) || _ct_bs->is_card_aligned(end), "sanity"); - - BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start); - BitMap::idx_t limit_idx = _cm->card_bitmap_index_for(limit); - BitMap::idx_t end_idx = _cm->card_bitmap_index_for(end); - - // If ntams is not card aligned then we bump card bitmap index - // for limit so that we get the all the cards spanned by - // the object ending at ntams. - // Note: if this is the last region in the heap then ntams - // could be actually just beyond the end of the the heap; - // limit_idx will then correspond to a (non-existent) card - // that is also outside the heap. - if (_g1h->is_in_g1_reserved(limit) && !_ct_bs->is_card_aligned(limit)) { - limit_idx += 1; - } - - assert(limit_idx <= end_idx, "or else use atomics"); - - // Aggregate the "stripe" in the count data associated with hr. - uint hrm_index = hr->hrm_index(); - size_t marked_bytes = 0; - - for (uint i = 0; i < _max_worker_id; i += 1) { - size_t* marked_bytes_array = _cm->count_marked_bytes_array_for(i); - BitMap* task_card_bm = _cm->count_card_bitmap_for(i); - - // Fetch the marked_bytes in this region for task i and - // add it to the running total for this region. - marked_bytes += marked_bytes_array[hrm_index]; - - // Now union the bitmaps[0,max_worker_id)[start_idx..limit_idx) - // into the global card bitmap. - BitMap::idx_t scan_idx = task_card_bm->get_next_one_offset(start_idx, limit_idx); - - while (scan_idx < limit_idx) { - assert(task_card_bm->at(scan_idx) == true, "should be"); - _cm_card_bm->set_bit(scan_idx); - assert(_cm_card_bm->at(scan_idx) == true, "should be"); - - // BitMap::get_next_one_offset() can handle the case when - // its left_offset parameter is greater than its right_offset - // parameter. It does, however, have an early exit if - // left_offset == right_offset. So let's limit the value - // passed in for left offset here. - BitMap::idx_t next_idx = MIN2(scan_idx + 1, limit_idx); - scan_idx = task_card_bm->get_next_one_offset(next_idx, limit_idx); - } - } - - // Update the marked bytes for this region. - hr->add_to_marked_bytes(marked_bytes); - - // Next heap region - return false; - } -}; - -class G1AggregateCountDataTask: public AbstractGangTask { -protected: - G1CollectedHeap* _g1h; - G1ConcurrentMark* _cm; - BitMap* _cm_card_bm; - uint _max_worker_id; - uint _active_workers; - HeapRegionClaimer _hrclaimer; - -public: - G1AggregateCountDataTask(G1CollectedHeap* g1h, - G1ConcurrentMark* cm, - BitMap* cm_card_bm, - uint max_worker_id, - uint n_workers) : - AbstractGangTask("Count Aggregation"), - _g1h(g1h), _cm(cm), _cm_card_bm(cm_card_bm), - _max_worker_id(max_worker_id), - _active_workers(n_workers), - _hrclaimer(_active_workers) { - } - - void work(uint worker_id) { - AggregateCountDataHRClosure cl(_g1h, _cm_card_bm, _max_worker_id); - - _g1h->heap_region_par_iterate(&cl, worker_id, &_hrclaimer); - } -}; - - -void G1ConcurrentMark::aggregate_count_data() { - uint n_workers = _g1h->workers()->active_workers(); - - G1AggregateCountDataTask g1_par_agg_task(_g1h, this, &_card_bm, - _max_worker_id, n_workers); - - _g1h->workers()->run_task(&g1_par_agg_task); +void G1ConcurrentMark::create_live_data() { + _g1h->g1_rem_set()->create_card_live_data(_parallel_workers, _nextMarkBitMap); } -// Clear the per-worker arrays used to store the per-region counting data -void G1ConcurrentMark::clear_all_count_data() { - // Clear the global card bitmap - it will be filled during - // liveness count aggregation (during remark) and the - // final counting task. - _card_bm.clear(); - - // Clear the global region bitmap - it will be filled as part - // of the final counting task. - _region_bm.clear(); - - uint max_regions = _g1h->max_regions(); - assert(_max_worker_id > 0, "uninitialized"); - - for (uint i = 0; i < _max_worker_id; i += 1) { - BitMap* task_card_bm = count_card_bitmap_for(i); - size_t* marked_bytes_array = count_marked_bytes_array_for(i); - - assert(task_card_bm->size() == _card_bm.size(), "size mismatch"); - assert(marked_bytes_array != NULL, "uninitialized"); - - memset(marked_bytes_array, 0, (size_t) max_regions * sizeof(size_t)); - task_card_bm->clear(); - } +void G1ConcurrentMark::finalize_live_data() { + _g1h->g1_rem_set()->finalize_card_live_data(_g1h->workers(), _nextMarkBitMap); } +void G1ConcurrentMark::verify_live_data() { + _g1h->g1_rem_set()->verify_card_live_data(_g1h->workers(), _nextMarkBitMap); +} + +void G1ConcurrentMark::clear_live_data(WorkGang* workers) { + _g1h->g1_rem_set()->clear_card_live_data(workers); +} + +#ifdef ASSERT +void G1ConcurrentMark::verify_live_data_clear() { + _g1h->g1_rem_set()->verify_card_live_data_is_clear(); +} +#endif + void G1ConcurrentMark::print_stats() { if (!log_is_enabled(Debug, gc, stats)) { return; @@ -2574,7 +2029,6 @@ } } -// abandon current marking iteration due to a Full GC void G1ConcurrentMark::abort() { if (!cmThread()->during_cycle() || _has_aborted) { // We haven't started a concurrent cycle or we have already aborted it. No need to do anything. @@ -2583,14 +2037,22 @@ // Clear all marks in the next bitmap for the next marking cycle. This will allow us to skip the next // concurrent bitmap clearing. - clear_bitmap(_nextMarkBitMap, _g1h->workers(), false); - + { + GCTraceTime(Debug, gc)("Clear Next Bitmap"); + clear_bitmap(_nextMarkBitMap, _g1h->workers(), false); + } // Note we cannot clear the previous marking bitmap here // since VerifyDuringGC verifies the objects marked during // a full GC against the previous bitmap. - // Clear the liveness counting data - clear_all_count_data(); + { + GCTraceTime(Debug, gc)("Clear Live Data"); + clear_live_data(_g1h->workers()); + } + DEBUG_ONLY({ + GCTraceTime(Debug, gc)("Verify Live Data Clear"); + verify_live_data_clear(); + }) // Empty mark stack reset_marking_state(); for (uint i = 0; i < _max_worker_id; ++i) { @@ -2634,7 +2096,7 @@ } print_ms_time_info(" ", "cleanups", _cleanup_times); - log.trace(" Final counting total time = %8.2f s (avg = %8.2f ms).", + log.trace(" Finalize live data total time = %8.2f s (avg = %8.2f ms).", _total_counting_time, (_cleanup_times.num() > 0 ? _total_counting_time * 1000.0 / (double)_cleanup_times.num() : 0.0)); if (G1ScrubRemSets) { log.trace(" RS scrub total time = %8.2f s (avg = %8.2f ms).", @@ -2650,6 +2112,10 @@ _parallel_workers->print_worker_threads_on(st); } +void G1ConcurrentMark::threads_do(ThreadClosure* tc) const { + _parallel_workers->threads_do(tc); +} + void G1ConcurrentMark::print_on_error(outputStream* st) const { st->print_cr("Marking Bits (Prev, Next): (CMBitMap*) " PTR_FORMAT ", (CMBitMap*) " PTR_FORMAT, p2i(_prevMarkBitMap), p2i(_nextMarkBitMap)); @@ -2657,16 +2123,6 @@ _nextMarkBitMap->print_on_error(st, " Next Bits: "); } -// We take a break if someone is trying to stop the world. -bool G1ConcurrentMark::do_yield_check(uint worker_id) { - if (SuspendibleThreadSet::should_yield()) { - SuspendibleThreadSet::yield(); - return true; - } else { - return false; - } -} - // Closure for iteration over bitmaps class G1CMBitMapClosure : public BitMapClosure { private: @@ -3473,8 +2929,6 @@ G1CMTask::G1CMTask(uint worker_id, G1ConcurrentMark* cm, - size_t* marked_bytes, - BitMap* card_bm, G1CMTaskQueue* task_queue, G1CMTaskQueueSet* task_queues) : _g1h(G1CollectedHeap::heap()), @@ -3483,9 +2937,7 @@ _nextMarkBitMap(NULL), _hash_seed(17), _task_queue(task_queue), _task_queues(task_queues), - _cm_oop_closure(NULL), - _marked_bytes_array(marked_bytes), - _card_bm(card_bm) { + _cm_oop_closure(NULL) { guarantee(task_queue != NULL, "invariant"); guarantee(task_queues != NULL, "invariant");
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -266,7 +266,7 @@ class G1ConcurrentMark: public CHeapObj<mtGC> { friend class ConcurrentMarkThread; friend class G1ParNoteEndTask; - friend class CalcLiveObjectsClosure; + friend class G1VerifyLiveDataClosure; friend class G1CMRefProcTaskProxy; friend class G1CMRefProcTaskExecutor; friend class G1CMKeepAliveAndDrainClosure; @@ -298,9 +298,6 @@ G1CMBitMapRO* _prevMarkBitMap; // Completed mark bitmap G1CMBitMap* _nextMarkBitMap; // Under-construction mark bitmap - BitMap _region_bm; - BitMap _card_bm; - // Heap bounds HeapWord* _heap_start; HeapWord* _heap_end; @@ -461,23 +458,6 @@ void enter_first_sync_barrier(uint worker_id); void enter_second_sync_barrier(uint worker_id); - // Live Data Counting data structures... - // These data structures are initialized at the start of - // marking. They are written to while marking is active. - // They are aggregated during remark; the aggregated values - // are then used to populate the _region_bm, _card_bm, and - // the total live bytes, which are then subsequently updated - // during cleanup. - - // An array of bitmaps (one bit map per task). Each bitmap - // is used to record the cards spanned by the live objects - // marked by that task/worker. - BitMap* _count_card_bitmaps; - - // Used to record the number of marked live bytes - // (for each region, by worker thread). - size_t** _count_marked_bytes; - // Card index of the bottom of the G1 heap. Used for biasing indices into // the card bitmaps. intptr_t _heap_bottom_card_num; @@ -563,18 +543,10 @@ // G1CollectedHeap // This notifies CM that a root during initial-mark needs to be - // grayed. It is MT-safe. word_size is the size of the object in - // words. It is passed explicitly as sometimes we cannot calculate - // it from the given object because it might be in an inconsistent - // state (e.g., in to-space and being copied). So the caller is - // responsible for dealing with this issue (e.g., get the size from - // the from-space image when the to-space image might be - // inconsistent) and always passing the size. hr is the region that + // grayed. It is MT-safe. hr is the region that // contains the object and it's passed optionally from callers who // might already have it (no point in recalculating it). inline void grayRoot(oop obj, - size_t word_size, - uint worker_id, HeapRegion* hr = NULL); // Prepare internal data structures for the next mark cycle. This includes clearing @@ -603,7 +575,7 @@ void scan_root_regions(); // Scan a single root region and mark everything reachable from it. - void scanRootRegion(HeapRegion* hr, uint worker_id); + void scanRootRegion(HeapRegion* hr); // Do concurrent phase of marking, to a tentative transitive closure. void mark_from_roots(); @@ -639,9 +611,9 @@ inline bool isPrevMarked(oop p) const; - inline bool do_yield_check(uint worker_i = 0); + inline bool do_yield_check(); - // Called to abort the marking cycle after a Full GC takes place. + // Abandon current marking iteration due to a Full GC. void abort(); bool has_aborted() { return _has_aborted; } @@ -649,78 +621,12 @@ void print_summary_info(); void print_worker_threads_on(outputStream* st) const; + void threads_do(ThreadClosure* tc) const; void print_on_error(outputStream* st) const; - // Liveness counting - - // Utility routine to set an exclusive range of cards on the given - // card liveness bitmap - inline void set_card_bitmap_range(BitMap* card_bm, - BitMap::idx_t start_idx, - BitMap::idx_t end_idx, - bool is_par); - - // Returns the card number of the bottom of the G1 heap. - // Used in biasing indices into accounting card bitmaps. - intptr_t heap_bottom_card_num() const { - return _heap_bottom_card_num; - } - - // Returns the card bitmap for a given task or worker id. - BitMap* count_card_bitmap_for(uint worker_id) { - assert(worker_id < _max_worker_id, "oob"); - assert(_count_card_bitmaps != NULL, "uninitialized"); - BitMap* task_card_bm = &_count_card_bitmaps[worker_id]; - assert(task_card_bm->size() == _card_bm.size(), "size mismatch"); - return task_card_bm; - } - - // Returns the array containing the marked bytes for each region, - // for the given worker or task id. - size_t* count_marked_bytes_array_for(uint worker_id) { - assert(worker_id < _max_worker_id, "oob"); - assert(_count_marked_bytes != NULL, "uninitialized"); - size_t* marked_bytes_array = _count_marked_bytes[worker_id]; - assert(marked_bytes_array != NULL, "uninitialized"); - return marked_bytes_array; - } - - // Returns the index in the liveness accounting card table bitmap - // for the given address - inline BitMap::idx_t card_bitmap_index_for(HeapWord* addr); - - // Counts the size of the given memory region in the the given - // marked_bytes array slot for the given HeapRegion. - // Sets the bits in the given card bitmap that are associated with the - // cards that are spanned by the memory region. - inline void count_region(MemRegion mr, - HeapRegion* hr, - size_t* marked_bytes_array, - BitMap* task_card_bm); - - // Counts the given object in the given task/worker counting - // data structures. - inline void count_object(oop obj, - HeapRegion* hr, - size_t* marked_bytes_array, - BitMap* task_card_bm, - size_t word_size); - - // Attempts to mark the given object and, if successful, counts - // the object in the given task/worker counting structures. - inline bool par_mark_and_count(oop obj, - HeapRegion* hr, - size_t* marked_bytes_array, - BitMap* task_card_bm); - - // Attempts to mark the given object and, if successful, counts - // the object in the task/worker counting structures for the - // given worker id. - inline bool par_mark_and_count(oop obj, - size_t word_size, - HeapRegion* hr, - uint worker_id); + // Attempts to mark the given object on the next mark bitmap. + inline bool par_mark(oop obj); // Returns true if initialization was successfully completed. bool completed_initialization() const { @@ -730,19 +636,22 @@ ConcurrentGCTimer* gc_timer_cm() const { return _gc_timer_cm; } G1OldTracer* gc_tracer_cm() const { return _gc_tracer_cm; } -protected: - // Clear all the per-task bitmaps and arrays used to store the - // counting data. - void clear_all_count_data(); +private: + // Clear (Reset) all liveness count data. + void clear_live_data(WorkGang* workers); - // Aggregates the counting data for each worker/task - // that was constructed while marking. Also sets - // the amount of marked bytes for each region and - // the top at concurrent mark count. - void aggregate_count_data(); +#ifdef ASSERT + // Verify all of the above data structures that they are in initial state. + void verify_live_data_clear(); +#endif - // Verification routine - void verify_count_data(); + // Aggregates the per-card liveness data based on the current marking. Also sets + // the amount of marked bytes for each region. + void create_live_data(); + + void finalize_live_data(); + + void verify_live_data(); }; // A class representing a marking task. @@ -844,12 +753,6 @@ TruncatedSeq _marking_step_diffs_ms; - // Counting data structures. Embedding the task's marked_bytes_array - // and card bitmap into the actual task saves having to go through - // the ConcurrentMark object. - size_t* _marked_bytes_array; - BitMap* _card_bm; - // it updates the local fields after this task has claimed // a new region to scan void setup_for_region(HeapRegion* hr); @@ -936,9 +839,8 @@ // Grey the object by marking it. If not already marked, push it on // the local queue if below the finger. - // Precondition: obj is in region. - // Precondition: obj is below region's NTAMS. - inline void make_reference_grey(oop obj, HeapRegion* region); + // obj is below its region's NTAMS. + inline void make_reference_grey(oop obj); // Grey the object (by calling make_grey_reference) if required, // e.g. obj is below its containing region's NTAMS. @@ -976,8 +878,6 @@ G1CMTask(uint worker_id, G1ConcurrentMark *cm, - size_t* marked_bytes, - BitMap* card_bm, G1CMTaskQueue* task_queue, G1CMTaskQueueSet* task_queues);
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -27,140 +27,11 @@ #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentMark.hpp" +#include "gc/g1/suspendibleThreadSet.hpp" #include "gc/shared/taskqueue.inline.hpp" -// Utility routine to set an exclusive range of cards on the given -// card liveness bitmap -inline void G1ConcurrentMark::set_card_bitmap_range(BitMap* card_bm, - BitMap::idx_t start_idx, - BitMap::idx_t end_idx, - bool is_par) { - - // Set the exclusive bit range [start_idx, end_idx). - assert((end_idx - start_idx) > 0, "at least one card"); - assert(end_idx <= card_bm->size(), "sanity"); - - // Silently clip the end index - end_idx = MIN2(end_idx, card_bm->size()); - - // For small ranges use a simple loop; otherwise use set_range or - // use par_at_put_range (if parallel). The range is made up of the - // cards that are spanned by an object/mem region so 8 cards will - // allow up to object sizes up to 4K to be handled using the loop. - if ((end_idx - start_idx) <= 8) { - for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) { - if (is_par) { - card_bm->par_set_bit(i); - } else { - card_bm->set_bit(i); - } - } - } else { - // Note BitMap::par_at_put_range() and BitMap::set_range() are exclusive. - if (is_par) { - card_bm->par_at_put_range(start_idx, end_idx, true); - } else { - card_bm->set_range(start_idx, end_idx); - } - } -} - -// Returns the index in the liveness accounting card bitmap -// for the given address -inline BitMap::idx_t G1ConcurrentMark::card_bitmap_index_for(HeapWord* addr) { - // Below, the term "card num" means the result of shifting an address - // by the card shift -- address 0 corresponds to card number 0. One - // must subtract the card num of the bottom of the heap to obtain a - // card table index. - intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift); - return card_num - heap_bottom_card_num(); -} - -// Counts the given memory region in the given task/worker -// counting data structures. -inline void G1ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr, - size_t* marked_bytes_array, - BitMap* task_card_bm) { - G1CollectedHeap* g1h = _g1h; - CardTableModRefBS* ct_bs = g1h->g1_barrier_set(); - - HeapWord* start = mr.start(); - HeapWord* end = mr.end(); - size_t region_size_bytes = mr.byte_size(); - uint index = hr->hrm_index(); - - assert(hr == g1h->heap_region_containing(start), "sanity"); - assert(marked_bytes_array != NULL, "pre-condition"); - assert(task_card_bm != NULL, "pre-condition"); - - // Add to the task local marked bytes for this region. - marked_bytes_array[index] += region_size_bytes; - - BitMap::idx_t start_idx = card_bitmap_index_for(start); - BitMap::idx_t end_idx = card_bitmap_index_for(end); - - // Note: if we're looking at the last region in heap - end - // could be actually just beyond the end of the heap; end_idx - // will then correspond to a (non-existent) card that is also - // just beyond the heap. - if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) { - // end of region is not card aligned - increment to cover - // all the cards spanned by the region. - end_idx += 1; - } - // The card bitmap is task/worker specific => no need to use - // the 'par' BitMap routines. - // Set bits in the exclusive bit range [start_idx, end_idx). - set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */); -} - -// Counts the given object in the given task/worker counting data structures. -inline void G1ConcurrentMark::count_object(oop obj, - HeapRegion* hr, - size_t* marked_bytes_array, - BitMap* task_card_bm, - size_t word_size) { - assert(!hr->is_continues_humongous(), "Cannot enter count_object with continues humongous"); - if (!hr->is_starts_humongous()) { - MemRegion mr((HeapWord*)obj, word_size); - count_region(mr, hr, marked_bytes_array, task_card_bm); - } else { - do { - MemRegion mr(hr->bottom(), hr->top()); - count_region(mr, hr, marked_bytes_array, task_card_bm); - hr = _g1h->next_region_in_humongous(hr); - } while (hr != NULL); - } -} - -// Attempts to mark the given object and, if successful, counts -// the object in the given task/worker counting structures. -inline bool G1ConcurrentMark::par_mark_and_count(oop obj, - HeapRegion* hr, - size_t* marked_bytes_array, - BitMap* task_card_bm) { - if (_nextMarkBitMap->parMark((HeapWord*)obj)) { - // Update the task specific count data for the object. - count_object(obj, hr, marked_bytes_array, task_card_bm, obj->size()); - return true; - } - return false; -} - -// Attempts to mark the given object and, if successful, counts -// the object in the task/worker counting structures for the -// given worker id. -inline bool G1ConcurrentMark::par_mark_and_count(oop obj, - size_t word_size, - HeapRegion* hr, - uint worker_id) { - if (_nextMarkBitMap->parMark((HeapWord*)obj)) { - size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id); - BitMap* task_card_bm = count_card_bitmap_for(worker_id); - count_object(obj, hr, marked_bytes_array, task_card_bm, word_size); - return true; - } - return false; +inline bool G1ConcurrentMark::par_mark(oop obj) { + return _nextMarkBitMap->parMark((HeapWord*)obj); } inline bool G1CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) { @@ -294,10 +165,8 @@ check_limits(); } - - -inline void G1CMTask::make_reference_grey(oop obj, HeapRegion* hr) { - if (_cm->par_mark_and_count(obj, hr, _marked_bytes_array, _card_bm)) { +inline void G1CMTask::make_reference_grey(oop obj) { + if (_cm->par_mark(obj)) { // No OrderAccess:store_load() is needed. It is implicit in the // CAS done in G1CMBitMap::parMark() call in the routine above. HeapWord* global_finger = _cm->finger(); @@ -348,7 +217,7 @@ // anything with it). HeapRegion* hr = _g1h->heap_region_containing(obj); if (!hr->obj_allocated_since_next_marking(obj)) { - make_reference_grey(obj, hr); + make_reference_grey(obj); } } } @@ -370,8 +239,7 @@ return _prevMarkBitMap->isMarked(addr); } -inline void G1ConcurrentMark::grayRoot(oop obj, size_t word_size, - uint worker_id, HeapRegion* hr) { +inline void G1ConcurrentMark::grayRoot(oop obj, HeapRegion* hr) { assert(obj != NULL, "pre-condition"); HeapWord* addr = (HeapWord*) obj; if (hr == NULL) { @@ -386,9 +254,18 @@ if (addr < hr->next_top_at_mark_start()) { if (!_nextMarkBitMap->isMarked(addr)) { - par_mark_and_count(obj, word_size, hr, worker_id); + par_mark(obj); } } } +inline bool G1ConcurrentMark::do_yield_check() { + if (SuspendibleThreadSet::should_yield()) { + SuspendibleThreadSet::yield(); + return true; + } else { + return false; + } +} + #endif // SHARE_VM_GC_G1_G1CONCURRENTMARK_INLINE_HPP
--- a/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1EvacFailure.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -95,8 +95,6 @@ void do_object(oop obj) { HeapWord* obj_addr = (HeapWord*) obj; assert(_hr->is_in(obj_addr), "sanity"); - size_t obj_size = obj->size(); - HeapWord* obj_end = obj_addr + obj_size; if (obj->is_forwarded() && obj->forwardee() == obj) { // The object failed to move. @@ -119,8 +117,10 @@ // explicitly and all objects in the CSet are considered // (implicitly) live. So, we won't mark them explicitly and // we'll leave them over NTAMS. - _cm->grayRoot(obj, obj_size, _worker_id, _hr); + _cm->grayRoot(obj, _hr); } + size_t obj_size = obj->size(); + _marked_bytes += (obj_size * HeapWordSize); obj->set_mark(markOopDesc::prototype()); @@ -138,6 +138,7 @@ // the collection set. So, we'll recreate such entries now. obj->oop_iterate(_update_rset_cl); + HeapWord* obj_end = obj_addr + obj_size; _last_forwarded_object_end = obj_end; _hr->cross_threshold(obj_addr, obj_end); }
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -186,11 +186,9 @@ private: G1CollectedHeap* _g1h; G1ConcurrentMark* _cm; - uint _worker_id; public: - G1RootRegionScanClosure(G1CollectedHeap* g1h, G1ConcurrentMark* cm, - uint worker_id) : - _g1h(g1h), _cm(cm), _worker_id(worker_id) { } + G1RootRegionScanClosure(G1CollectedHeap* g1h, G1ConcurrentMark* cm) : + _g1h(g1h), _cm(cm) { } template <class T> void do_oop_nv(T* p); virtual void do_oop( oop* p) { do_oop_nv(p); } virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
--- a/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1OopClosures.inline.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -131,7 +131,7 @@ if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); HeapRegion* hr = _g1h->heap_region_containing((HeapWord*) obj); - _cm->grayRoot(obj, obj->size(), _worker_id, hr); + _cm->grayRoot(obj, hr); } } @@ -246,7 +246,7 @@ assert(!_g1->heap_region_containing(obj)->in_collection_set(), "should not mark objects in the CSet"); // We know that the object is not moving so it's safe to read its size. - _cm->grayRoot(obj, (size_t) obj->size(), _worker_id); + _cm->grayRoot(obj); } void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) { @@ -261,7 +261,7 @@ // worker so we cannot trust that its to-space image is // well-formed. So we have to read its size from its from-space // image which we know should not be changing. - _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id); + _cm->grayRoot(to_obj); } template <G1Barrier barrier, G1Mark do_mark_object, bool use_ext>
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -38,6 +38,7 @@ #include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionManager.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" +#include "gc/shared/gcTraceTime.inline.hpp" #include "memory/iterator.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" @@ -84,8 +85,16 @@ return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads); } -void G1RemSet::initialize(uint max_regions) { +void G1RemSet::initialize(size_t capacity, uint max_regions) { G1FromCardCache::initialize(num_par_rem_sets(), max_regions); + { + GCTraceTime(Debug, gc, marking)("Initialize Card Live Data"); + _card_live_data.initialize(capacity, max_regions); + } + if (G1PretouchAuxiliaryMemory) { + GCTraceTime(Debug, gc, marking)("Pre-Touch Card Live Data"); + _card_live_data.pretouch(); + } } ScanRSClosure::ScanRSClosure(G1ParPushHeapRSClosure* oc, @@ -312,27 +321,24 @@ _into_cset_dirty_card_queue_set.clear_n_completed_buffers(); } -class ScrubRSClosure: public HeapRegionClosure { +class G1ScrubRSClosure: public HeapRegionClosure { G1CollectedHeap* _g1h; - BitMap* _region_bm; - BitMap* _card_bm; - CardTableModRefBS* _ctbs; + G1CardLiveData* _live_data; public: - ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) : + G1ScrubRSClosure(G1CardLiveData* live_data) : _g1h(G1CollectedHeap::heap()), - _region_bm(region_bm), _card_bm(card_bm), - _ctbs(_g1h->g1_barrier_set()) {} + _live_data(live_data) { } bool doHeapRegion(HeapRegion* r) { if (!r->is_continues_humongous()) { - r->rem_set()->scrub(_ctbs, _region_bm, _card_bm); + r->rem_set()->scrub(_live_data); } return false; } }; -void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) { - ScrubRSClosure scrub_cl(region_bm, card_bm); +void G1RemSet::scrub(uint worker_num, HeapRegionClaimer *hrclaimer) { + G1ScrubRSClosure scrub_cl(&_card_live_data); _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer); } @@ -580,3 +586,25 @@ assert(JavaThread::dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed"); } } + +void G1RemSet::create_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap) { + _card_live_data.create(workers, mark_bitmap); +} + +void G1RemSet::finalize_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap) { + _card_live_data.finalize(workers, mark_bitmap); +} + +void G1RemSet::verify_card_live_data(WorkGang* workers, G1CMBitMap* bitmap) { + _card_live_data.verify(workers, bitmap); +} + +void G1RemSet::clear_card_live_data(WorkGang* workers) { + _card_live_data.clear(workers); +} + +#ifdef ASSERT +void G1RemSet::verify_card_live_data_is_clear() { + _card_live_data.verify_is_clear(); +} +#endif
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1RemSet.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -26,6 +26,7 @@ #define SHARE_VM_GC_G1_G1REMSET_HPP #include "gc/g1/dirtyCardQueue.hpp" +#include "gc/g1/g1CardLiveData.hpp" #include "gc/g1/g1RemSetSummary.hpp" #include "gc/g1/heapRegion.hpp" #include "memory/allocation.hpp" @@ -48,9 +49,10 @@ // A G1RemSet in which each heap region has a rem set that records the // external heap references into it. Uses a mod ref bs to track updates, // so that they can be used to update the individual region remsets. - class G1RemSet: public CHeapObj<mtGC> { private: + G1CardLiveData _card_live_data; + G1RemSetSummary _prev_period_summary; // A DirtyCardQueueSet that is used to hold cards that contain @@ -83,7 +85,7 @@ static uint num_par_rem_sets(); // Initialize data that depends on the heap size being known. - static void initialize(uint max_regions); + void initialize(size_t capacity, uint max_regions); // This is called to reset dual hash tables after the gc pause // is finished and the initial hash table is no longer being @@ -140,7 +142,7 @@ // set entries that correspond to dead heap ranges. "worker_num" is the // parallel thread id of the current thread, and "hrclaimer" is the // HeapRegionClaimer that should be used. - void scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer* hrclaimer); + void scrub(uint worker_num, HeapRegionClaimer* hrclaimer); // Refine the card corresponding to "card_ptr". // If check_for_refs_into_cset is true, a true result is returned @@ -162,6 +164,19 @@ size_t conc_refine_cards() const { return _conc_refine_cards; } + + void create_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap); + void finalize_card_live_data(WorkGang* workers, G1CMBitMap* mark_bitmap); + + // Verify that the liveness count data created concurrently matches one created + // during this safepoint. + void verify_card_live_data(WorkGang* workers, G1CMBitMap* actual_bitmap); + + void clear_card_live_data(WorkGang* workers); + +#ifdef ASSERT + void verify_card_live_data_is_clear(); +#endif }; class ScanRSClosure : public HeapRegionClosure {
--- a/hotspot/src/share/vm/gc/g1/g1_globals.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/g1_globals.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -260,6 +260,9 @@ "The target number of mixed GCs after a marking cycle.") \ range(0, max_uintx) \ \ + experimental(bool, G1PretouchAuxiliaryMemory, false, \ + "Pre-touch large auxiliary data structures used by the GC.") \ + \ experimental(bool, G1EagerReclaimHumongousObjects, true, \ "Try to reclaim dead large objects at every young GC.") \ \
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -26,6 +26,7 @@ #include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/g1BlockOffsetTable.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1CardLiveData.inline.hpp" #include "gc/g1/heapRegionManager.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" #include "gc/shared/space.inline.hpp" @@ -141,10 +142,8 @@ add_reference_work(from, /*parallel*/ false); } - void scrub(CardTableModRefBS* ctbs, BitMap* card_bm) { - HeapWord* hr_bot = hr()->bottom(); - size_t hr_first_card_index = ctbs->index_for(hr_bot); - bm()->set_intersection_at_offset(*card_bm, hr_first_card_index); + void scrub(G1CardLiveData* live_data) { + live_data->remove_nonlive_cards(hr()->hrm_index(), &_bm); recount_occupied(); } @@ -515,14 +514,12 @@ return max; } -void OtherRegionsTable::scrub(CardTableModRefBS* ctbs, - BitMap* region_bm, BitMap* card_bm) { +void OtherRegionsTable::scrub(G1CardLiveData* live_data) { // First eliminated garbage regions from the coarse map. log_develop_trace(gc, remset, scrub)("Scrubbing region %u:", _hr->hrm_index()); - assert(_coarse_map.size() == region_bm->size(), "Precondition"); log_develop_trace(gc, remset, scrub)(" Coarse map: before = " SIZE_FORMAT "...", _n_coarse_entries); - _coarse_map.set_intersection(*region_bm); + live_data->remove_nonlive_regions(&_coarse_map); _n_coarse_entries = _coarse_map.count_one_bits(); log_develop_trace(gc, remset, scrub)(" after = " SIZE_FORMAT ".", _n_coarse_entries); @@ -534,7 +531,7 @@ PerRegionTable* nxt = cur->collision_list_next(); // If the entire region is dead, eliminate. log_develop_trace(gc, remset, scrub)(" For other region %u:", cur->hr()->hrm_index()); - if (!region_bm->at((size_t) cur->hr()->hrm_index())) { + if (!live_data->is_region_live(cur->hr()->hrm_index())) { *prev = nxt; cur->set_collision_list_next(NULL); _n_fine_entries--; @@ -544,7 +541,7 @@ } else { // Do fine-grain elimination. log_develop_trace(gc, remset, scrub)(" occ: before = %4d.", cur->occupied()); - cur->scrub(ctbs, card_bm); + cur->scrub(live_data); log_develop_trace(gc, remset, scrub)(" after = %4d.", cur->occupied()); // Did that empty the table completely? if (cur->occupied() == 0) { @@ -773,9 +770,8 @@ assert(verify_ready_for_par_iteration(), "post-condition"); } -void HeapRegionRemSet::scrub(CardTableModRefBS* ctbs, - BitMap* region_bm, BitMap* card_bm) { - _other_regions.scrub(ctbs, region_bm, card_bm); +void HeapRegionRemSet::scrub(G1CardLiveData* live_data) { + _other_regions.scrub(live_data); } // Code roots support
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -35,6 +35,7 @@ class G1CollectedHeap; class G1BlockOffsetTable; +class G1CardLiveData; class HeapRegion; class HeapRegionRemSetIterator; class PerRegionTable; @@ -143,7 +144,7 @@ // Removes any entries shown by the given bitmaps to contain only dead // objects. Not thread safe. // Set bits in the bitmaps indicate that the given region or card is live. - void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); + void scrub(G1CardLiveData* live_data); // Returns whether this remembered set (and all sub-sets) does not contain any entry. bool is_empty() const; @@ -230,10 +231,9 @@ _other_regions.add_reference(from, tid); } - // Removes any entries in the remembered set shown by the given bitmaps to + // Removes any entries in the remembered set shown by the given card live data to // contain only dead objects. Not thread safe. - // One bits in the bitmaps indicate that the given region or card is live. - void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); + void scrub(G1CardLiveData* live_data); // The region is being reclaimed; clear its remset, and any mention of // entries for this region in other remsets.
--- a/hotspot/src/share/vm/gc/parallel/generationSizer.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/parallel/generationSizer.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -26,18 +26,6 @@ #include "gc/parallel/generationSizer.hpp" #include "gc/shared/collectorPolicy.hpp" -void GenerationSizer::trace_gen_sizes(const char* const str) { - if (TracePageSizes) { - tty->print_cr("%s: " SIZE_FORMAT "," SIZE_FORMAT " " - SIZE_FORMAT "," SIZE_FORMAT " " - SIZE_FORMAT, - str, - _min_old_size / K, _max_old_size / K, - _min_young_size / K, _max_young_size / K, - _max_heap_byte_size / K); - } -} - void GenerationSizer::initialize_alignments() { _space_alignment = _gen_alignment = default_gen_alignment(); _heap_alignment = compute_heap_alignment(); @@ -60,7 +48,6 @@ } void GenerationSizer::initialize_size_info() { - trace_gen_sizes("ps heap raw"); const size_t max_page_sz = os::page_size_for_region_aligned(_max_heap_byte_size, 8); const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old const size_t min_page_sz = os::page_size_for_region_aligned(_min_heap_byte_size, min_pages); @@ -76,6 +63,4 @@ initialize_flags(); } GenCollectorPolicy::initialize_size_info(); - - trace_gen_sizes("ps heap rnd"); }
--- a/hotspot/src/share/vm/gc/parallel/generationSizer.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/parallel/generationSizer.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -33,8 +33,6 @@ class GenerationSizer : public GenCollectorPolicy { private: - void trace_gen_sizes(const char* const str); - // The alignment used for boundary between young gen and old gen static size_t default_gen_alignment() { return 64 * K * HeapWordSize; }
--- a/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -49,7 +49,7 @@ const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 : MAX2(page_sz, granularity); ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0); - os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz, + os::trace_page_sizes("Mark Bitmap", raw_bytes, raw_bytes, page_sz, rs.base(), rs.size()); MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
--- a/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/parallel/parallelScavengeHeap.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -60,8 +60,10 @@ ReservedSpace heap_rs = Universe::reserve_heap(heap_size, _collector_policy->heap_alignment()); - os::trace_page_sizes("ps main", _collector_policy->min_heap_byte_size(), - heap_size, generation_alignment(), + os::trace_page_sizes("Heap", + _collector_policy->min_heap_byte_size(), + heap_size, + generation_alignment(), heap_rs.base(), heap_rs.size());
--- a/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/parallel/psAdaptiveSizePolicy.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -32,7 +32,6 @@ #include "gc/shared/gcPolicyCounters.hpp" #include "logging/log.hpp" #include "runtime/timer.hpp" -#include "utilities/top.hpp" #include <math.h>
--- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -426,7 +426,7 @@ const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 : MAX2(page_sz, granularity); ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0); - os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(), + os::trace_page_sizes("Parallel Compact Data", raw_bytes, raw_bytes, page_sz, rs.base(), rs.size()); MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -692,7 +692,7 @@ _promo_failure_scan_stack.clear(true); // Clear cached segments. remove_forwarding_pointers(); - log_debug(gc)("Promotion failed"); + log_info(gc, promotion)("Promotion failed"); // Add to-space to the list of space to compact // when a promotion failure has occurred. In that // case there can be live objects in to-space @@ -739,8 +739,7 @@ eden()->object_iterate(&rspc); from()->object_iterate(&rspc); - // Now restore saved marks, if any. - _preserved_marks_set.restore(); + _preserved_marks_set.restore(GenCollectedHeap::heap()->workers()); } void DefNewGeneration::handle_promotion_failure(oop old) {
--- a/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/shared/cardTableModRefBS.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -93,7 +93,7 @@ MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtGC); - os::trace_page_sizes("card table", _guard_index + 1, _guard_index + 1, + os::trace_page_sizes("Card Table", _guard_index + 1, _guard_index + 1, _page_size, heap_rs.base(), heap_rs.size()); if (!heap_rs.is_reserved()) { vm_exit_during_initialization("Could not reserve enough space for the "
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -167,6 +167,14 @@ SIZE_FORMAT, total_reserved, alignment); *heap_rs = Universe::reserve_heap(total_reserved, alignment); + + os::trace_page_sizes("Heap", + collector_policy()->min_heap_byte_size(), + total_reserved, + alignment, + heap_rs->base(), + heap_rs->size()); + return heap_rs->base(); }
--- a/hotspot/src/share/vm/gc/shared/preservedMarks.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/shared/preservedMarks.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -24,24 +24,30 @@ #include "precompiled.hpp" #include "gc/shared/preservedMarks.inline.hpp" +#include "gc/shared/workgroup.hpp" #include "memory/allocation.inline.hpp" -#include "oops/oop.inline.hpp" void PreservedMarks::restore() { - // First, iterate over the stack and restore all marks. - StackIterator<OopAndMarkOop, mtGC> iter(_stack); - while (!iter.is_empty()) { - OopAndMarkOop elem = iter.next(); + while (!_stack.is_empty()) { + const OopAndMarkOop elem = _stack.pop(); elem.set_mark(); } + assert_empty(); +} - // Second, reclaim all the stack memory - _stack.clear(true /* clear_cache */); +#ifndef PRODUCT +void PreservedMarks::assert_empty() { + assert(_stack.is_empty(), "stack expected to be empty, size = "SIZE_FORMAT, + _stack.size()); + assert(_stack.cache_size() == 0, + "stack expected to have no cached segments, cache size = "SIZE_FORMAT, + _stack.cache_size()); } +#endif // ndef PRODUCT void RemoveForwardedPointerClosure::do_object(oop obj) { if (obj->is_forwarded()) { - obj->init_mark(); + PreservedMarks::init_forwarded_mark(obj); } } @@ -61,15 +67,48 @@ assert_empty(); } +class ParRestoreTask : public AbstractGangTask { +private: + PreservedMarksSet* const _preserved_marks_set; + SequentialSubTasksDone _sub_tasks; + volatile size_t* const _total_size_addr; + +public: + virtual void work(uint worker_id) { + uint task_id = 0; + while (!_sub_tasks.is_task_claimed(/* reference */ task_id)) { + PreservedMarks* const preserved_marks = _preserved_marks_set->get(task_id); + const size_t size = preserved_marks->size(); + preserved_marks->restore(); + // Only do the atomic add if the size is > 0. + if (size > 0) { + Atomic::add(size, _total_size_addr); + } + } + _sub_tasks.all_tasks_completed(); + } + + ParRestoreTask(uint worker_num, + PreservedMarksSet* preserved_marks_set, + volatile size_t* total_size_addr) + : AbstractGangTask("Parallel Preserved Mark Restoration"), + _preserved_marks_set(preserved_marks_set), + _total_size_addr(total_size_addr) { + _sub_tasks.set_n_threads(worker_num); + _sub_tasks.set_n_tasks(preserved_marks_set->num()); + } +}; + +void PreservedMarksSet::restore_internal(WorkGang* workers, + volatile size_t* total_size_addr) { + assert(workers != NULL, "pre-condition"); + ParRestoreTask task(workers->active_workers(), this, total_size_addr); + workers->run_task(&task); +} + +// temporary, used by PS void PreservedMarksSet::restore() { - size_t total_size = 0; - for (uint i = 0; i < _num; i += 1) { - total_size += get(i)->size(); - get(i)->restore(); - } - assert_empty(); - - log_trace(gc)("Restored " SIZE_FORMAT " marks", total_size); + restore<WorkGang>(NULL); } void PreservedMarksSet::reclaim() { @@ -92,7 +131,7 @@ void PreservedMarksSet::assert_empty() { assert(_stacks != NULL && _num > 0, "should have been initialized"); for (uint i = 0; i < _num; i += 1) { - assert(get(i)->is_empty(), "stack should be empty"); + get(i)->assert_empty(); } } #endif // ndef PRODUCT
--- a/hotspot/src/share/vm/gc/shared/preservedMarks.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/shared/preservedMarks.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -44,6 +44,8 @@ }; typedef Stack<OopAndMarkOop, mtGC> OopAndMarkOopStack; +class WorkGang; + class PreservedMarks VALUE_OBJ_CLASS_SPEC { private: OopAndMarkOopStack _stack; @@ -52,13 +54,19 @@ inline void push(oop obj, markOop m); public: - bool is_empty() const { return _stack.is_empty(); } size_t size() const { return _stack.size(); } inline void push_if_necessary(oop obj, markOop m); - // Iterate over the stack, restore the preserved marks, then reclaim - // the memory taken up by stack chunks. + // Iterate over the stack, restore all preserved marks, and + // reclaim the memory taken up by the stack segments. void restore(); - ~PreservedMarks() { assert(is_empty(), "should have been cleared"); } + + inline static void init_forwarded_mark(oop obj); + + // Assert the stack is empty and has no cached segments. + void assert_empty() PRODUCT_RETURN; + + inline PreservedMarks(); + ~PreservedMarks() { assert_empty(); } }; class RemoveForwardedPointerClosure: public ObjectClosure { @@ -82,7 +90,12 @@ // or == NULL if they have not. Padded<PreservedMarks>* _stacks; + // Internal version of restore() that uses a WorkGang for parallelism. + void restore_internal(WorkGang* workers, volatile size_t* total_size_addr); + public: + uint num() const { return _num; } + // Return the i'th stack. PreservedMarks* get(uint i = 0) const { assert(_num > 0 && _stacks != NULL, "stacks should have been initialized"); @@ -92,13 +105,23 @@ // Allocate stack array. void init(uint num); - // Iterate over all stacks, restore all preserved marks, then - // reclaim the memory taken up by stack chunks. + + // Itrerate over all stacks, restore all presered marks, and reclaim + // the memory taken up by the stack segments. If the executor is + // NULL, restoration will be done serially. If the executor is not + // NULL, restoration could be done in parallel (when it makes + // sense). Supported executors: WorkGang (Serial, CMS, G1) + template <class E> + inline void restore(E* executor); + + // Do the restoration serially. Temporary, to be used by PS until we + // can support GCTaskManager in restore(E*). void restore(); + // Reclaim stack array. void reclaim(); - // Assert all the stacks are empty. + // Assert all the stacks are empty and have no cached segments. void assert_empty() PRODUCT_RETURN; PreservedMarksSet(bool in_c_heap)
--- a/hotspot/src/share/vm/gc/shared/preservedMarks.inline.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/gc/shared/preservedMarks.inline.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -22,13 +22,13 @@ * */ -#include "gc/shared/preservedMarks.hpp" -#include "oops/markOop.inline.hpp" -#include "utilities/stack.inline.hpp" - #ifndef SHARE_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP #define SHARE_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP +#include "gc/shared/preservedMarks.hpp" +#include "oops/oop.inline.hpp" +#include "utilities/stack.inline.hpp" + inline bool PreservedMarks::should_preserve_mark(oop obj, markOop m) const { return m->must_be_preserved_for_promotion_failure(obj); } @@ -45,4 +45,48 @@ } } +inline void PreservedMarks::init_forwarded_mark(oop obj) { + obj->init_mark(); +} + +template <class E> +inline void PreservedMarksSet::restore(E* executor) { + volatile size_t total_size = 0; + +#ifdef ASSERT + // This is to make sure the total_size we'll calculate below is correct. + size_t total_size_before = 0; + for (uint i = 0; i < _num; i += 1) { + total_size_before += get(i)->size(); + } +#endif // def ASSERT + + if (executor == NULL) { + for (uint i = 0; i < _num; i += 1) { + total_size += get(i)->size(); + get(i)->restore(); + } + } else { + // Right now, if the executor is not NULL we do the work in + // parallel. In the future we might want to do the restoration + // serially, if there's only a small number of marks per stack. + restore_internal(executor, &total_size); + } + assert_empty(); + + assert(total_size == total_size_before, + "total_size = " SIZE_FORMAT " before = " SIZE_FORMAT, + total_size, total_size_before); + + log_trace(gc)("Restored " SIZE_FORMAT " marks", total_size); +} + +inline PreservedMarks::PreservedMarks() + : _stack(OopAndMarkOopStack::default_segment_size(), + // This stack should be used very infrequently so there's + // no point in caching stack segments (there will be a + // waste of space most of the time). So we set the max + // cache size to 0. + 0 /* max_cache_size */) { } + #endif // SHARE_VM_GC_SHARED_PRESERVEDMARKS_INLINE_HPP
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" +#include "compiler/disassembler.hpp" #include "interpreter/bytecodeHistogram.hpp" #include "interpreter/bytecodeInterpreter.hpp" #include "interpreter/interpreter.hpp" @@ -32,6 +33,7 @@ #include "interpreter/interp_masm.hpp" #include "interpreter/templateTable.hpp" #include "memory/allocation.inline.hpp" +#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "oops/arrayOop.hpp" #include "oops/methodData.hpp" @@ -93,6 +95,7 @@ address AbstractInterpreter::_native_entry_end = NULL; address AbstractInterpreter::_slow_signature_handler; address AbstractInterpreter::_entry_table [AbstractInterpreter::number_of_method_entries]; +address AbstractInterpreter::_cds_entry_table [AbstractInterpreter::number_of_method_entries]; address AbstractInterpreter::_native_abi_to_tosca [AbstractInterpreter::number_of_result_handlers]; //------------------------------------------------------------------------------------------------------------------------ @@ -204,15 +207,42 @@ return zerolocals; } +#if INCLUDE_CDS + +address AbstractInterpreter::get_trampoline_code_buffer(AbstractInterpreter::MethodKind kind) { + const size_t trampoline_size = SharedRuntime::trampoline_size(); + address addr = MetaspaceShared::cds_i2i_entry_code_buffers((size_t)(AbstractInterpreter::number_of_method_entries) * trampoline_size); + addr += (size_t)(kind) * trampoline_size; + + return addr; +} + +void AbstractInterpreter::update_cds_entry_table(AbstractInterpreter::MethodKind kind) { + if (DumpSharedSpaces || UseSharedSpaces) { + address trampoline = get_trampoline_code_buffer(kind); + _cds_entry_table[kind] = trampoline; + + CodeBuffer buffer(trampoline, (int)(SharedRuntime::trampoline_size())); + MacroAssembler _masm(&buffer); + SharedRuntime::generate_trampoline(&_masm, _entry_table[kind]); + + if (PrintInterpreter) { + Disassembler::decode(buffer.insts_begin(), buffer.insts_end()); + } + } +} + +#endif void AbstractInterpreter::set_entry_for_kind(AbstractInterpreter::MethodKind kind, address entry) { assert(kind >= method_handle_invoke_FIRST && kind <= method_handle_invoke_LAST, "late initialization only for MH entry points"); assert(_entry_table[kind] == _entry_table[abstract], "previous value must be AME entry"); _entry_table[kind] = entry; + + update_cds_entry_table(kind); } - // Return true if the interpreter can prove that the given bytecode has // not yet been executed (in Java semantics, not in actual operation). bool AbstractInterpreter::is_not_reached(const methodHandle& method, int bci) { @@ -416,5 +446,6 @@ for (int i = method_handle_invoke_FIRST; i <= method_handle_invoke_LAST; i++) { MethodKind kind = (MethodKind) i; _entry_table[kind] = _entry_table[Interpreter::abstract]; + Interpreter::update_cds_entry_table(kind); } }
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -28,9 +28,8 @@ #include "asm/macroAssembler.hpp" #include "code/stubs.hpp" #include "interpreter/bytecodes.hpp" -#include "runtime/thread.inline.hpp" +#include "runtime/thread.hpp" #include "runtime/vmThread.hpp" -#include "utilities/top.hpp" // This file contains the platform-independent parts // of the abstract interpreter and the abstract interpreter generator. @@ -113,6 +112,7 @@ // method entry points static address _entry_table[number_of_method_entries]; // entry points for a given method + static address _cds_entry_table[number_of_method_entries]; // entry points for methods in the CDS archive static address _native_abi_to_tosca[number_of_result_handlers]; // for native method result handlers static address _slow_signature_handler; // the native method generic (slow) signature handler @@ -132,6 +132,17 @@ static address entry_for_kind(MethodKind k) { assert(0 <= k && k < number_of_method_entries, "illegal kind"); return _entry_table[k]; } static address entry_for_method(methodHandle m) { return entry_for_kind(method_kind(m)); } + static address entry_for_cds_method(methodHandle m) { + MethodKind k = method_kind(m); + assert(0 <= k && k < number_of_method_entries, "illegal kind"); + return _cds_entry_table[k]; + } + + // used by class data sharing + static void update_cds_entry_table(MethodKind kind) NOT_CDS_RETURN; + + static address get_trampoline_code_buffer(AbstractInterpreter::MethodKind kind) NOT_CDS_RETURN_(0); + // used for bootstrapping method handles: static void set_entry_for_kind(MethodKind k, address e);
--- a/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -26,6 +26,7 @@ #define SHARE_VM_INTERPRETER_BYTECODETRACER_HPP #include "memory/allocation.hpp" +#include "utilities/ostream.hpp" // The BytecodeTracer is a helper class used by the interpreter for run-time // bytecode tracing. If bytecode tracing is turned on, trace() will be called
--- a/hotspot/src/share/vm/interpreter/bytecodes.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -26,11 +26,12 @@ #define SHARE_VM_INTERPRETER_BYTECODES_HPP #include "memory/allocation.hpp" -#include "utilities/top.hpp" // Bytecodes specifies all bytecodes used in the VM and // provides utility functions to get bytecode attributes. +class Method; + // NOTE: replicated in SA in vm/agent/sun/jvm/hotspot/interpreter/Bytecodes.java class Bytecodes: AllStatic { public:
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -313,18 +313,7 @@ THROW_HANDLE(exception); IRT_END -IRT_ENTRY(address, InterpreterRuntime::check_ReservedStackAccess_annotated_methods(JavaThread* thread)) - frame fr = thread->last_frame(); - assert(fr.is_java_frame(), "Must be a Java frame"); - frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr); - if (activation.sp() != NULL) { - thread->disable_stack_reserved_zone(); - thread->set_reserved_stack_activation((address)activation.unextended_sp()); - } - return (address)activation.sp(); -IRT_END - - IRT_ENTRY(void, InterpreterRuntime::throw_delayed_StackOverflowError(JavaThread* thread)) +IRT_ENTRY(void, InterpreterRuntime::throw_delayed_StackOverflowError(JavaThread* thread)) Handle exception = get_preinitialized_exception( SystemDictionary::StackOverflowError_klass(), CHECK);
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -31,8 +31,7 @@ #include "oops/method.hpp" #include "runtime/frame.inline.hpp" #include "runtime/signature.hpp" -#include "runtime/thread.inline.hpp" -#include "utilities/top.hpp" +#include "runtime/thread.hpp" // The InterpreterRuntime is called by the interpreter for everything // that cannot/should not be dealt with in assembly and needs C support. @@ -91,8 +90,6 @@ // Quicken instance-of and check-cast bytecodes static void quicken_io_cc(JavaThread* thread); - static address check_ReservedStackAccess_annotated_methods(JavaThread* thread); - // Exceptions thrown by the interpreter static void throw_AbstractMethodError(JavaThread* thread); static void throw_IncompatibleClassChangeError(JavaThread* thread);
--- a/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -26,7 +26,6 @@ #define SHARE_VM_INTERPRETER_LINKRESOLVER_HPP #include "oops/method.hpp" -#include "utilities/top.hpp" // All the necessary definitions for run-time link resolution.
--- a/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -212,6 +212,7 @@ #define method_entry(kind) \ { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \ + Interpreter::update_cds_entry_table(Interpreter::kind); \ } // all non-native method kinds
--- a/hotspot/src/share/vm/logging/log.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/logging/log.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -31,7 +31,10 @@ #include "gc/shared/gcTraceTime.inline.hpp" #include "logging/log.hpp" #include "logging/logConfiguration.hpp" +#include "logging/logFileOutput.hpp" #include "logging/logOutput.hpp" +#include "logging/logTagLevelExpression.hpp" +#include "logging/logTagSet.hpp" #include "logging/logStream.inline.hpp" #include "memory/resourceArea.hpp" @@ -44,6 +47,13 @@ #define assert_char_not_in(c, s) \ assert(strchr(s, c) == NULL, "Expected '%s' to *not* contain character '%c'", s, c) +void Test_log_tag_combinations_limit() { + assert(LogTagLevelExpression::MaxCombinations > LogTagSet::ntagsets(), + "Combination limit (" SIZE_FORMAT ") not sufficient " + "for configuring all available tag sets (" SIZE_FORMAT ")", + LogTagLevelExpression::MaxCombinations, LogTagSet::ntagsets()); +} + class TestLogFile { private: char file_name[256]; @@ -129,6 +139,131 @@ assert_str_eq("all=off", stdoutput->config_string()); } +static size_t number_of_lines_with_substring_in_file(const char* filename, + const char* substr) { + ResourceMark rm; + size_t ret = 0; + FILE* fp = fopen(filename, "r"); + assert(fp != NULL, "error opening file %s: %s", filename, strerror(errno)); + + int buflen = 512; + char* buf = NEW_RESOURCE_ARRAY(char, buflen); + long pos = 0; + + while (fgets(buf, buflen, fp) != NULL) { + if (buf[strlen(buf) - 1] != '\n' && !feof(fp)) { + // retry with a larger buffer + buf = REALLOC_RESOURCE_ARRAY(char, buf, buflen, buflen * 2); + buflen *= 2; + // rewind to beginning of line + fseek(fp, pos, SEEK_SET); + continue; + } + pos = ftell(fp); + if (strstr(buf, substr) != NULL) { + ret++; + } + } + + fclose(fp); + return ret; +} + +static bool file_exists(const char* filename) { + struct stat st; + return os::stat(filename, &st) == 0; +} + +static void delete_file(const char* filename) { + if (!file_exists(filename)) { + return; + } + int ret = remove(filename); + assert(ret == 0, "failed to remove file '%s': %s", filename, strerror(errno)); +} + +static void create_directory(const char* name) { + assert(!file_exists(name), "can't create directory: %s already exists", name); + bool failed; +#ifdef _WINDOWS + failed = !CreateDirectory(name, NULL); +#else + failed = mkdir(name, 0777); +#endif + assert(!failed, "failed to create directory %s", name); +} + +static const char* ExpectedLine = "a (hopefully) unique log line for testing"; + +static void init_file(const char* filename, const char* options = "") { + LogConfiguration::parse_log_arguments(filename, "logging=trace", "", options, + Log(logging)::error_stream()); + log_debug(logging)("%s", ExpectedLine); + LogConfiguration::parse_log_arguments(filename, "all=off", "", "", + Log(logging)::error_stream()); +} + +void Test_log_file_startup_rotation() { + ResourceMark rm; + const size_t rotations = 5; + const char* filename = "start-rotate-test"; + char* rotated_file[rotations]; + for (size_t i = 0; i < rotations; i++) { + size_t len = strlen(filename) + 3; + rotated_file[i] = NEW_RESOURCE_ARRAY(char, len); + jio_snprintf(rotated_file[i], len, "%s." SIZE_FORMAT, filename, i); + delete_file(rotated_file[i]); + }; + + delete_file(filename); + init_file(filename); + assert(file_exists(filename), + "configured logging to file '%s' but file was not found", filename); + + // Initialize the same file a bunch more times to trigger rotations + for (size_t i = 0; i < rotations; i++) { + init_file(filename); + assert(file_exists(rotated_file[i]), "existing file was not rotated"); + } + + // Remove a file and expect its slot to be re-used + delete_file(rotated_file[1]); + init_file(filename); + assert(file_exists(rotated_file[1]), "log file not properly rotated"); + + // Clean up after test + delete_file(filename); + for (size_t i = 0; i < rotations; i++) { + delete_file(rotated_file[i]); + } +} + +void Test_log_file_startup_truncation() { + ResourceMark rm; + const char* filename = "start-truncate-test"; + const char* archived_filename = "start-truncate-test.0"; + + delete_file(filename); + delete_file(archived_filename); + + // Use the same log file twice and expect it to be overwritten/truncated + init_file(filename, "filecount=0"); + assert(file_exists(filename), "couldn't find log file: %s", filename); + + init_file(filename, "filecount=0"); + assert(file_exists(filename), "couldn't find log file: %s", filename); + assert(!file_exists(archived_filename), + "existing log file %s was not properly truncated when filecount was 0", + filename); + + // Verify that the file was really truncated and not just appended + assert(number_of_lines_with_substring_in_file(filename, ExpectedLine) == 1, + "log file %s appended rather than truncated", filename); + + delete_file(filename); + delete_file(archived_filename); +} + static int Test_logconfiguration_subscribe_triggered = 0; static void Test_logconfiguration_subscribe_helper() { @@ -361,11 +496,32 @@ Test_logstream_helper(stream); } +static void Test_logstreamcheap_log() { + Log(gc) log; + LogStreamCHeap stream(log.debug()); + + Test_logstream_helper(&stream); +} + +static void Test_logstreamcheap_logtarget() { + LogTarget(Debug, gc) log; + LogStreamCHeap stream(log); + + Test_logstream_helper(&stream); +} + void Test_logstream() { + // Test LogStreams with embedded ResourceMark. Test_logstream_log(); Test_logstream_logtarget(); Test_logstream_logstreamhandle(); + + // Test LogStreams without embedded ResourceMark. Test_logstream_no_rm(); + + // Test LogStreams backed by CHeap memory. + Test_logstreamcheap_log(); + Test_logstreamcheap_logtarget(); } void Test_loghandle_on() { @@ -377,7 +533,7 @@ assert(log_handle.is_debug(), "assert"); - // Try to log trough a LogHandle. + // Try to log through a LogHandle. log_handle.debug("%d workers", 3); FILE* fp = fopen(log_file.name(), "r"); @@ -408,7 +564,7 @@ return; } - // Try to log trough a LogHandle. Should fail, since only info is turned on. + // Try to log through a LogHandle. Should fail, since only info is turned on. log_handle.debug("%d workers", 3); // Log a dummy line so that fgets doesn't return NULL because the file is empty. @@ -440,7 +596,7 @@ assert(log_handle.is_enabled(), "assert"); - // Try to log trough a LogHandle. + // Try to log through a LogHandle. log_handle.print("%d workers", 3); FILE* fp = fopen(log_file.name(), "r"); @@ -471,7 +627,7 @@ return; } - // Try to log trough a LogHandle. Should fail, since only info is turned on. + // Try to log through a LogHandle. Should fail, since only info is turned on. log_handle.print("%d workers", 3); // Log a dummy line so that fgets doesn't return NULL because the file is empty. @@ -711,4 +867,20 @@ Test_log_gctracetime_no_heap_no_cause(); } +void Test_invalid_log_file() { + ResourceMark rm; + stringStream ss; + const char* target_name = "tmplogdir"; + + // Attempt to log to a directory (existing log not a regular file) + create_directory(target_name); + LogFileOutput bad_file("tmplogdir"); + assert(bad_file.initialize("", &ss) == false, "file was initialized " + "when there was an existing directory with the same name"); + assert(strstr(ss.as_string(), "tmplogdir is not a regular file") != NULL, + "missing expected error message, received msg: %s", ss.as_string()); + ss.reset(); + remove(target_name); +} + #endif // PRODUCT
--- a/hotspot/src/share/vm/logging/logConfiguration.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/logging/logConfiguration.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -145,7 +145,7 @@ return NULL; } - bool success = output->initialize(options); + bool success = output->initialize(options, errstream); if (!success) { errstream->print_cr("Initialization of output '%s' using options '%s' failed.", name, options); delete output;
--- a/hotspot/src/share/vm/logging/logFileOutput.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/logging/logFileOutput.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -41,8 +41,9 @@ LogFileOutput::LogFileOutput(const char* name) : LogFileStreamOutput(NULL), _name(os::strdup_check_oom(name, mtLogging)), - _file_name(NULL), _archive_name(NULL), _archive_name_len(0), _current_size(0), - _rotate_size(0), _current_file(1), _file_count(0), _rotation_semaphore(1) { + _file_name(NULL), _archive_name(NULL), _archive_name_len(0), + _rotate_size(DefaultFileSize), _file_count(DefaultFileCount), + _current_size(0), _current_file(0), _rotation_semaphore(1) { _file_name = make_file_name(name, _pid_str, _vm_start_time_str); } @@ -59,9 +60,6 @@ LogFileOutput::~LogFileOutput() { if (_stream != NULL) { - if (_archive_name != NULL) { - archive(); - } if (fclose(_stream) != 0) { jio_fprintf(defaultStream::error_stream(), "Could not close log file '%s' (%s).\n", _file_name, os::strerror(errno)); @@ -72,7 +70,7 @@ os::free(const_cast<char*>(_name)); } -size_t LogFileOutput::parse_value(const char* value_str) { +static size_t parse_value(const char* value_str) { char* end; unsigned long long value = strtoull(value_str, &end, 10); if (!isdigit(*value_str) || end != value_str + strlen(value_str) || value >= SIZE_MAX) { @@ -81,7 +79,80 @@ return value; } -bool LogFileOutput::configure_rotation(const char* options) { +static bool file_exists(const char* filename) { + struct stat dummy_stat; + return os::stat(filename, &dummy_stat) == 0; +} + +static uint number_of_digits(uint number) { + return number < 10 ? 1 : (number < 100 ? 2 : 3); +} + +static bool is_regular_file(const char* filename) { + struct stat st; + int ret = os::stat(filename, &st); + if (ret != 0) { + return false; + } +#ifdef _WINDOWS + return (st.st_mode & S_IFMT) == _S_IFREG; +#else + return S_ISREG(st.st_mode); +#endif +} + +// Try to find the next number that should be used for file rotation. +// Return UINT_MAX on error. +static uint next_file_number(const char* filename, + uint number_of_digits, + uint filecount, + outputStream* errstream) { + bool found = false; + uint next_num = 0; + + // len is filename + dot + digits + null char + size_t len = strlen(filename) + number_of_digits + 2; + char* archive_name = NEW_C_HEAP_ARRAY(char, len, mtLogging); + char* oldest_name = NEW_C_HEAP_ARRAY(char, len, mtLogging); + + for (uint i = 0; i < filecount; i++) { + int ret = jio_snprintf(archive_name, len, "%s.%0*u", + filename, number_of_digits, i); + assert(ret > 0 && static_cast<size_t>(ret) == len - 1, + "incorrect buffer length calculation"); + + if (file_exists(archive_name) && !is_regular_file(archive_name)) { + // We've encountered something that's not a regular file among the + // possible file rotation targets. Fail immediately to prevent + // problems later. + errstream->print_cr("Possible rotation target file '%s' already exists " + "but is not a regular file.", archive_name); + next_num = UINT_MAX; + break; + } + + // Stop looking if we find an unused file name + if (!file_exists(archive_name)) { + next_num = i; + found = true; + break; + } + + // Keep track of oldest existing log file + if (!found + || os::compare_file_modified_times(oldest_name, archive_name) > 0) { + strcpy(oldest_name, archive_name); + next_num = i; + found = true; + } + } + + FREE_C_HEAP_ARRAY(char, oldest_name); + FREE_C_HEAP_ARRAY(char, archive_name); + return next_num; +} + +bool LogFileOutput::parse_options(const char* options, outputStream* errstream) { if (options == NULL || strlen(options) == 0) { return true; } @@ -107,22 +178,25 @@ if (strcmp(FileCountOptionKey, key) == 0) { size_t value = parse_value(value_str); - if (value == SIZE_MAX || value >= UINT_MAX) { + if (value > MaxRotationFileCount) { + errstream->print_cr("Invalid option: %s must be in range [0, %u]", + FileCountOptionKey, + MaxRotationFileCount); success = false; break; } _file_count = static_cast<uint>(value); - _file_count_max_digits = static_cast<uint>(log10(static_cast<double>(_file_count)) + 1); - _archive_name_len = 2 + strlen(_file_name) + _file_count_max_digits; - _archive_name = NEW_C_HEAP_ARRAY(char, _archive_name_len, mtLogging); } else if (strcmp(FileSizeOptionKey, key) == 0) { size_t value = parse_value(value_str); if (value == SIZE_MAX || value > SIZE_MAX / K) { + errstream->print_cr("Invalid option: %s must be in range [0, " + SIZE_FORMAT "]", FileSizeOptionKey, SIZE_MAX / K); success = false; break; } _rotate_size = value * K; } else { + errstream->print_cr("Invalid option '%s' for log file output.", key); success = false; break; } @@ -133,15 +207,54 @@ return success; } -bool LogFileOutput::initialize(const char* options) { - if (!configure_rotation(options)) { +bool LogFileOutput::initialize(const char* options, outputStream* errstream) { + if (!parse_options(options, errstream)) { return false; } + + if (_file_count > 0) { + // compute digits with filecount - 1 since numbers will start from 0 + _file_count_max_digits = number_of_digits(_file_count - 1); + _archive_name_len = 2 + strlen(_file_name) + _file_count_max_digits; + _archive_name = NEW_C_HEAP_ARRAY(char, _archive_name_len, mtLogging); + } + + log_trace(logging)("Initializing logging to file '%s' (filecount: %u" + ", filesize: " SIZE_FORMAT " KiB).", + _file_name, _file_count, _rotate_size / K); + + if (_file_count > 0 && file_exists(_file_name)) { + if (!is_regular_file(_file_name)) { + errstream->print_cr("Unable to log to file %s with log file rotation: " + "%s is not a regular file", + _file_name, _file_name); + return false; + } + _current_file = next_file_number(_file_name, + _file_count_max_digits, + _file_count, + errstream); + if (_current_file == UINT_MAX) { + return false; + } + log_trace(logging)("Existing log file found, saving it as '%s.%0*u'", + _file_name, _file_count_max_digits, _current_file); + archive(); + increment_file_count(); + } + _stream = fopen(_file_name, FileOpenMode); if (_stream == NULL) { - log_error(logging)("Could not open log file '%s' (%s).\n", _file_name, os::strerror(errno)); + errstream->print_cr("Error opening log file '%s': %s", + _file_name, strerror(errno)); return false; } + + if (_file_count == 0 && is_regular_file(_file_name)) { + log_trace(logging)("Truncating log file"); + os::ftruncate(os::fileno(_stream), 0); + } + return true; } @@ -210,7 +323,7 @@ // Reset accumulated size, increase current file counter, and check for file count wrap-around. _current_size = 0; - _current_file = (_current_file >= _file_count ? 1 : _current_file + 1); + increment_file_count(); } char* LogFileOutput::make_file_name(const char* file_name,
--- a/hotspot/src/share/vm/logging/logFileOutput.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/logging/logFileOutput.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -39,8 +39,11 @@ static const char* PidFilenamePlaceholder; static const char* TimestampFilenamePlaceholder; static const char* TimestampFormat; + static const size_t DefaultFileCount = 5; + static const size_t DefaultFileSize = 20 * M; static const size_t StartTimeBufferSize = 20; - static const size_t PidBufferSize = 21; + static const size_t PidBufferSize = 21; + static const uint MaxRotationFileCount = 1000; static char _pid_str[PidBufferSize]; static char _vm_start_time_str[StartTimeBufferSize]; @@ -61,18 +64,24 @@ void archive(); void rotate(); - bool configure_rotation(const char* options); + bool parse_options(const char* options, outputStream* errstream); char *make_file_name(const char* file_name, const char* pid_string, const char* timestamp_string); - static size_t parse_value(const char* value_str); bool should_rotate() { return _file_count > 0 && _rotate_size > 0 && _current_size >= _rotate_size; } + void increment_file_count() { + _current_file++; + if (_current_file == _file_count) { + _current_file = 0; + } + } + public: LogFileOutput(const char *name); virtual ~LogFileOutput(); - virtual bool initialize(const char* options); + virtual bool initialize(const char* options, outputStream* errstream); virtual int write(const LogDecorations& decorations, const char* msg); virtual void force_rotate();
--- a/hotspot/src/share/vm/logging/logFileStreamOutput.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/logging/logFileStreamOutput.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -53,7 +53,7 @@ LogStdoutOutput() : LogFileStreamOutput(stdout) { set_config_string("all=off"); } - virtual bool initialize(const char* options) { + virtual bool initialize(const char* options, outputStream* errstream) { return false; } public: @@ -69,7 +69,7 @@ LogStderrOutput() : LogFileStreamOutput(stderr) { set_config_string("all=warning"); } - virtual bool initialize(const char* options) { + virtual bool initialize(const char* options, outputStream* errstream) { return false; } public:
--- a/hotspot/src/share/vm/logging/logHandle.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/logging/logHandle.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -67,13 +67,13 @@ // This can be used to pass a Log instance as a parameter without // polluting the surrounding API with template functions. class LogTargetHandle { - friend class LogStream; - private: const LogLevelType _level; LogTagSet* _tagset; public: + LogTargetHandle(LogLevelType level, LogTagSet* tagset) : _level(level), _tagset(tagset) {} + template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag> LogTargetHandle(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>& type_carrier) : _level(level),
--- a/hotspot/src/share/vm/logging/logOutput.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/logging/logOutput.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -82,7 +82,7 @@ } virtual const char* name() const = 0; - virtual bool initialize(const char* options) = 0; + virtual bool initialize(const char* options, outputStream* errstream) = 0; virtual int write(const LogDecorations &decorations, const char* msg) = 0; };
--- a/hotspot/src/share/vm/logging/logStream.cpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/logging/logStream.cpp Thu Apr 14 19:55:39 2016 -0700 @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "logging/log.hpp" -#include "logging/logStream.hpp" +#include "logging/logStream.inline.hpp" // Create a log stream without an embedded ResourceMark. // The function is placed here to be called out-of-line in log.hpp.
--- a/hotspot/src/share/vm/logging/logStream.hpp Thu Apr 14 09:33:16 2016 -0700 +++ b/hotspot/src/share/vm/logging/logStream.hpp Thu Apr 14 19:55:39 2016 -0700 @@ -26,23 +26,100 @@ #define SHARE_VM_LOGGING_LOGSTREAM_HPP #include "logging/log.hpp" +#include "logging/logHandle.hpp" +#include "memory/resourceArea.hpp" #include "utilities/ostream.hpp" -// An output stream that logs to the logging framework. -// Requires a ResourceMark on the stack. -class LogStreamNoResourceMark : public outputStream { -private: - stringStream _current_line; - LogLevelType _level; - LogTagSet* _tagset; +// The base class of an output stream that logs to the logging framework. +template <class streamClass> +class LogStreamBase : public outputStream { + streamClass _current_line; + LogTargetHandle _log_handle; public: - LogStreamNoResourceMark(LogLevelType level, LogTagSet* tagset) : _level(level), _tagset(tagset) {} - ~LogStreamNoResourceMark() { + // Constructor to support creation from a LogTarget instance. + // + // LogTarget(Debug, gc) log; + // LogStreamBase(log) stream; + template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag> + LogStreamBase(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>& type_carrier) :