--- 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);
+}
+
+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);
}
-// 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::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) :
+ _log_handle(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
+
+ // Constructor to support creation from typed (likely NULL) pointer. Mostly used by the logging framework.
+ //
+ // LogStreamBase stream(log.debug());
+ // or
+ // LogStreamBase stream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL);
+ 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) :
+ _log_handle(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
+
+ // Constructor to support creation from a LogTargetHandle.
+ //
+ // LogTarget(Debug, gc) log;
+ // LogTargetHandle(log) handle;
+ // LogStreamBase stream(handle);
+ LogStreamBase(LogTargetHandle handle) : _log_handle(handle) {}
+
+ // Constructor to support creation from a log level and tagset.
+ //
+ // LogStreamBase(level, tageset);
+ LogStreamBase(LogLevelType level, LogTagSet* tagset) : _log_handle(level, tagset) {}
+
+ ~LogStreamBase() {
guarantee(_current_line.size() == 0, "Buffer not flushed. Missing call to print_cr()?");
}
+public:
void write(const char* s, size_t len);
};
+// A stringStream with an embedded ResourceMark.
+class stringStreamWithResourceMark : outputStream {
+ private:
+ // The stringStream Resource allocate in the constructor,
+ // so the order of the fields is important.
+ ResourceMark _embedded_resource_mark;
+ stringStream _stream;
+
+ public:
+ stringStreamWithResourceMark(size_t initial_bufsize = 256) :
+ _embedded_resource_mark(),
+ _stream(initial_bufsize) {}
+
+ virtual void write(const char* c, size_t len) { _stream.write(c, len); }
+ size_t size() { return _stream.size(); }
+ const char* base() { return _stream.base(); }
+ void reset() { _stream.reset(); }
+ char* as_string() { return _stream.as_string(); }
+};
+
+// An output stream that logs to the logging framework.
+//
+// The backing buffer is allocated in Resource memory.
+// The caller is required to have a ResourceMark on the stack.
+typedef LogStreamBase<stringStream> LogStreamNoResourceMark;
+
+// An output stream that logs to the logging framework.
+//
+// The backing buffer is allocated in CHeap memory.
+typedef LogStreamBase<bufferedStream> LogStreamCHeap;
+
+// An output stream that logs to the logging framework, and embeds a ResourceMark.
+//
+// The backing buffer is allocated in Resource memory.
+// The class is intended to be stack allocated.
+// The class provides its own ResourceMark,
+// so care needs to be taken when nested ResourceMarks are used.
+typedef LogStreamBase<stringStreamWithResourceMark> LogStream;
+
+// Support creation of a LogStream without having to provide a LogTarget pointer.
+#define LogStreamHandle(level, ...) LogStreamTemplate<LogLevel::level, LOG_TAGS(__VA_ARGS__)>
+
+template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
+class LogStreamTemplate : public LogStream {
+public:
+ LogStreamTemplate() : LogStream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL) {}
+};
+
#endif // SHARE_VM_LOGGING_LOGSTREAM_HPP
--- a/hotspot/src/share/vm/logging/logStream.inline.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/logging/logStream.inline.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -30,10 +30,12 @@
#include "memory/resourceArea.hpp"
#include "utilities/ostream.hpp"
-inline void LogStreamNoResourceMark::write(const char* s, size_t len) {
+template <class streamClass>
+inline void LogStreamBase<streamClass>::write(const char* s, size_t len) {
if (len > 0 && s[len - 1] == '\n') {
_current_line.write(s, len - 1);
- _tagset->write(_level, "%s", _current_line.as_string());
+ _current_line.write("\0", 1);
+ _log_handle.print("%s", _current_line.base());
_current_line.reset();
} else {
_current_line.write(s, len);
@@ -41,54 +43,4 @@
update_position(s, len);
}
-// An output stream that logs to the logging framework, and embeds a ResourceMark.
-//
-// The class is intended to be stack allocated.
-// Care needs to be taken when nested ResourceMarks are used.
-class LogStream : public outputStream {
-private:
- ResourceMark _embedded_resource_mark;
- LogStreamNoResourceMark _stream;
-
-public:
- // Constructor to support creation from a LogTarget instance.
- //
- // LogTarget(Debug, gc) log;
- // LogStream(log) stream;
- template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
- LogStream(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>& type_carrier) :
- _embedded_resource_mark(),
- _stream(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
-
- // Constructor to support creation from typed (likely NULL) pointer. Mostly used by the logging framework.
- //
- // LogStream stream(log.debug());
- // LogStream stream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL);
- template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
- LogStream(const LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>* type_carrier) :
- _embedded_resource_mark(),
- _stream(level, &LogTagSetMapping<T0, T1, T2, T3, T4>::tagset()) {}
-
- // Constructor to support creation from a LogTargetHandle.
- //
- // LogTarget(Debug, gc) log;
- // LogTargetHandle(log) handle;
- // LogStream stream(handle);
- LogStream(LogTargetHandle handle) :
- _embedded_resource_mark(),
- _stream(handle._level, handle._tagset) {}
-
- // Override of outputStream::write.
- void write(const char* s, size_t len) { _stream.write(s, len); }
-};
-
-// Support creation of a LogStream without having to provide a LogTarget pointer.
-#define LogStreamHandle(level, ...) LogStreamTemplate<LogLevel::level, LOG_TAGS(__VA_ARGS__)>
-
-template <LogLevelType level, LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
-class LogStreamTemplate : public LogStream {
-public:
- LogStreamTemplate() : LogStream((LogTargetImpl<level, T0, T1, T2, T3, T4, GuardTag>*)NULL) {}
-};
-
#endif // SHARE_VM_LOGGING_LOGSTREAM_INLINE_HPP
--- a/hotspot/src/share/vm/logging/logTag.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTag.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -48,6 +48,7 @@
LOG_TAG(classpath) \
LOG_TAG(compaction) \
LOG_TAG(constraints) \
+ LOG_TAG(coops) \
LOG_TAG(cpu) \
LOG_TAG(cset) \
LOG_TAG(defaultmethods) \
@@ -69,6 +70,7 @@
LOG_TAG(monitorinflation) \
LOG_TAG(monitormismatch) \
LOG_TAG(os) \
+ LOG_TAG(pagesize) \
LOG_TAG(phases) \
LOG_TAG(plab) \
LOG_TAG(promotion) \
--- a/hotspot/src/share/vm/logging/logTagLevelExpression.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagLevelExpression.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -36,9 +36,12 @@
// Class used to temporary encode a 'what'-expression during log configuration.
// Consists of a combination of tags and levels, e.g. "tag1+tag2=level1,tag3*=level2".
class LogTagLevelExpression : public StackObj {
- friend void LogConfiguration::configure_stdout(LogLevelType, bool, ...);
+ public:
+ static const size_t MaxCombinations = 256;
+
private:
- static const size_t MaxCombinations = 32;
+ friend void LogConfiguration::configure_stdout(LogLevelType, bool, ...);
+
static const char* DefaultExpressionString;
size_t _ntags, _ncombinations;
--- a/hotspot/src/share/vm/logging/logTagSet.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagSet.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -98,6 +98,7 @@
const size_t vwrite_buffer_size = 512;
void LogTagSet::vwrite(LogLevelType level, const char* fmt, va_list args) {
+ assert(level >= LogLevel::First && level <= LogLevel::Last, "Log level:%d is incorrect", level);
char buf[vwrite_buffer_size];
va_list saved_args; // For re-format on buf overflow.
va_copy(saved_args, args);
--- a/hotspot/src/share/vm/logging/logTagSet.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagSet.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -64,6 +64,10 @@
return _list;
}
+ static size_t ntagsets() {
+ return _ntagsets;
+ }
+
LogTagSet* next() {
return _next;
}
--- a/hotspot/src/share/vm/memory/filemap.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/memory/filemap.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -959,6 +959,16 @@
return false;
}
+// Check if a given address is within one of the shared regions (ro, rw, md, mc)
+bool FileMapInfo::is_in_shared_region(const void* p, int idx) {
+ assert((idx >= MetaspaceShared::ro) && (idx <= MetaspaceShared::mc), "invalid region index");
+ char* base = _header->region_addr(idx);
+ if (p >= base && p < base + _header->_space[idx]._used) {
+ return true;
+ }
+ return false;
+}
+
void FileMapInfo::print_shared_spaces() {
tty->print_cr("Shared Spaces:");
for (int i = 0; i < MetaspaceShared::n_regions; i++) {
--- a/hotspot/src/share/vm/memory/filemap.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/memory/filemap.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -107,6 +107,8 @@
int _narrow_klass_shift; // save narrow klass base and shift
address _narrow_klass_base;
char* _misc_data_patching_start;
+ address _cds_i2i_entry_code_buffers;
+ size_t _cds_i2i_entry_code_buffers_size;
struct space_info {
int _crc; // crc checksum of the current space
@@ -195,6 +197,19 @@
char* misc_data_patching_start() { return _header->_misc_data_patching_start; }
void set_misc_data_patching_start(char* p) { _header->_misc_data_patching_start = p; }
+ address cds_i2i_entry_code_buffers() {
+ return _header->_cds_i2i_entry_code_buffers;
+ }
+ void set_cds_i2i_entry_code_buffers(address addr) {
+ _header->_cds_i2i_entry_code_buffers = addr;
+ }
+ size_t cds_i2i_entry_code_buffers_size() {
+ return _header->_cds_i2i_entry_code_buffers_size;
+ }
+ void set_cds_i2i_entry_code_buffers_size(size_t s) {
+ _header->_cds_i2i_entry_code_buffers_size = s;
+ }
+
static FileMapInfo* current_info() {
CDS_ONLY(return _current_info;)
NOT_CDS(return NULL;)
@@ -234,6 +249,7 @@
// Return true if given address is in the mapped shared space.
bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
+ bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
void print_shared_spaces() NOT_CDS_RETURN;
static size_t shared_spaces_size() {
--- a/hotspot/src/share/vm/memory/iterator.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/memory/iterator.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -27,7 +27,7 @@
#include "memory/allocation.hpp"
#include "memory/memRegion.hpp"
-#include "utilities/top.hpp"
+#include "oops/oopsHierarchy.hpp"
class CodeBlob;
class nmethod;
@@ -35,6 +35,7 @@
class DataLayout;
class KlassClosure;
class ClassLoaderData;
+class Symbol;
// The following classes are C++ `closures` for iterating over objects, roots and spaces
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -59,6 +59,8 @@
bool MetaspaceShared::_check_classes_made_progress;
bool MetaspaceShared::_has_error_classes;
bool MetaspaceShared::_archive_loading_failed = false;
+address MetaspaceShared::_cds_i2i_entry_code_buffers = NULL;
+size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0;
SharedMiscRegion MetaspaceShared::_mc;
SharedMiscRegion MetaspaceShared::_md;
@@ -129,6 +131,21 @@
soc->do_tag(666);
}
+address MetaspaceShared::cds_i2i_entry_code_buffers(size_t total_size) {
+ if (DumpSharedSpaces) {
+ if (_cds_i2i_entry_code_buffers == NULL) {
+ _cds_i2i_entry_code_buffers = (address)misc_data_space_alloc(total_size);
+ _cds_i2i_entry_code_buffers_size = total_size;
+ }
+ } else if (UseSharedSpaces) {
+ assert(_cds_i2i_entry_code_buffers != NULL, "must already been initialized");
+ } else {
+ return NULL;
+ }
+
+ assert(_cds_i2i_entry_code_buffers_size == total_size, "must not change");
+ return _cds_i2i_entry_code_buffers;
+}
// CDS code for dumping shared archive.
@@ -576,6 +593,8 @@
&md_top, md_end,
&mc_top, mc_end);
+ guarantee(md_top <= md_end, "Insufficient space for vtables.");
+
// Reorder the system dictionary. (Moving the symbols affects
// how the hash table indices are calculated.)
// Not doing this either.
@@ -668,6 +687,8 @@
FileMapInfo* mapinfo = new FileMapInfo();
mapinfo->populate_header(MetaspaceShared::max_alignment());
mapinfo->set_misc_data_patching_start((char*)vtbl_list);
+ mapinfo->set_cds_i2i_entry_code_buffers(MetaspaceShared::cds_i2i_entry_code_buffers());
+ mapinfo->set_cds_i2i_entry_code_buffers_size(MetaspaceShared::cds_i2i_entry_code_buffers_size());
for (int pass=1; pass<=2; pass++) {
if (pass == 1) {
@@ -686,7 +707,7 @@
mapinfo->write_region(MetaspaceShared::md, _md_vs.low(),
pointer_delta(md_top, _md_vs.low(), sizeof(char)),
SharedMiscDataSize,
- false, false);
+ false, true);
mapinfo->write_region(MetaspaceShared::mc, _mc_vs.low(),
pointer_delta(mc_top, _mc_vs.low(), sizeof(char)),
SharedMiscCodeSize,
@@ -980,6 +1001,11 @@
return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_space(p);
}
+// Return true if given address is in the misc data region
+bool MetaspaceShared::is_in_shared_region(const void* p, int idx) {
+ return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_region(p, idx);
+}
+
bool MetaspaceShared::is_string_region(int idx) {
return (idx >= MetaspaceShared::first_string &&
idx < MetaspaceShared::first_string + MetaspaceShared::max_strings);
@@ -1053,6 +1079,8 @@
void MetaspaceShared::initialize_shared_spaces() {
FileMapInfo *mapinfo = FileMapInfo::current_info();
+ _cds_i2i_entry_code_buffers = mapinfo->cds_i2i_entry_code_buffers();
+ _cds_i2i_entry_code_buffers_size = mapinfo->cds_i2i_entry_code_buffers_size();
char* buffer = mapinfo->misc_data_patching_start();
// Skip over (reserve space for) a list of addresses of C++ vtables
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -50,17 +50,14 @@
#define MIN_SHARED_READ_ONLY_SIZE (NOT_LP64(8*M) LP64_ONLY(9*M))
// the MIN_SHARED_MISC_DATA_SIZE and MIN_SHARED_MISC_CODE_SIZE estimates are based on
-// MetaspaceShared::generate_vtable_methods().
-// The minimum size only accounts for the vtable methods. Any size less than the
-// minimum required size would cause vm crash when allocating the vtable methods.
-#define SHARED_MISC_SIZE_FOR(size) (DEFAULT_VTBL_VIRTUALS_COUNT*DEFAULT_VTBL_LIST_SIZE*size)
+// the sizes required for dumping the archive using the default classlist. The sizes
+// are multiplied by 1.5 for a safety margin.
#define DEFAULT_SHARED_MISC_DATA_SIZE (NOT_LP64(2*M) LP64_ONLY(4*M))
-#define MIN_SHARED_MISC_DATA_SIZE (SHARED_MISC_SIZE_FOR(sizeof(void*)))
+#define MIN_SHARED_MISC_DATA_SIZE (NOT_LP64(1*M) LP64_ONLY(1200*K))
#define DEFAULT_SHARED_MISC_CODE_SIZE (120*K)
-#define MIN_SHARED_MISC_CODE_SIZE (SHARED_MISC_SIZE_FOR(sizeof(void*))+SHARED_MISC_SIZE_FOR(DEFAULT_VTBL_METHOD_SIZE)+DEFAULT_VTBL_COMMON_CODE_SIZE)
-
+#define MIN_SHARED_MISC_CODE_SIZE (NOT_LP64(63*K) LP64_ONLY(69*K))
#define DEFAULT_COMBINED_SIZE (DEFAULT_SHARED_READ_WRITE_SIZE+DEFAULT_SHARED_READ_ONLY_SIZE+DEFAULT_SHARED_MISC_DATA_SIZE+DEFAULT_SHARED_MISC_CODE_SIZE)
// the max size is the MAX size (ie. 0x7FFFFFFF) - the total size of
@@ -128,6 +125,8 @@
static bool _check_classes_made_progress;
static bool _has_error_classes;
static bool _archive_loading_failed;
+ static address _cds_i2i_entry_code_buffers;
+ static size_t _cds_i2i_entry_code_buffers_size;
// Used only during dumping.
static SharedMiscRegion _md;
@@ -185,6 +184,9 @@
// Return true if given address is in the mapped shared space.
static bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
+ // Return true if given address is in the shared region corresponding to the idx
+ static bool is_in_shared_region(const void* p, int idx) NOT_CDS_RETURN_(false);
+
static bool is_string_region(int idx) NOT_CDS_RETURN_(false);
static void generate_vtable_methods(void** vtbl_list,
@@ -218,6 +220,15 @@
static char* misc_code_space_alloc(size_t num_bytes) { return _mc.alloc(num_bytes); }
static char* misc_data_space_alloc(size_t num_bytes) { return _md.alloc(num_bytes); }
+ static address cds_i2i_entry_code_buffers(size_t total_size);
+
+ static address cds_i2i_entry_code_buffers() {
+ return _cds_i2i_entry_code_buffers;
+ }
+ static size_t cds_i2i_entry_code_buffers_size() {
+ return _cds_i2i_entry_code_buffers_size;
+ }
+
static SharedMiscRegion* misc_code_region() {
assert(DumpSharedSpaces, "used during dumping only");
return &_mc;
--- a/hotspot/src/share/vm/memory/resourceArea.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/memory/resourceArea.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -26,7 +26,7 @@
#define SHARE_VM_MEMORY_RESOURCEAREA_HPP
#include "memory/allocation.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
// The resource area holds temporary data structures in the VM.
// The actual allocation areas are thread local. Typical usage:
--- a/hotspot/src/share/vm/memory/universe.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -747,8 +747,10 @@
Universe::set_narrow_ptrs_base(Universe::narrow_oop_base());
- if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
- Universe::print_compressed_oops_mode(tty);
+ if (log_is_enabled(Info, gc, heap, coops)) {
+ ResourceMark rm;
+ outputStream* logst = Log(gc, heap, coops)::info_stream();
+ Universe::print_compressed_oops_mode(logst);
}
// Tell tests in which mode we run.
@@ -776,8 +778,8 @@
}
void Universe::print_compressed_oops_mode(outputStream* st) {
- st->print("heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
- p2i(Universe::heap()->base()), Universe::heap()->reserved_region().byte_size()/M);
+ st->print("Heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB",
+ p2i(Universe::heap()->base()), Universe::heap()->reserved_region().byte_size()/M);
st->print(", Compressed Oops mode: %s", narrow_oop_mode_to_string(narrow_oop_mode()));
--- a/hotspot/src/share/vm/memory/virtualspace.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/memory/virtualspace.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -24,6 +24,8 @@
#include "precompiled.hpp"
#include "code/codeCacheExtensions.hpp"
+#include "logging/log.hpp"
+#include "memory/resourceArea.hpp"
#include "memory/virtualspace.hpp"
#include "oops/markOop.hpp"
#include "oops/oop.inline.hpp"
@@ -78,10 +80,7 @@
// Different reserve address may be acceptable in other cases
// but for compressed oops heap should be at requested address.
assert(UseCompressedOops, "currently requested address used only for compressed oops");
- if (PrintCompressedOopsMode) {
- tty->cr();
- tty->print_cr("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, p2i(base), p2i(requested_address));
- }
+ log_debug(gc, heap, coops)("Reserved memory not at requested address: " PTR_FORMAT " vs " PTR_FORMAT, p2i(base), p2i(requested_address));
// OS ignored requested address. Try different address.
if (special) {
if (!os::release_memory_special(base, size)) {
@@ -143,10 +142,7 @@
// failed; try to reserve regular memory below
if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
!FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
- if (PrintCompressedOopsMode) {
- tty->cr();
- tty->print_cr("Reserve regular memory without large pages.");
- }
+ log_debug(gc, heap, coops)("Reserve regular memory without large pages");
}
}
}
@@ -286,11 +282,10 @@
if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE, _special)) {
fatal("cannot protect protection page");
}
- if (PrintCompressedOopsMode) {
- tty->cr();
- tty->print_cr("Protected page at the reserved heap base: "
- PTR_FORMAT " / " INTX_FORMAT " bytes", p2i(_base), _noaccess_prefix);
- }
+ log_debug(gc, heap, coops)("Protected page at the reserved heap base: "
+ PTR_FORMAT " / " INTX_FORMAT " bytes",
+ p2i(_base),
+ _noaccess_prefix);
assert(Universe::narrow_oop_use_implicit_null_checks() == true, "not initialized?");
} else {
Universe::set_narrow_oop_use_implicit_null_checks(false);
@@ -321,10 +316,10 @@
bool special = large && !os::can_commit_large_page_memory();
char* base = NULL;
- if (PrintCompressedOopsMode && Verbose) {
- tty->print("Trying to allocate at address " PTR_FORMAT " heap of size " SIZE_FORMAT_HEX ".\n",
- p2i(requested_address), size);
- }
+ log_trace(gc, heap, coops)("Trying to allocate at address " PTR_FORMAT
+ " heap of size " SIZE_FORMAT_HEX,
+ p2i(requested_address),
+ size);
if (special) {
base = os::reserve_memory_special(size, alignment, requested_address, false);
@@ -343,10 +338,7 @@
// Failed; try to reserve regular memory below
if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
!FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
- if (PrintCompressedOopsMode) {
- tty->cr();
- tty->print_cr("Reserve regular memory without large pages.");
- }
+ log_debug(gc, heap, coops)("Reserve regular memory without large pages");
}
// Optimistically assume that the OSes returns an aligned base pointer.
@@ -558,9 +550,7 @@
// Last, desperate try without any placement.
if (_base == NULL) {
- if (PrintCompressedOopsMode && Verbose) {
- tty->print("Trying to allocate at address NULL heap of size " SIZE_FORMAT_HEX ".\n", size + noaccess_prefix);
- }
+ log_trace(gc, heap, coops)("Trying to allocate at address NULL heap of size " SIZE_FORMAT_HEX, size + noaccess_prefix);
initialize(size + noaccess_prefix, alignment, large, NULL, false);
}
}
--- a/hotspot/src/share/vm/oops/constMethod.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/oops/constMethod.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -121,6 +121,7 @@
};
class KlassSizeStats;
+class AdapterHandlerEntry;
// Class to collect the sizes of ConstMethod inline tables
#define INLINE_TABLES_DO(do_element) \
@@ -201,6 +202,12 @@
// Raw stackmap data for the method
Array<u1>* _stackmap_data;
+ // Adapter blob (i2c/c2i) for this Method*. Set once when method is linked.
+ union {
+ AdapterHandlerEntry* _adapter;
+ AdapterHandlerEntry** _adapter_trampoline;
+ };
+
int _constMethod_size;
u2 _flags;
@@ -276,6 +283,29 @@
void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPS);
bool has_stackmap_table() const { return _stackmap_data != NULL; }
+ // adapter
+ void set_adapter_entry(AdapterHandlerEntry* adapter) {
+ assert(!is_shared(), "shared methods have fixed adapter_trampoline");
+ _adapter = adapter;
+ }
+ void set_adapter_trampoline(AdapterHandlerEntry** trampoline) {
+ assert(DumpSharedSpaces, "must be");
+ assert(*trampoline == NULL, "must be NULL during dump time, to be initialized at run time");
+ _adapter_trampoline = trampoline;
+ }
+ void update_adapter_trampoline(AdapterHandlerEntry* adapter) {
+ assert(is_shared(), "must be");
+ *_adapter_trampoline = adapter;
+ assert(this->adapter() == adapter, "must be");
+ }
+ AdapterHandlerEntry* adapter() {
+ if (is_shared()) {
+ return *_adapter_trampoline;
+ } else {
+ return _adapter;
+ }
+ }
+
void init_fingerprint() {
const uint64_t initval = UCONST64(0x8000000000000000);
_fingerprint = initval;
--- a/hotspot/src/share/vm/oops/constantPool.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -283,8 +283,9 @@
this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM
// logging for classresolve tag.
- trace_class_resolution(this_cp, k);
-
+ if (log_is_enabled(Debug, classresolve)){
+ trace_class_resolution(this_cp, k);
+ }
this_cp->klass_at_put(which, k());
entry = this_cp->resolved_klass_at(which);
assert(entry.is_resolved() && entry.get_klass()->is_klass(), "must be resolved at this point");
@@ -340,9 +341,7 @@
int cache_index = decode_cpcache_index(which, true);
if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {
// FIXME: should be an assert
- if (PrintMiscellaneous && (Verbose||WizardMode)) {
- tty->print_cr("bad operand %d in:", which); cpool->print();
- }
+ log_debug(classresolve)("bad operand %d in:", which); cpool->print();
return NULL;
}
ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
@@ -396,7 +395,7 @@
int i = which;
if (!uncached && cache() != NULL) {
if (ConstantPool::is_invokedynamic_index(which)) {
- // Invokedynamic index is index into resolved_references
+ // Invokedynamic index is index into the constant pool cache
int pool_index = invokedynamic_cp_cache_entry_at(which)->constant_pool_index();
pool_index = invoke_dynamic_name_and_type_ref_index_at(pool_index);
assert(tag_at(pool_index).is_name_and_type(), "");
@@ -672,10 +671,11 @@
int callee_index = this_cp->method_handle_klass_index_at(index);
Symbol* name = this_cp->method_handle_name_ref_at(index);
Symbol* signature = this_cp->method_handle_signature_ref_at(index);
- if (PrintMiscellaneous)
- tty->print_cr("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s",
- ref_kind, index, this_cp->method_handle_index_at(index),
- callee_index, name->as_C_string(), signature->as_C_string());
+ { ResourceMark rm(THREAD);
+ log_debug(classresolve)("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s",
+ ref_kind, index, this_cp->method_handle_index_at(index),
+ callee_index, name->as_C_string(), signature->as_C_string());
+ }
KlassHandle callee;
{ Klass* k = klass_at_impl(this_cp, callee_index, true, CHECK_NULL);
callee = KlassHandle(THREAD, k);
@@ -694,10 +694,11 @@
case JVM_CONSTANT_MethodType:
{
Symbol* signature = this_cp->method_type_signature_at(index);
- if (PrintMiscellaneous)
- tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s",
- index, this_cp->method_type_index_at(index),
- signature->as_C_string());
+ { ResourceMark rm(THREAD);
+ log_debug(classresolve)("resolve JVM_CONSTANT_MethodType [%d/%d] %s",
+ index, this_cp->method_type_index_at(index),
+ signature->as_C_string());
+ }
KlassHandle klass(THREAD, this_cp->pool_holder());
Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD);
result_oop = value();
@@ -964,8 +965,8 @@
case JVM_CONSTANT_MethodType:
{
- int k1 = method_type_index_at_error_ok(index1);
- int k2 = cp2->method_type_index_at_error_ok(index2);
+ int k1 = method_type_index_at(index1);
+ int k2 = cp2->method_type_index_at(index2);
bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
if (match) {
return true;
@@ -974,11 +975,11 @@
case JVM_CONSTANT_MethodHandle:
{
- int k1 = method_handle_ref_kind_at_error_ok(index1);
- int k2 = cp2->method_handle_ref_kind_at_error_ok(index2);
+ int k1 = method_handle_ref_kind_at(index1);
+ int k2 = cp2->method_handle_ref_kind_at(index2);
if (k1 == k2) {
- int i1 = method_handle_index_at_error_ok(index1);
- int i2 = cp2->method_handle_index_at_error_ok(index2);
+ int i1 = method_handle_index_at(index1);
+ int i2 = cp2->method_handle_index_at(index2);
bool match = compare_entry_to(i1, cp2, i2, CHECK_false);
if (match) {
return true;
@@ -1310,15 +1311,15 @@
case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_MethodTypeInError:
{
- jint k = from_cp->method_type_index_at_error_ok(from_i);
+ jint k = from_cp->method_type_index_at(from_i);
to_cp->method_type_index_at_put(to_i, k);
} break;
case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodHandleInError:
{
- int k1 = from_cp->method_handle_ref_kind_at_error_ok(from_i);
- int k2 = from_cp->method_handle_index_at_error_ok(from_i);
+ int k1 = from_cp->method_handle_ref_kind_at(from_i);
+ int k2 = from_cp->method_handle_index_at(from_i);
to_cp->method_handle_index_at_put(to_i, k1, k2);
} break;
@@ -1754,8 +1755,8 @@
case JVM_CONSTANT_MethodHandle:
case JVM_CONSTANT_MethodHandleInError: {
*bytes = JVM_CONSTANT_MethodHandle;
- int kind = method_handle_ref_kind_at_error_ok(idx);
- idx1 = method_handle_index_at_error_ok(idx);
+ int kind = method_handle_ref_kind_at(idx);
+ idx1 = method_handle_index_at(idx);
*(bytes+1) = (unsigned char) kind;
Bytes::put_Java_u2((address) (bytes+2), idx1);
DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1));
@@ -1764,7 +1765,7 @@
case JVM_CONSTANT_MethodType:
case JVM_CONSTANT_MethodTypeInError: {
*bytes = JVM_CONSTANT_MethodType;
- idx1 = method_type_index_at_error_ok(idx);
+ idx1 = method_type_index_at(idx);
Bytes::put_Java_u2((address) (bytes+1), idx1);
DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
break;
@@ -1952,12 +1953,12 @@
break;
case JVM_CONSTANT_MethodHandle :
case JVM_CONSTANT_MethodHandleInError :
- st->print("ref_kind=%d", method_handle_ref_kind_at_error_ok(index));
- st->print(" ref_index=%d", method_handle_index_at_error_ok(index));
+ st->print("ref_kind=%d", method_handle_ref_kind_at(index));
+ st->print(" ref_index=%d", method_handle_index_at(index));
break;
case JVM_CONSTANT_MethodType :
case JVM_CONSTANT_MethodTypeInError :
- st->print("signature_index=%d", method_type_index_at_error_ok(index));
+ st->print("signature_index=%d", method_type_index_at(index));
break;
case JVM_CONSTANT_InvokeDynamic :
{
--- a/hotspot/src/share/vm/oops/constantPool.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -460,41 +460,21 @@
return *int_at_addr(which);
}
- private:
- int method_handle_ref_kind_at(int which, bool error_ok) {
+ int method_handle_ref_kind_at(int which) {
assert(tag_at(which).is_method_handle() ||
- (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
+ tag_at(which).is_method_handle_in_error(), "Corrupted constant pool");
return extract_low_short_from_int(*int_at_addr(which)); // mask out unwanted ref_index bits
}
- int method_handle_index_at(int which, bool error_ok) {
+ int method_handle_index_at(int which) {
assert(tag_at(which).is_method_handle() ||
- (error_ok && tag_at(which).is_method_handle_in_error()), "Corrupted constant pool");
+ tag_at(which).is_method_handle_in_error(), "Corrupted constant pool");
return extract_high_short_from_int(*int_at_addr(which)); // shift out unwanted ref_kind bits
}
- int method_type_index_at(int which, bool error_ok) {
+ int method_type_index_at(int which) {
assert(tag_at(which).is_method_type() ||
- (error_ok && tag_at(which).is_method_type_in_error()), "Corrupted constant pool");
+ tag_at(which).is_method_type_in_error(), "Corrupted constant pool");
return *int_at_addr(which);
}
- public:
- int method_handle_ref_kind_at(int which) {
- return method_handle_ref_kind_at(which, false);
- }
- int method_handle_ref_kind_at_error_ok(int which) {
- return method_handle_ref_kind_at(which, true);
- }
- int method_handle_index_at(int which) {
- return method_handle_index_at(which, false);
- }
- int method_handle_index_at_error_ok(int which) {
- return method_handle_index_at(which, true);
- }
- int method_type_index_at(int which) {
- return method_type_index_at(which, false);
- }
- int method_type_index_at_error_ok(int which) {
- return method_type_index_at(which, true);
- }
// Derived queries:
Symbol* method_handle_name_ref_at(int which) {
--- a/hotspot/src/share/vm/oops/method.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -38,6 +38,7 @@
#include "interpreter/oopMapCache.hpp"
#include "memory/heapInspection.hpp"
#include "memory/metadataFactory.hpp"
+#include "memory/metaspaceShared.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/constMethod.hpp"
@@ -123,18 +124,18 @@
}
address Method::get_i2c_entry() {
- assert(_adapter != NULL, "must have");
- return _adapter->get_i2c_entry();
+ assert(adapter() != NULL, "must have");
+ return adapter()->get_i2c_entry();
}
address Method::get_c2i_entry() {
- assert(_adapter != NULL, "must have");
- return _adapter->get_c2i_entry();
+ assert(adapter() != NULL, "must have");
+ return adapter()->get_c2i_entry();
}
address Method::get_c2i_unverified_entry() {
- assert(_adapter != NULL, "must have");
- return _adapter->get_c2i_unverified_entry();
+ assert(adapter() != NULL, "must have");
+ return adapter()->get_c2i_unverified_entry();
}
char* Method::name_and_sig_as_C_string() const {
@@ -892,10 +893,10 @@
// this may be NULL if c2i adapters have not been made yet
// Only should happen at allocate time.
- if (_adapter == NULL) {
+ if (adapter() == NULL) {
_from_compiled_entry = NULL;
} else {
- _from_compiled_entry = _adapter->get_c2i_entry();
+ _from_compiled_entry = adapter()->get_c2i_entry();
}
OrderAccess::storestore();
_from_interpreted_entry = _i2i_entry;
@@ -903,47 +904,68 @@
_code = NULL;
}
+#if INCLUDE_CDS
// Called by class data sharing to remove any entry points (which are not shared)
void Method::unlink_method() {
_code = NULL;
- _i2i_entry = NULL;
- _from_interpreted_entry = NULL;
+
+ assert(DumpSharedSpaces, "dump time only");
+ // Set the values to what they should be at run time. Note that
+ // this Method can no longer be executed during dump time.
+ _i2i_entry = Interpreter::entry_for_cds_method(this);
+ _from_interpreted_entry = _i2i_entry;
+
if (is_native()) {
*native_function_addr() = NULL;
set_signature_handler(NULL);
}
NOT_PRODUCT(set_compiled_invocation_count(0);)
- _adapter = NULL;
- _from_compiled_entry = NULL;
+
+ CDSAdapterHandlerEntry* cds_adapter = (CDSAdapterHandlerEntry*)adapter();
+ constMethod()->set_adapter_trampoline(cds_adapter->get_adapter_trampoline());
+ _from_compiled_entry = cds_adapter->get_c2i_entry_trampoline();
+ assert(*((int*)_from_compiled_entry) == 0, "must be NULL during dump time, to be initialized at run time");
+
// In case of DumpSharedSpaces, _method_data should always be NULL.
- //
- // During runtime (!DumpSharedSpaces), when we are cleaning a
- // shared class that failed to load, this->link_method() may
- // have already been called (before an exception happened), so
- // this->_method_data may not be NULL.
- assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?");
+ assert(_method_data == NULL, "unexpected method data?");
set_method_data(NULL);
clear_method_counters();
}
+#endif
// Called when the method_holder is getting linked. Setup entrypoints so the method
// is ready to be called from interpreter, compiler, and vtables.
void Method::link_method(const methodHandle& h_method, TRAPS) {
// If the code cache is full, we may reenter this function for the
// leftover methods that weren't linked.
- if (_i2i_entry != NULL) return;
+ if (is_shared()) {
+ if (adapter() != NULL) return;
+ } else {
+ if (_i2i_entry != NULL) return;
- assert(_adapter == NULL, "init'd to NULL" );
+ assert(adapter() == NULL, "init'd to NULL" );
+ }
assert( _code == NULL, "nothing compiled yet" );
// Setup interpreter entrypoint
assert(this == h_method(), "wrong h_method()" );
- address entry = Interpreter::entry_for_method(h_method);
+ address entry;
+
+ if (this->is_shared()) {
+ entry = Interpreter::entry_for_cds_method(h_method);
+ } else {
+ entry = Interpreter::entry_for_method(h_method);
+ }
assert(entry != NULL, "interpreter entry must be non-null");
- // Sets both _i2i_entry and _from_interpreted_entry
- set_interpreter_entry(entry);
+ if (is_shared()) {
+ assert(entry == _i2i_entry && entry == _from_interpreted_entry,
+ "should be correctly set during dump time");
+ } else {
+ // Sets both _i2i_entry and _from_interpreted_entry
+ set_interpreter_entry(entry);
+ }
// Don't overwrite already registered native entries.
if (is_native() && !has_native_function()) {
@@ -975,8 +997,13 @@
THROW_MSG_NULL(vmSymbols::java_lang_VirtualMachineError(), "Out of space in CodeCache for adapters");
}
- mh->set_adapter_entry(adapter);
- mh->_from_compiled_entry = adapter->get_c2i_entry();
+ if (mh->is_shared()) {
+ assert(mh->adapter() == adapter, "must be");
+ assert(mh->_from_compiled_entry != NULL, "must be"); // FIXME, the instructions also not NULL
+ } else {
+ mh->set_adapter_entry(adapter);
+ mh->_from_compiled_entry = adapter->get_c2i_entry();
+ }
return adapter->get_c2i_entry();
}
@@ -992,6 +1019,14 @@
}
}
+volatile address Method::from_compiled_entry_no_trampoline() const {
+ nmethod *code = (nmethod *)OrderAccess::load_ptr_acquire(&_code);
+ if (code) {
+ return code->verified_entry_point();
+ } else {
+ return adapter()->get_c2i_entry();
+ }
+}
// The verified_code_entry() must be called when a invoke is resolved
// on this method.
--- a/hotspot/src/share/vm/oops/method.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/oops/method.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -93,8 +93,6 @@
#endif
// Entry point for calling both from and to the interpreter.
address _i2i_entry; // All-args-on-stack calling convention
- // Adapter blob (i2c/c2i) for this Method*. Set once when method is linked.
- AdapterHandlerEntry* _adapter;
// Entry point for calling from compiled code, to compiled code if it exists
// or else the interpreter.
volatile address _from_compiled_entry; // Cache of: _code ? _code->entry_point() : _adapter->c2i_entry()
@@ -137,6 +135,7 @@
static address make_adapters(methodHandle mh, TRAPS);
volatile address from_compiled_entry() const { return (address)OrderAccess::load_ptr_acquire(&_from_compiled_entry); }
+ volatile address from_compiled_entry_no_trampoline() const;
volatile address from_interpreted_entry() const{ return (address)OrderAccess::load_ptr_acquire(&_from_interpreted_entry); }
// access flag
@@ -435,15 +434,23 @@
nmethod* volatile code() const { assert( check_code(), "" ); return (nmethod *)OrderAccess::load_ptr_acquire(&_code); }
void clear_code(); // Clear out any compiled code
static void set_code(methodHandle mh, nmethod* code);
- void set_adapter_entry(AdapterHandlerEntry* adapter) { _adapter = adapter; }
+ void set_adapter_entry(AdapterHandlerEntry* adapter) {
+ constMethod()->set_adapter_entry(adapter);
+ }
+ void update_adapter_trampoline(AdapterHandlerEntry* adapter) {
+ constMethod()->update_adapter_trampoline(adapter);
+ }
+
address get_i2c_entry();
address get_c2i_entry();
address get_c2i_unverified_entry();
- AdapterHandlerEntry* adapter() { return _adapter; }
+ AdapterHandlerEntry* adapter() const {
+ return constMethod()->adapter();
+ }
// setup entry points
void link_method(const methodHandle& method, TRAPS);
- // clear entry points. Used by sharing code
- void unlink_method();
+ // clear entry points. Used by sharing code during dump time
+ void unlink_method() NOT_CDS_RETURN;
// vtable index
enum VtableIndexFlag {
@@ -469,7 +476,15 @@
// interpreter entry
address interpreter_entry() const { return _i2i_entry; }
// Only used when first initialize so we can set _i2i_entry and _from_interpreted_entry
- void set_interpreter_entry(address entry) { _i2i_entry = entry; _from_interpreted_entry = entry; }
+ void set_interpreter_entry(address entry) {
+ assert(!is_shared(), "shared method's interpreter entry should not be changed at run time");
+ if (_i2i_entry != entry) {
+ _i2i_entry = entry;
+ }
+ if (_from_interpreted_entry != entry) {
+ _from_interpreted_entry = entry;
+ }
+ }
// native function (used for native methods only)
enum {
--- a/hotspot/src/share/vm/oops/methodData.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/oops/methodData.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -1729,6 +1729,7 @@
}
void MethodData::clean_method_data(BoolObjectClosure* is_alive) {
+ ResourceMark rm;
for (ProfileData* data = first_data();
is_valid(data);
data = next_data(data)) {
@@ -1745,6 +1746,7 @@
}
void MethodData::clean_weak_method_links() {
+ ResourceMark rm;
for (ProfileData* data = first_data();
is_valid(data);
data = next_data(data)) {
@@ -1758,6 +1760,7 @@
#ifdef ASSERT
void MethodData::verify_clean_weak_method_links() {
+ ResourceMark rm;
for (ProfileData* data = first_data();
is_valid(data);
data = next_data(data)) {
--- a/hotspot/src/share/vm/oops/oop.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/oops/oop.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -30,7 +30,6 @@
#include "memory/memRegion.hpp"
#include "oops/metadata.hpp"
#include "utilities/macros.hpp"
-#include "utilities/top.hpp"
// oopDesc is the top baseclass for objects classes. The {name}Desc classes describe
// the format of Java objects so the fields can be accessed from C++.
--- a/hotspot/src/share/vm/oops/symbol.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/oops/symbol.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -25,9 +25,10 @@
#ifndef SHARE_VM_OOPS_SYMBOL_HPP
#define SHARE_VM_OOPS_SYMBOL_HPP
-#include "utilities/utf8.hpp"
#include "memory/allocation.hpp"
#include "runtime/atomic.hpp"
+#include "utilities/exceptions.hpp"
+#include "utilities/utf8.hpp"
// A Symbol is a canonicalized string.
// All Symbols reside in global SymbolTable and are reference counted.
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -242,7 +242,6 @@
# include "utilities/ostream.hpp"
# include "utilities/preserveException.hpp"
# include "utilities/sizes.hpp"
-# include "utilities/top.hpp"
# include "utilities/utf8.hpp"
#ifdef COMPILER2
# include "libadt/dict.hpp"
--- a/hotspot/src/share/vm/prims/jvm.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -79,7 +79,6 @@
#include "utilities/events.hpp"
#include "utilities/histogram.hpp"
#include "utilities/macros.hpp"
-#include "utilities/top.hpp"
#include "utilities/utf8.hpp"
#if INCLUDE_CDS
#include "classfile/sharedClassUtil.hpp"
@@ -534,7 +533,6 @@
JVM_ENTRY(jobject, JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
jint skip_frames, jint frame_count, jint start_index,
- jobjectArray classes,
jobjectArray frames))
JVMWrapper("JVM_CallStackWalk");
JavaThread* jt = (JavaThread*) THREAD;
@@ -543,78 +541,51 @@
}
Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream));
- objArrayOop ca = objArrayOop(JNIHandles::resolve_non_null(classes));
- objArrayHandle classes_array_h(THREAD, ca);
-
- // frames array is null when only getting caller reference
- objArrayOop fa = objArrayOop(JNIHandles::resolve(frames));
+
+ // frames array is a Class<?>[] array when only getting caller reference,
+ // and a StackFrameInfo[] array (or derivative) otherwise. It should never
+ // be null.
+ objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
objArrayHandle frames_array_h(THREAD, fa);
int limit = start_index + frame_count;
- if (classes_array_h->length() < limit) {
+ if (frames_array_h->length() < limit) {
THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "not enough space in buffers", NULL);
}
Handle result = StackWalk::walk(stackStream_h, mode, skip_frames, frame_count,
- start_index, classes_array_h,
- frames_array_h, CHECK_NULL);
+ start_index, frames_array_h, CHECK_NULL);
return JNIHandles::make_local(env, result());
JVM_END
JVM_ENTRY(jint, JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
jint frame_count, jint start_index,
- jobjectArray classes,
jobjectArray frames))
JVMWrapper("JVM_MoreStackWalk");
JavaThread* jt = (JavaThread*) THREAD;
- objArrayOop ca = objArrayOop(JNIHandles::resolve_non_null(classes));
- objArrayHandle classes_array_h(THREAD, ca);
-
- // frames array is null when only getting caller reference
- objArrayOop fa = objArrayOop(JNIHandles::resolve(frames));
+
+ // frames array is a Class<?>[] array when only getting caller reference,
+ // and a StackFrameInfo[] array (or derivative) otherwise. It should never
+ // be null.
+ objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
objArrayHandle frames_array_h(THREAD, fa);
int limit = start_index+frame_count;
- if (classes_array_h->length() < limit) {
+ if (frames_array_h->length() < limit) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "not enough space in buffers");
}
Handle stackStream_h(THREAD, JNIHandles::resolve_non_null(stackStream));
return StackWalk::moreFrames(stackStream_h, mode, anchor, frame_count,
- start_index, classes_array_h,
- frames_array_h, THREAD);
+ start_index, frames_array_h, THREAD);
JVM_END
-JVM_ENTRY(void, JVM_FillStackFrames(JNIEnv *env, jclass stackStream,
- jint start_index,
- jobjectArray frames,
- jint from_index, jint to_index))
- JVMWrapper("JVM_FillStackFrames");
- if (TraceStackWalk) {
- tty->print("JVM_FillStackFrames() start_index=%d from_index=%d to_index=%d\n",
- start_index, from_index, to_index);
- }
-
- JavaThread* jt = (JavaThread*) THREAD;
-
- objArrayOop fa = objArrayOop(JNIHandles::resolve_non_null(frames));
- objArrayHandle frames_array_h(THREAD, fa);
-
- if (frames_array_h->length() < to_index) {
- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "array length not matched");
- }
-
- for (int i = from_index; i < to_index; i++) {
- Handle stackFrame(THREAD, frames_array_h->obj_at(i));
- java_lang_StackFrameInfo::fill_methodInfo(stackFrame, CHECK);
- }
-JVM_END
-
-JVM_ENTRY(void, JVM_SetMethodInfo(JNIEnv *env, jobject frame))
- JVMWrapper("JVM_SetMethodInfo");
- Handle stackFrame(THREAD, JNIHandles::resolve(frame));
- java_lang_StackFrameInfo::fill_methodInfo(stackFrame, THREAD);
+JVM_ENTRY(void, JVM_ToStackTraceElement(JNIEnv *env, jobject frame, jobject stack))
+ JVMWrapper("JVM_ToStackTraceElement");
+ Handle stack_frame_info(THREAD, JNIHandles::resolve_non_null(frame));
+ Handle stack_trace_element(THREAD, JNIHandles::resolve_non_null(stack));
+ java_lang_StackFrameInfo::to_stack_trace_element(stack_frame_info, stack_trace_element, THREAD);
JVM_END
// java.lang.Object ///////////////////////////////////////////////
@@ -1818,9 +1789,6 @@
// Ensure class is linked
k->link_class(CHECK_NULL);
- // 4496456 We need to filter out java.lang.Throwable.backtrace
- bool skip_backtrace = false;
-
// Allocate result
int num_fields;
@@ -1831,11 +1799,6 @@
}
} else {
num_fields = k->java_fields_count();
-
- if (k() == SystemDictionary::Throwable_klass()) {
- num_fields--;
- skip_backtrace = true;
- }
}
objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), num_fields, CHECK_NULL);
@@ -1844,12 +1807,6 @@
int out_idx = 0;
fieldDescriptor fd;
for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
- if (skip_backtrace) {
- // 4496456 skip java.lang.Throwable.backtrace
- int offset = fs.offset();
- if (offset == java_lang_Throwable::get_backtrace_offset()) continue;
- }
-
if (!publicOnly || fs.access_flags().is_public()) {
fd.reinitialize(k(), fs.index());
oop field = Reflection::new_field(&fd, CHECK_NULL);
--- a/hotspot/src/share/vm/prims/jvm.h Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvm.h Thu Apr 14 19:55:39 2016 -0700
@@ -209,7 +209,6 @@
*/
enum {
JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x2,
- JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE = 0x10,
JVM_STACKWALK_SHOW_HIDDEN_FRAMES = 0x20,
JVM_STACKWALK_FILL_LIVE_STACK_FRAMES = 0x100
};
@@ -217,23 +216,15 @@
JNIEXPORT jobject JNICALL
JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
jint skip_frames, jint frame_count, jint start_index,
- jobjectArray classes,
jobjectArray frames);
JNIEXPORT jint JNICALL
JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode, jlong anchor,
jint frame_count, jint start_index,
- jobjectArray classes,
jobjectArray frames);
JNIEXPORT void JNICALL
-JVM_FillStackFrames(JNIEnv* env, jclass cls,
- jint start_index,
- jobjectArray frames,
- jint from_index, jint toIndex);
-
-JNIEXPORT void JNICALL
-JVM_SetMethodInfo(JNIEnv* env, jobject frame);
+JVM_ToStackTraceElement(JNIEnv* env, jobject frame, jobject stackElement);
/*
* java.lang.Thread
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -1443,8 +1443,9 @@
return JVMTI_ERROR_INTERNAL;
}
- // Update the version number of the constant pool
+ // Update the version number of the constant pools (may keep scratch_cp)
merge_cp->increment_and_save_version(old_cp->version());
+ scratch_cp->increment_and_save_version(old_cp->version());
ResourceMark rm(THREAD);
_index_map_count = 0;
@@ -3911,6 +3912,11 @@
method->set_constants(scratch_class->constants());
}
+ // NOTE: this doesn't work because you can redefine the same class in two
+ // threads, each getting their own constant pool data appended to the
+ // original constant pool. In order for the new methods to work when they
+ // become old methods, they need to keep their updated copy of the constant pool.
+
{
// walk all previous versions of the klass
InstanceKlass *ik = (InstanceKlass *)the_class();
--- a/hotspot/src/share/vm/prims/nativeLookup.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/prims/nativeLookup.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -25,8 +25,8 @@
#ifndef SHARE_VM_PRIMS_NATIVELOOKUP_HPP
#define SHARE_VM_PRIMS_NATIVELOOKUP_HPP
+#include "memory/allocation.hpp"
#include "runtime/handles.hpp"
-#include "utilities/top.hpp"
// NativeLookup provides an interface for finding DLL entry points for
// Java native functions.
--- a/hotspot/src/share/vm/prims/stackwalk.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/prims/stackwalk.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -37,22 +37,22 @@
#include "utilities/globalDefinitions.hpp"
// setup and cleanup actions
-void StackWalkAnchor::setup_magic_on_entry(objArrayHandle classes_array) {
- classes_array->obj_at_put(magic_pos, _thread->threadObj());
+void StackWalkAnchor::setup_magic_on_entry(objArrayHandle frames_array) {
+ frames_array->obj_at_put(magic_pos, _thread->threadObj());
_anchor = address_value();
- assert(check_magic(classes_array), "invalid magic");
+ assert(check_magic(frames_array), "invalid magic");
}
-bool StackWalkAnchor::check_magic(objArrayHandle classes_array) {
- oop m1 = classes_array->obj_at(magic_pos);
+bool StackWalkAnchor::check_magic(objArrayHandle frames_array) {
+ oop m1 = frames_array->obj_at(magic_pos);
jlong m2 = _anchor;
if (m1 == _thread->threadObj() && m2 == address_value()) return true;
return false;
}
-bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle classes_array) {
- bool ok = check_magic(classes_array);
- classes_array->obj_at_put(magic_pos, NULL);
+bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle frames_array) {
+ bool ok = check_magic(frames_array);
+ frames_array->obj_at_put(magic_pos, NULL);
_anchor = 0L;
return ok;
}
@@ -62,18 +62,18 @@
// Parameters:
// thread Current Java thread.
// magic Magic value used for each stack walking
-// classes_array User-supplied buffers. The 0th element is reserved
+// frames_array User-supplied buffers. The 0th element is reserved
// to this StackWalkAnchor to use
//
StackWalkAnchor* StackWalkAnchor::from_current(JavaThread* thread, jlong magic,
- objArrayHandle classes_array)
+ objArrayHandle frames_array)
{
assert(thread != NULL && thread->is_Java_thread(), "");
- oop m1 = classes_array->obj_at(magic_pos);
+ oop m1 = frames_array->obj_at(magic_pos);
if (m1 != thread->threadObj()) return NULL;
if (magic == 0L) return NULL;
StackWalkAnchor* anchor = (StackWalkAnchor*) (intptr_t) magic;
- if (!anchor->is_valid_in(thread, classes_array)) return NULL;
+ if (!anchor->is_valid_in(thread, frames_array)) return NULL;
return anchor;
}
@@ -88,24 +88,24 @@
// vfst vFrameStream.
// max_nframes Maximum number of frames to be filled.
// start_index Start index to the user-supplied buffers.
-// classes_array Buffer to store classes in, starting at start_index.
-// frames_array Buffer to store StackFrame in, starting at start_index.
-// NULL if not used.
+// frames_array Buffer to store Class or StackFrame in, starting at start_index.
+// frames array is a Class<?>[] array when only getting caller
+// reference, and a StackFrameInfo[] array (or derivative)
+// otherwise. It should never be null.
// end_index End index to the user-supplied buffers with unpacked frames.
//
// Returns the number of frames whose information was transferred into the buffers.
//
int StackWalk::fill_in_frames(jlong mode, vframeStream& vfst,
int max_nframes, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
int& end_index, TRAPS) {
if (TraceStackWalk) {
tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d",
- max_nframes, start_index, classes_array->length());
+ max_nframes, start_index, frames_array->length());
}
assert(max_nframes > 0, "invalid max_nframes");
- assert(start_index + max_nframes <= classes_array->length(), "oob");
+ assert(start_index + max_nframes <= frames_array->length(), "oob");
int frames_decoded = 0;
for (; !vfst.at_end(); vfst.next()) {
@@ -129,14 +129,18 @@
tty->print_cr(" bci=%d", bci);
}
- classes_array->obj_at_put(index, method->method_holder()->java_mirror());
// fill in StackFrameInfo and initialize MemberName
if (live_frame_info(mode)) {
+ assert (use_frames_array(mode), "Bad mode for get live frame");
Handle stackFrame(frames_array->obj_at(index));
fill_live_stackframe(stackFrame, method, bci, vfst.java_frame(), CHECK_0);
} else if (need_method_info(mode)) {
+ assert (use_frames_array(mode), "Bad mode for get stack frame");
Handle stackFrame(frames_array->obj_at(index));
fill_stackframe(stackFrame, method, bci);
+ } else {
+ assert (use_frames_array(mode) == false, "Bad mode for get caller class");
+ frames_array->obj_at_put(index, method->method_holder()->java_mirror());
}
if (++frames_decoded >= max_nframes) break;
}
@@ -279,15 +283,15 @@
// skip_frames Number of frames to be skipped.
// frame_count Number of frames to be traversed.
// start_index Start index to the user-supplied buffers.
-// classes_array Buffer to store classes in, starting at start_index.
// frames_array Buffer to store StackFrame in, starting at start_index.
-// NULL if not used.
+// frames array is a Class<?>[] array when only getting caller
+// reference, and a StackFrameInfo[] array (or derivative)
+// otherwise. It should never be null.
//
// Returns Object returned from AbstractStackWalker::doStackWalk call.
//
oop StackWalk::walk(Handle stackStream, jlong mode,
int skip_frames, int frame_count, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
TRAPS) {
JavaThread* jt = (JavaThread*)THREAD;
@@ -296,10 +300,8 @@
mode, skip_frames, frame_count);
}
- if (need_method_info(mode)) {
- if (frames_array.is_null()) {
- THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
- }
+ if (frames_array.is_null()) {
+ THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
}
Klass* stackWalker_klass = SystemDictionary::StackWalker_klass();
@@ -313,48 +315,17 @@
vframeStream& vfst = anchor.vframe_stream();
{
- // Skip all methods from AbstractStackWalker and StackWalk (enclosing method)
- if (!fill_in_stacktrace(mode)) {
- while (!vfst.at_end()) {
- InstanceKlass* ik = vfst.method()->method_holder();
- if (ik != stackWalker_klass &&
- ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass) {
- break;
- }
-
- if (TraceStackWalk) {
- tty->print(" skip "); vfst.method()->print_short_name(); tty->print("\n");
- }
- vfst.next();
+ while (!vfst.at_end()) {
+ InstanceKlass* ik = vfst.method()->method_holder();
+ if (ik != stackWalker_klass &&
+ ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass) {
+ break;
}
- }
- // For exceptions, skip Throwable::fillInStackTrace and <init> methods
- // of the exception class and superclasses
- if (fill_in_stacktrace(mode)) {
- bool skip_to_fillInStackTrace = false;
- bool skip_throwableInit_check = false;
- while (!vfst.at_end() && !skip_throwableInit_check) {
- InstanceKlass* ik = vfst.method()->method_holder();
- Method* method = vfst.method();
- if (!skip_to_fillInStackTrace) {
- if (ik == SystemDictionary::Throwable_klass() &&
- method->name() == vmSymbols::fillInStackTrace_name()) {
- // this frame will be skipped
- skip_to_fillInStackTrace = true;
- }
- } else if (!(ik->is_subclass_of(SystemDictionary::Throwable_klass()) &&
- method->name() == vmSymbols::object_initializer_name())) {
- // there are none or we've seen them all - either way stop checking
- skip_throwableInit_check = true;
- break;
- }
-
- if (TraceStackWalk) {
- tty->print("stack walk: skip "); vfst.method()->print_short_name(); tty->print("\n");
- }
- vfst.next();
+ if (TraceStackWalk) {
+ tty->print(" skip "); vfst.method()->print_short_name(); tty->print("\n");
}
+ vfst.next();
}
// stack frame has been traversed individually and resume stack walk
@@ -372,7 +343,7 @@
int end_index = start_index;
int numFrames = 0;
if (!vfst.at_end()) {
- numFrames = fill_in_frames(mode, vfst, frame_count, start_index, classes_array,
+ numFrames = fill_in_frames(mode, vfst, frame_count, start_index,
frames_array, end_index, CHECK_NULL);
if (numFrames < 1) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "stack walk: decode failed", NULL);
@@ -392,12 +363,12 @@
args.push_int(end_index);
// Link the thread and vframe stream into the callee-visible object
- anchor.setup_magic_on_entry(classes_array);
+ anchor.setup_magic_on_entry(frames_array);
JavaCalls::call(&result, m_doStackWalk, &args, THREAD);
// Do this before anything else happens, to disable any lingering stream objects
- bool ok = anchor.cleanup_magic_on_exit(classes_array);
+ bool ok = anchor.cleanup_magic_on_exit(frames_array);
// Throw pending exception if we must
(void) (CHECK_NULL);
@@ -419,31 +390,28 @@
// magic Must be valid value to continue the stack walk
// frame_count Number of frames to be decoded.
// start_index Start index to the user-supplied buffers.
-// classes_array Buffer to store classes in, starting at start_index.
// frames_array Buffer to store StackFrame in, starting at start_index.
-// NULL if not used.
//
// Returns the end index of frame filled in the buffer.
//
jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic,
int frame_count, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
TRAPS)
{
JavaThread* jt = (JavaThread*)THREAD;
- StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, classes_array);
+ StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, frames_array);
if (existing_anchor == NULL) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
}
- if ((need_method_info(mode) || live_frame_info(mode)) && frames_array.is_null()) {
+ if (frames_array.is_null()) {
THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L);
}
if (TraceStackWalk) {
tty->print_cr("StackWalk::moreFrames frame_count %d existing_anchor " PTR_FORMAT " start %d frames %d",
- frame_count, p2i(existing_anchor), start_index, classes_array->length());
+ frame_count, p2i(existing_anchor), start_index, frames_array->length());
}
int end_index = start_index;
if (frame_count <= 0) {
@@ -451,14 +419,14 @@
}
int count = frame_count + start_index;
- assert (classes_array->length() >= count, "not enough space in buffers");
+ assert (frames_array->length() >= count, "not enough space in buffers");
StackWalkAnchor& anchor = (*existing_anchor);
vframeStream& vfst = anchor.vframe_stream();
if (!vfst.at_end()) {
vfst.next(); // this was the last frame decoded in the previous batch
if (!vfst.at_end()) {
- int n = fill_in_frames(mode, vfst, frame_count, start_index, classes_array,
+ int n = fill_in_frames(mode, vfst, frame_count, start_index,
frames_array, end_index, CHECK_0);
if (n < 1) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
--- a/hotspot/src/share/vm/prims/stackwalk.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/prims/stackwalk.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -45,12 +45,12 @@
vframeStream& vframe_stream() { return _vfst; }
JavaThread* thread() { return _thread; }
- void setup_magic_on_entry(objArrayHandle classes_array);
- bool check_magic(objArrayHandle classes_array);
- bool cleanup_magic_on_exit(objArrayHandle classes_array);
+ void setup_magic_on_entry(objArrayHandle frames_array);
+ bool check_magic(objArrayHandle frames_array);
+ bool cleanup_magic_on_exit(objArrayHandle frames_array);
- bool is_valid_in(Thread* thread, objArrayHandle classes_array) {
- return (_thread == thread && check_magic(classes_array));
+ bool is_valid_in(Thread* thread, objArrayHandle frames_array) {
+ return (_thread == thread && check_magic(frames_array));
}
jlong address_value() {
@@ -64,7 +64,6 @@
private:
static int fill_in_frames(jlong mode, vframeStream& vfst,
int max_nframes, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
int& end_index, TRAPS);
@@ -82,20 +81,18 @@
static inline bool live_frame_info(int mode) {
return (mode & JVM_STACKWALK_FILL_LIVE_STACK_FRAMES) != 0;
}
- static inline bool fill_in_stacktrace(int mode) {
- return (mode & JVM_STACKWALK_FILTER_FILL_IN_STACK_TRACE) != 0;
- }
public:
+ static inline bool use_frames_array(int mode) {
+ return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0;
+ }
static oop walk(Handle stackStream, jlong mode,
int skip_frames, int frame_count, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
TRAPS);
static jint moreFrames(Handle stackStream, jlong mode, jlong magic,
int frame_count, int start_index,
- objArrayHandle classes_array,
objArrayHandle frames_array,
TRAPS);
};
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -407,7 +407,9 @@
{ NULL, NULL}
};
+// NOTE: A compatibility request will be necessary for each alias to be removed.
static AliasedLoggingFlag const aliased_logging_flags[] = {
+ { "PrintCompressedOopsMode", LogLevel::Info, true, LOG_TAGS(gc, heap, coops) },
{ "TraceBiasedLocking", LogLevel::Info, true, LOG_TAGS(biasedlocking) },
{ "TraceClassLoading", LogLevel::Info, true, LOG_TAGS(classload) },
{ "TraceClassLoadingPreorder", LogLevel::Debug, true, LOG_TAGS(classload, preorder) },
@@ -2184,15 +2186,11 @@
if (!FLAG_IS_DEFAULT(HeapBaseMinAddress)) {
if (HeapBaseMinAddress < DefaultHeapBaseMinAddress) {
// matches compressed oops printing flags
- if (PrintCompressedOopsMode || (PrintMiscellaneous && Verbose)) {
- jio_fprintf(defaultStream::error_stream(),
- "HeapBaseMinAddress must be at least " SIZE_FORMAT
- " (" SIZE_FORMAT "G) which is greater than value given "
- SIZE_FORMAT "\n",
- DefaultHeapBaseMinAddress,
- DefaultHeapBaseMinAddress/G,
- HeapBaseMinAddress);
- }
+ log_debug(gc, heap, coops)("HeapBaseMinAddress must be at least " SIZE_FORMAT
+ " (" SIZE_FORMAT "G) which is greater than value given " SIZE_FORMAT,
+ DefaultHeapBaseMinAddress,
+ DefaultHeapBaseMinAddress/G,
+ HeapBaseMinAddress);
FLAG_SET_ERGO(size_t, HeapBaseMinAddress, DefaultHeapBaseMinAddress);
}
}
--- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -31,7 +31,6 @@
#include "runtime/os.hpp"
#include "runtime/perfData.hpp"
#include "utilities/debug.hpp"
-#include "utilities/top.hpp"
// Arguments parses the command line and recognizes options
--- a/hotspot/src/share/vm/runtime/basicLock.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/basicLock.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -27,7 +27,6 @@
#include "oops/markOop.hpp"
#include "runtime/handles.hpp"
-#include "utilities/top.hpp"
class BasicLock VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -457,6 +457,51 @@
}
}
+static Flag::Error CMSReservedAreaConstraintFunc(const char* name, size_t value, bool verbose) {
+#if INCLUDE_ALL_GCS
+ if (UseConcMarkSweepGC) {
+ ConcurrentMarkSweepGeneration* cms = (ConcurrentMarkSweepGeneration*)GenCollectedHeap::heap()->old_gen();
+ const size_t ergo_max = cms->cmsSpace()->max_flag_size_for_task_size();
+ if (value > ergo_max) {
+ CommandLineError::print(verbose,
+ "%s (" SIZE_FORMAT ") must be "
+ "less than or equal to ergonomic maximum (" SIZE_FORMAT ") "
+ "which is based on the maximum size of the old generation of the Java heap\n",
+ name, value, ergo_max);
+ return Flag::VIOLATES_CONSTRAINT;
+ }
+ }
+#endif
+
+ return Flag::SUCCESS;
+}
+
+Flag::Error CMSRescanMultipleConstraintFunc(size_t value, bool verbose) {
+ Flag::Error status = CMSReservedAreaConstraintFunc("CMSRescanMultiple", value, verbose);
+
+#if INCLUDE_ALL_GCS
+ if (status == Flag::SUCCESS && UseConcMarkSweepGC) {
+ // CMSParRemarkTask::do_dirty_card_rescan_tasks requires CompactibleFreeListSpace::rescan_task_size()
+ // to be aligned to CardTableModRefBS::card_size * BitsPerWord.
+ // Note that rescan_task_size() will be aligned if CMSRescanMultiple is a multiple of 'HeapWordSize'
+ // because rescan_task_size() is CardTableModRefBS::card_size / HeapWordSize * BitsPerWord.
+ if (value % HeapWordSize != 0) {
+ CommandLineError::print(verbose,
+ "CMSRescanMultiple (" SIZE_FORMAT ") must be "
+ "a multiple of " SIZE_FORMAT "\n",
+ value, HeapWordSize);
+ status = Flag::VIOLATES_CONSTRAINT;
+ }
+ }
+#endif
+
+ return status;
+}
+
+Flag::Error CMSConcMarkMultipleConstraintFunc(size_t value, bool verbose) {
+ return CMSReservedAreaConstraintFunc("CMSConcMarkMultiple", value, verbose);
+}
+
Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose) {
#if INCLUDE_ALL_GCS
if (UseConcMarkSweepGC && (value <= CMSPrecleanNumerator)) {
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -60,6 +60,8 @@
Flag::Error CMSOldPLABMinConstraintFunc(size_t value, bool verbose);
Flag::Error CMSOldPLABMaxConstraintFunc(size_t value, bool verbose);
Flag::Error MarkStackSizeConstraintFunc(size_t value, bool verbose);
+Flag::Error CMSRescanMultipleConstraintFunc(size_t value, bool verbose);
+Flag::Error CMSConcMarkMultipleConstraintFunc(size_t value, bool verbose);
Flag::Error CMSPrecleanDenominatorConstraintFunc(uintx value, bool verbose);
Flag::Error CMSPrecleanNumeratorConstraintFunc(uintx value, bool verbose);
Flag::Error CMSSamplingGrainConstraintFunc(uintx value, bool verbose);
--- a/hotspot/src/share/vm/runtime/frame.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/frame.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -29,7 +29,6 @@
#include "runtime/basicLock.hpp"
#include "runtime/monitorChunk.hpp"
#include "runtime/registerMap.hpp"
-#include "utilities/top.hpp"
#ifdef TARGET_ARCH_zero
# include "stack_zero.hpp"
#endif
--- a/hotspot/src/share/vm/runtime/globals.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -35,7 +35,6 @@
#include "trace/tracing.hpp"
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
-#include "utilities/top.hpp"
#if INCLUDE_ALL_GCS
#include "gc/g1/g1_globals.hpp"
#endif // INCLUDE_ALL_GCS
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -641,9 +641,6 @@
"region.") \
range(1, max_uintx) \
\
- diagnostic(bool, PrintCompressedOopsMode, false, \
- "Print compressed oops base address and encoding mode") \
- \
lp64_product(intx, ObjectAlignmentInBytes, 8, \
"Default object alignment in bytes, 8 is minimum") \
range(8, 256) \
@@ -688,9 +685,6 @@
"Use large page memory in metaspace. " \
"Only used if UseLargePages is enabled.") \
\
- develop(bool, TracePageSizes, false, \
- "Trace page size selection and usage") \
- \
product(bool, UseNUMA, false, \
"Use NUMA if available") \
\
@@ -1809,13 +1803,17 @@
"enough work per iteration") \
range(0, max_intx) \
\
+ /* 4096 = CardTableModRefBS::card_size_in_words * BitsPerWord */ \
product(size_t, CMSRescanMultiple, 32, \
"Size (in cards) of CMS parallel rescan task") \
- range(1, max_uintx) \
- \
+ range(1, SIZE_MAX / 4096) \
+ constraint(CMSRescanMultipleConstraintFunc,AfterMemoryInit) \
+ \
+ /* 4096 = CardTableModRefBS::card_size_in_words * BitsPerWord */ \
product(size_t, CMSConcMarkMultiple, 32, \
"Size (in cards) of CMS concurrent MT marking task") \
- range(1, max_uintx) \
+ range(1, SIZE_MAX / 4096) \
+ constraint(CMSConcMarkMultipleConstraintFunc,AfterMemoryInit) \
\
product(bool, CMSAbortSemantics, false, \
"Whether abort-on-overflow semantics is implemented") \
@@ -2954,9 +2952,6 @@
develop(bool, TraceStackWalk, false, \
"Trace stack walking") \
\
- product(bool, MemberNameInStackFrame, true, \
- "Use MemberName in StackFrame") \
- \
/* notice: the max range value here is max_jint, not max_intx */ \
/* because of overflow issue */ \
NOT_EMBEDDED(diagnostic(intx, GuaranteedSafepointInterval, 1000, \
--- a/hotspot/src/share/vm/runtime/globals_extension.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -27,7 +27,19 @@
#include "runtime/globals.hpp"
#include "utilities/macros.hpp"
-#include "utilities/top.hpp"
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc/g1/g1_globals.hpp"
+#endif
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci_globals.hpp"
+#endif
+#ifdef COMPILER1
+#include "c1/c1_globals.hpp"
+#endif
+#ifdef COMPILER2
+#include "opto/c2_globals.hpp"
+#endif
// Construct enum of Flag_<cmdline-arg> constants.
--- a/hotspot/src/share/vm/runtime/init.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/init.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -25,7 +25,7 @@
#ifndef SHARE_VM_RUNTIME_INIT_HPP
#define SHARE_VM_RUNTIME_INIT_HPP
-#include "utilities/top.hpp"
+#include "utilities/globalDefinitions.hpp"
// init_globals replaces C++ global objects so we can use the standard linker
// to link Delta (which is at least twice as fast as using the GNU C++ linker).
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -35,7 +35,6 @@
#include "runtime/vmThread.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/preserveException.hpp"
-#include "utilities/top.hpp"
// Wrapper for all entry points to the virtual machine.
// The HandleMarkCleaner is a faster version of HandleMark.
--- a/hotspot/src/share/vm/runtime/javaCalls.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/javaCalls.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -29,7 +29,7 @@
#include "oops/method.hpp"
#include "runtime/handles.hpp"
#include "runtime/javaFrameAnchor.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
#include "runtime/vmThread.hpp"
#ifdef TARGET_ARCH_x86
# include "jniTypes_x86.hpp"
--- a/hotspot/src/share/vm/runtime/jniHandles.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/jniHandles.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -25,8 +25,8 @@
#ifndef SHARE_VM_RUNTIME_JNIHANDLES_HPP
#define SHARE_VM_RUNTIME_JNIHANDLES_HPP
+#include "memory/allocation.hpp"
#include "runtime/handles.hpp"
-#include "utilities/top.hpp"
class JNIHandleBlock;
--- a/hotspot/src/share/vm/runtime/os.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -33,6 +33,7 @@
#include "gc/shared/vmGCOperations.hpp"
#include "interpreter/interpreter.hpp"
#include "logging/log.hpp"
+#include "logging/logStream.inline.hpp"
#include "memory/allocation.inline.hpp"
#ifdef ASSERT
#include "memory/guardedMemory.hpp"
@@ -1494,31 +1495,63 @@
return errno_to_string(e, true);
}
-#ifndef PRODUCT
-void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count)
-{
- if (TracePageSizes) {
- tty->print("%s: ", str);
+void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count) {
+ LogTarget(Info, pagesize) log;
+ if (log.is_enabled()) {
+ LogStreamCHeap out(log);
+
+ out.print("%s: ", str);
for (int i = 0; i < count; ++i) {
- tty->print(" " SIZE_FORMAT, page_sizes[i]);
+ out.print(" " SIZE_FORMAT, page_sizes[i]);
}
- tty->cr();
+ out.cr();
}
}
-void os::trace_page_sizes(const char* str, const size_t region_min_size,
- const size_t region_max_size, const size_t page_size,
- const char* base, const size_t size)
-{
- if (TracePageSizes) {
- tty->print_cr("%s: min=" SIZE_FORMAT " max=" SIZE_FORMAT
- " pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT
- " size=" SIZE_FORMAT,
- str, region_min_size, region_max_size,
- page_size, p2i(base), size);
- }
+#define trace_page_size_params(size) byte_size_in_exact_unit(size), exact_unit_for_byte_size(size)
+
+void os::trace_page_sizes(const char* str,
+ const size_t region_min_size,
+ const size_t region_max_size,
+ const size_t page_size,
+ const char* base,
+ const size_t size) {
+
+ log_info(pagesize)("%s: "
+ " min=" SIZE_FORMAT "%s"
+ " max=" SIZE_FORMAT "%s"
+ " base=" PTR_FORMAT
+ " page_size=" SIZE_FORMAT "%s"
+ " size=" SIZE_FORMAT "%s",
+ str,
+ trace_page_size_params(region_min_size),
+ trace_page_size_params(region_max_size),
+ p2i(base),
+ trace_page_size_params(page_size),
+ trace_page_size_params(size));
}
-#endif // #ifndef PRODUCT
+
+void os::trace_page_sizes_for_requested_size(const char* str,
+ const size_t requested_size,
+ const size_t page_size,
+ const size_t alignment,
+ const char* base,
+ const size_t size) {
+
+ log_info(pagesize)("%s:"
+ " req_size=" SIZE_FORMAT "%s"
+ " base=" PTR_FORMAT
+ " page_size=" SIZE_FORMAT "%s"
+ " alignment=" SIZE_FORMAT "%s"
+ " size=" SIZE_FORMAT "%s",
+ str,
+ trace_page_size_params(requested_size),
+ p2i(base),
+ trace_page_size_params(page_size),
+ trace_page_size_params(alignment),
+ trace_page_size_params(size));
+}
+
// This is the working definition of a server class machine:
// >= 2 physical CPU's and >=2GB of memory, with some fuzz
--- a/hotspot/src/share/vm/runtime/os.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/os.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -28,7 +28,6 @@
#include "jvmtifiles/jvmti.h"
#include "runtime/extendedPC.hpp"
#include "runtime/handles.hpp"
-#include "utilities/top.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "jvm_linux.h"
# include <setjmp.h>
@@ -286,18 +285,24 @@
return _page_sizes[0];
}
- // Methods for tracing page sizes returned by the above method; enabled by
- // TracePageSizes. The region_{min,max}_size parameters should be the values
+ // Methods for tracing page sizes returned by the above method.
+ // The region_{min,max}_size parameters should be the values
// passed to page_size_for_region() and page_size should be the result of that
// call. The (optional) base and size parameters should come from the
// ReservedSpace base() and size() methods.
- static void trace_page_sizes(const char* str, const size_t* page_sizes,
- int count) PRODUCT_RETURN;
- static void trace_page_sizes(const char* str, const size_t region_min_size,
+ static void trace_page_sizes(const char* str, const size_t* page_sizes, int count);
+ static void trace_page_sizes(const char* str,
+ const size_t region_min_size,
const size_t region_max_size,
const size_t page_size,
- const char* base = NULL,
- const size_t size = 0) PRODUCT_RETURN;
+ const char* base,
+ const size_t size);
+ static void trace_page_sizes_for_requested_size(const char* str,
+ const size_t requested_size,
+ const size_t page_size,
+ const size_t alignment,
+ const char* base,
+ const size_t size);
static int vm_allocation_granularity();
static char* reserve_memory(size_t bytes, char* addr = 0,
@@ -515,6 +520,9 @@
static int ftruncate(int fd, jlong length);
static int fsync(int fd);
static int available(int fd, jlong *bytes);
+ static int fileno(FILE* fp);
+
+ static int compare_file_modified_times(const char* file1, const char* file2);
//File i/o operations
--- a/hotspot/src/share/vm/runtime/osThread.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/osThread.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -29,7 +29,6 @@
#include "runtime/handles.hpp"
#include "runtime/javaFrameAnchor.hpp"
#include "runtime/objectMonitor.hpp"
-#include "utilities/top.hpp"
// The OSThread class holds OS-specific thread information. It is equivalent
// to the sys_thread_t structure of the classic JVM implementation.
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -38,6 +38,7 @@
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "logging/log.hpp"
+#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/klass.hpp"
@@ -1788,7 +1789,7 @@
IRT_LEAF(void, SharedRuntime::fixup_callers_callsite(Method* method, address caller_pc))
Method* moop(method);
- address entry_point = moop->from_compiled_entry();
+ address entry_point = moop->from_compiled_entry_no_trampoline();
// It's possible that deoptimization can occur at a call site which hasn't
// been resolved yet, in which case this function will be called from
@@ -2351,12 +2352,15 @@
public:
AdapterHandlerTable()
- : BasicHashtable<mtCode>(293, sizeof(AdapterHandlerEntry)) { }
+ : BasicHashtable<mtCode>(293, (DumpSharedSpaces ? sizeof(CDSAdapterHandlerEntry) : sizeof(AdapterHandlerEntry))) { }
// Create a new entry suitable for insertion in the table
AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry) {
AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable<mtCode>::new_entry(fingerprint->compute_hash());
entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
+ if (DumpSharedSpaces) {
+ ((CDSAdapterHandlerEntry*)entry)->init();
+ }
return entry;
}
@@ -2519,6 +2523,28 @@
}
AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) {
+ AdapterHandlerEntry* entry = get_adapter0(method);
+ if (method->is_shared()) {
+ MutexLocker mu(AdapterHandlerLibrary_lock);
+ if (method->adapter() == NULL) {
+ method->update_adapter_trampoline(entry);
+ }
+ address trampoline = method->from_compiled_entry();
+ if (*(int*)trampoline == 0) {
+ CodeBuffer buffer(trampoline, (int)SharedRuntime::trampoline_size());
+ MacroAssembler _masm(&buffer);
+ SharedRuntime::generate_trampoline(&_masm, entry->get_c2i_entry());
+
+ if (PrintInterpreter) {
+ Disassembler::decode(buffer.insts_begin(), buffer.insts_end());
+ }
+ }
+ }
+
+ return entry;
+}
+
+AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter0(const methodHandle& method) {
// Use customized signature handler. Need to lock around updates to
// the AdapterHandlerTable (it is not safe for concurrent readers
// and a single writer: this could be fixed if it becomes a
@@ -2535,7 +2561,9 @@
// make sure data structure is initialized
initialize();
- if (CodeCacheExtensions::skip_compiler_support()) {
+ // during dump time, always generate adapters, even if the
+ // compiler has been turned off.
+ if (!DumpSharedSpaces && CodeCacheExtensions::skip_compiler_support()) {
// adapters are useless and should not be used, including the
// abstract_method_handler. However, some callers check that
// an adapter was installed.
@@ -3017,6 +3045,17 @@
}
+#if INCLUDE_CDS
+
+void CDSAdapterHandlerEntry::init() {
+ assert(DumpSharedSpaces, "used during dump time only");
+ _c2i_entry_trampoline = (address)MetaspaceShared::misc_data_space_alloc(SharedRuntime::trampoline_size());
+ _adapter_trampoline = (AdapterHandlerEntry**)MetaspaceShared::misc_data_space_alloc(sizeof(AdapterHandlerEntry*));
+};
+
+#endif // INCLUDE_CDS
+
+
#ifndef PRODUCT
void AdapterHandlerLibrary::print_statistics() {
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -398,6 +398,10 @@
static void convert_ints_to_longints(int i2l_argcnt, int& in_args_count,
BasicType*& in_sig_bt, VMRegPair*& in_regs);
+ static size_t trampoline_size();
+
+ static void generate_trampoline(MacroAssembler *masm, address destination);
+
// Generate I2C and C2I adapters. These adapters are simple argument marshalling
// blobs. Unlike adapters in the tiger and earlier releases the code in these
// blobs does not create a new frame and are therefore virtually invisible
@@ -680,6 +684,17 @@
void print_adapter_on(outputStream* st) const;
};
+class CDSAdapterHandlerEntry: public AdapterHandlerEntry {
+ address _c2i_entry_trampoline; // allocated from shared spaces "MC" region
+ AdapterHandlerEntry** _adapter_trampoline; // allocated from shared spaces "MD" region
+
+public:
+ address get_c2i_entry_trampoline() const { return _c2i_entry_trampoline; }
+ AdapterHandlerEntry** get_adapter_trampoline() const { return _adapter_trampoline; }
+ void init() NOT_CDS_RETURN;
+};
+
+
class AdapterHandlerLibrary: public AllStatic {
private:
static BufferBlob* _buffer; // the temporary code buffer in CodeCache
@@ -687,6 +702,7 @@
static AdapterHandlerEntry* _abstract_method_handler;
static BufferBlob* buffer_blob();
static void initialize();
+ static AdapterHandlerEntry* get_adapter0(const methodHandle& method);
public:
--- a/hotspot/src/share/vm/runtime/signature.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/signature.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -27,7 +27,6 @@
#include "memory/allocation.hpp"
#include "oops/method.hpp"
-#include "utilities/top.hpp"
// SignatureIterators iterate over a Java signature (or parts of it).
// (Syntax according to: "The Java Virtual Machine Specification" by
--- a/hotspot/src/share/vm/runtime/stackValue.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/stackValue.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -27,7 +27,6 @@
#include "code/location.hpp"
#include "runtime/handles.hpp"
-#include "utilities/top.hpp"
class StackValue : public ResourceObj {
private:
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -30,7 +30,6 @@
#include "runtime/frame.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/stubCodeGenerator.hpp"
-#include "utilities/top.hpp"
// StubRoutines provides entry points to assembly routines used by
// compiled code and the run-time system. Platform-specific entry
--- a/hotspot/src/share/vm/runtime/synchronizer.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/synchronizer.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -29,8 +29,6 @@
#include "runtime/basicLock.hpp"
#include "runtime/handles.hpp"
#include "runtime/perfData.hpp"
-#include "utilities/top.hpp"
-
class ObjectMonitor;
--- a/hotspot/src/share/vm/runtime/task.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/task.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -25,7 +25,8 @@
#ifndef SHARE_VM_RUNTIME_TASK_HPP
#define SHARE_VM_RUNTIME_TASK_HPP
-#include "utilities/top.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/timer.hpp"
// A PeriodicTask has the sole purpose of executing its task
// function with regular intervals.
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -818,13 +818,17 @@
// Thread::print_on_error() is called by fatal error handler. Don't use
// any lock or allocate memory.
void Thread::print_on_error(outputStream* st, char* buf, int buflen) const {
- if (is_VM_thread()) st->print("VMThread");
- else if (is_Compiler_thread()) st->print("CompilerThread");
- else if (is_Java_thread()) st->print("JavaThread");
- else if (is_GC_task_thread()) st->print("GCTaskThread");
- else if (is_Watcher_thread()) st->print("WatcherThread");
- else if (is_ConcurrentGC_thread()) st->print("ConcurrentGCThread");
- else st->print("Thread");
+ assert(!(is_Compiler_thread() || is_Java_thread()), "Can't call name() here if it allocates");
+
+ if (is_VM_thread()) { st->print("VMThread"); }
+ else if (is_GC_task_thread()) { st->print("GCTaskThread"); }
+ else if (is_Watcher_thread()) { st->print("WatcherThread"); }
+ else if (is_ConcurrentGC_thread()) { st->print("ConcurrentGCThread"); }
+ else { st->print("Thread"); }
+
+ if (is_Named_thread()) {
+ st->print(" \"%s\"", name());
+ }
st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]",
p2i(stack_end()), p2i(stack_base()));
@@ -4498,6 +4502,36 @@
st->flush();
}
+void Threads::print_on_error(Thread* this_thread, outputStream* st, Thread* current, char* buf,
+ int buflen, bool* found_current) {
+ if (this_thread != NULL) {
+ bool is_current = (current == this_thread);
+ *found_current = *found_current || is_current;
+ st->print("%s", is_current ? "=>" : " ");
+
+ st->print(PTR_FORMAT, p2i(this_thread));
+ st->print(" ");
+ this_thread->print_on_error(st, buf, buflen);
+ st->cr();
+ }
+}
+
+class PrintOnErrorClosure : public ThreadClosure {
+ outputStream* _st;
+ Thread* _current;
+ char* _buf;
+ int _buflen;
+ bool* _found_current;
+ public:
+ PrintOnErrorClosure(outputStream* st, Thread* current, char* buf,
+ int buflen, bool* found_current) :
+ _st(st), _current(current), _buf(buf), _buflen(buflen), _found_current(found_current) {}
+
+ virtual void do_thread(Thread* thread) {
+ Threads::print_on_error(thread, _st, _current, _buf, _buflen, _found_current);
+ }
+};
+
// Threads::print_on_error() is called by fatal error handler. It's possible
// that VM is not at safepoint and/or current thread is inside signal handler.
// Don't print stack trace, as the stack may not be walkable. Don't allocate
@@ -4507,40 +4541,17 @@
bool found_current = false;
st->print_cr("Java Threads: ( => current thread )");
ALL_JAVA_THREADS(thread) {
- bool is_current = (current == thread);
- found_current = found_current || is_current;
-
- st->print("%s", is_current ? "=>" : " ");
-
- st->print(PTR_FORMAT, p2i(thread));
- st->print(" ");
- thread->print_on_error(st, buf, buflen);
- st->cr();
+ print_on_error(thread, st, current, buf, buflen, &found_current);
}
st->cr();
st->print_cr("Other Threads:");
- if (VMThread::vm_thread()) {
- bool is_current = (current == VMThread::vm_thread());
- found_current = found_current || is_current;
- st->print("%s", current == VMThread::vm_thread() ? "=>" : " ");
-
- st->print(PTR_FORMAT, p2i(VMThread::vm_thread()));
- st->print(" ");
- VMThread::vm_thread()->print_on_error(st, buf, buflen);
- st->cr();
- }
- WatcherThread* wt = WatcherThread::watcher_thread();
- if (wt != NULL) {
- bool is_current = (current == wt);
- found_current = found_current || is_current;
- st->print("%s", is_current ? "=>" : " ");
-
- st->print(PTR_FORMAT, p2i(wt));
- st->print(" ");
- wt->print_on_error(st, buf, buflen);
- st->cr();
- }
+ print_on_error(VMThread::vm_thread(), st, current, buf, buflen, &found_current);
+ print_on_error(WatcherThread::watcher_thread(), st, current, buf, buflen, &found_current);
+
+ PrintOnErrorClosure print_closure(st, current, buf, buflen, &found_current);
+ Universe::heap()->gc_threads_do(&print_closure);
+
if (!found_current) {
st->cr();
st->print("=>" PTR_FORMAT " (exited) ", p2i(current));
--- a/hotspot/src/share/vm/runtime/thread.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -46,7 +46,6 @@
#include "trace/traceMacros.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/macros.hpp"
-#include "utilities/top.hpp"
#if INCLUDE_ALL_GCS
#include "gc/g1/dirtyCardQueue.hpp"
#include "gc/g1/satbMarkQueue.hpp"
@@ -2157,6 +2156,8 @@
print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */);
}
static void print_on_error(outputStream* st, Thread* current, char* buf, int buflen);
+ static void print_on_error(Thread* this_thread, outputStream* st, Thread* current, char* buf,
+ int buflen, bool* found_current);
static void print_threads_compiling(outputStream* st, char* buf, int buflen);
// Get Java threads that are waiting to enter a monitor. If doLock
--- a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -25,7 +25,7 @@
#ifndef SHARE_VM_RUNTIME_THREADLOCALSTORAGE_HPP
#define SHARE_VM_RUNTIME_THREADLOCALSTORAGE_HPP
-#include "utilities/top.hpp"
+#include "memory/allocation.hpp"
// forward-decl as we can't have an include cycle
class Thread;
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -400,7 +400,6 @@
nonproduct_nonstatic_field(Method, _compiled_invocation_count, int) \
volatile_nonstatic_field(Method, _code, nmethod*) \
nonstatic_field(Method, _i2i_entry, address) \
- nonstatic_field(Method, _adapter, AdapterHandlerEntry*) \
volatile_nonstatic_field(Method, _from_compiled_entry, address) \
volatile_nonstatic_field(Method, _from_interpreted_entry, address) \
volatile_nonstatic_field(ConstMethod, _fingerprint, uint64_t) \
--- a/hotspot/src/share/vm/runtime/vmThread.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vmThread.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -26,7 +26,7 @@
#define SHARE_VM_RUNTIME_VMTHREAD_HPP
#include "runtime/perfData.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
#include "runtime/vm_operations.hpp"
//
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -29,7 +29,6 @@
#include "memory/allocation.hpp"
#include "oops/oop.hpp"
#include "runtime/thread.hpp"
-#include "utilities/top.hpp"
#include "code/codeCache.hpp"
// The following classes are used for operations
--- a/hotspot/src/share/vm/runtime/vm_version.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "code/codeCacheExtensions.hpp"
+#include "logging/log.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/arguments.hpp"
@@ -274,12 +275,12 @@
void VM_Version_init() {
VM_Version::initialize();
-#ifndef PRODUCT
- if (PrintMiscellaneous && Verbose) {
- char buf[512];
- os::print_cpu_info(tty, buf, sizeof(buf));
+ if (log_is_enabled(Info, os, cpu)) {
+ char buf[1024];
+ ResourceMark rm;
+ outputStream* log = Log(os, cpu)::info_stream();
+ os::print_cpu_info(log, buf, sizeof(buf));
}
-#endif
}
unsigned int Abstract_VM_Version::nof_parallel_worker_threads(
--- a/hotspot/src/share/vm/utilities/accessFlags.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/accessFlags.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -25,8 +25,9 @@
#ifndef SHARE_VM_UTILITIES_ACCESSFLAGS_HPP
#define SHARE_VM_UTILITIES_ACCESSFLAGS_HPP
+#include "memory/allocation.hpp"
#include "prims/jvm.h"
-#include "utilities/top.hpp"
+#include "utilities/macros.hpp"
// AccessFlags is an abstraction over Java access flags.
--- a/hotspot/src/share/vm/utilities/bitMap.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/bitMap.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -68,6 +68,10 @@
}
}
+void BitMap::pretouch() {
+ os::pretouch_memory(word_addr(0), word_addr(size()));
+}
+
void BitMap::set_range_within_word(idx_t beg, idx_t end) {
// With a valid range (beg <= end), this test ensures that end != 0, as
// required by inverted_bit_mask_for_range. Also avoids an unnecessary write.
--- a/hotspot/src/share/vm/utilities/bitMap.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/bitMap.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, 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
@@ -26,7 +26,6 @@
#define SHARE_VM_UTILITIES_BITMAP_HPP
#include "memory/allocation.hpp"
-#include "utilities/top.hpp"
// Forward decl;
class BitMapClosure;
@@ -135,10 +134,18 @@
// use the same value for "in_resource_area".)
void resize(idx_t size_in_bits, bool in_resource_area = true);
+ // Pretouch the entire range of memory this BitMap covers.
+ void pretouch();
+
// Accessing
idx_t size() const { return _size; }
+ idx_t size_in_bytes() const { return size_in_words() * BytesPerWord; }
idx_t size_in_words() const {
- return word_index(size() + BitsPerWord - 1);
+ return calc_size_in_words(size());
+ }
+
+ static idx_t calc_size_in_words(size_t size_in_bits) {
+ return word_index(size_in_bits + BitsPerWord - 1);
}
bool at(idx_t index) const {
--- a/hotspot/src/share/vm/utilities/constantTag.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/constantTag.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "utilities/constantTag.hpp"
+#include "utilities/ostream.hpp"
#ifndef PRODUCT
--- a/hotspot/src/share/vm/utilities/constantTag.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/constantTag.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -25,8 +25,8 @@
#ifndef SHARE_VM_UTILITIES_CONSTANTTAG_HPP
#define SHARE_VM_UTILITIES_CONSTANTTAG_HPP
+#include "memory/allocation.hpp"
#include "prims/jvm.h"
-#include "utilities/top.hpp"
// constant tags in Java .class files
--- a/hotspot/src/share/vm/utilities/debug.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/debug.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -52,7 +52,6 @@
#include "utilities/defaultStream.hpp"
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
-#include "utilities/top.hpp"
#include "utilities/vmError.hpp"
#if INCLUDE_TRACE
--- a/hotspot/src/share/vm/utilities/events.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/events.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -28,7 +28,6 @@
#include "memory/allocation.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/thread.hpp"
-#include "utilities/top.hpp"
#include "utilities/vmError.hpp"
// Events and EventMark provide interfaces to log events taking place in the vm.
--- a/hotspot/src/share/vm/utilities/exceptions.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -47,7 +47,6 @@
// Forward declarations to be independent of the include structure.
-// This allows us to have exceptions.hpp included in top.hpp.
class Thread;
class Handle;
--- a/hotspot/src/share/vm/utilities/globalDefinitions.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -25,7 +25,6 @@
#include "precompiled.hpp"
#include "runtime/os.hpp"
#include "utilities/globalDefinitions.hpp"
-#include "utilities/top.hpp"
// Basic error support
@@ -374,39 +373,89 @@
#ifndef PRODUCT
// For unit testing only
-class GlobalDefinitions {
+class TestGlobalDefinitions {
+private:
+
+ static void test_clamp_address_in_page() {
+ intptr_t page_sizes[] = { os::vm_page_size(), 4096, 8192, 65536, 2*1024*1024 };
+ const int num_page_sizes = sizeof(page_sizes) / sizeof(page_sizes[0]);
+
+ for (int i = 0; i < num_page_sizes; i++) {
+ intptr_t page_size = page_sizes[i];
+
+ address a_page = (address)(10*page_size);
+
+ // Check that address within page is returned as is
+ assert(clamp_address_in_page(a_page, a_page, page_size) == a_page, "incorrect");
+ assert(clamp_address_in_page(a_page + 128, a_page, page_size) == a_page + 128, "incorrect");
+ assert(clamp_address_in_page(a_page + page_size - 1, a_page, page_size) == a_page + page_size - 1, "incorrect");
+
+ // Check that address above page returns start of next page
+ assert(clamp_address_in_page(a_page + page_size, a_page, page_size) == a_page + page_size, "incorrect");
+ assert(clamp_address_in_page(a_page + page_size + 1, a_page, page_size) == a_page + page_size, "incorrect");
+ assert(clamp_address_in_page(a_page + page_size*5 + 1, a_page, page_size) == a_page + page_size, "incorrect");
+
+ // Check that address below page returns start of page
+ assert(clamp_address_in_page(a_page - 1, a_page, page_size) == a_page, "incorrect");
+ assert(clamp_address_in_page(a_page - 2*page_size - 1, a_page, page_size) == a_page, "incorrect");
+ assert(clamp_address_in_page(a_page - 5*page_size - 1, a_page, page_size) == a_page, "incorrect");
+ }
+ }
+
+ static void test_exact_unit_for_byte_size() {
+ assert(strcmp(exact_unit_for_byte_size(0), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(K - 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(K), "K") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(K + 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(M - 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(M), "M") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(M + 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(M + K), "K") == 0, "incorrect");
+#ifdef LP64
+ assert(strcmp(exact_unit_for_byte_size(G - 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(G), "G") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(G + 1), "B") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(G + K), "K") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(G + M), "M") == 0, "incorrect");
+ assert(strcmp(exact_unit_for_byte_size(G + M + K), "K") == 0, "incorrect");
+#endif
+ }
+
+ static void test_byte_size_in_exact_unit() {
+ assert(byte_size_in_exact_unit(0) == 0, "incorrect");
+ assert(byte_size_in_exact_unit(1) == 1, "incorrect");
+ assert(byte_size_in_exact_unit(K - 1) == K - 1, "incorrect");
+ assert(byte_size_in_exact_unit(K) == 1, "incorrect");
+ assert(byte_size_in_exact_unit(K + 1) == K + 1, "incorrect");
+ assert(byte_size_in_exact_unit(M - 1) == M - 1, "incorrect");
+ assert(byte_size_in_exact_unit(M) == 1, "incorrect");
+ assert(byte_size_in_exact_unit(M + 1) == M + 1, "incorrect");
+ assert(byte_size_in_exact_unit(M + K) == K + 1, "incorrect");
+#ifdef LP64
+ assert(byte_size_in_exact_unit(G - 1) == G - 1, "incorrect");
+ assert(byte_size_in_exact_unit(G) == 1, "incorrect");
+ assert(byte_size_in_exact_unit(G + 1) == G + 1, "incorrect");
+ assert(byte_size_in_exact_unit(G + K) == M + 1, "incorrect");
+ assert(byte_size_in_exact_unit(G + M) == K + 1, "incorrect");
+ assert(byte_size_in_exact_unit(G + M + K) == M + K + 1, "incorrect");
+#endif
+ }
+
+ static void test_exact_units() {
+ test_exact_unit_for_byte_size();
+ test_byte_size_in_exact_unit();
+ }
+
public:
- static void test_globals();
+ static void test() {
+ test_clamp_address_in_page();
+ test_exact_units();
+ }
};
-void GlobalDefinitions::test_globals() {
- intptr_t page_sizes[] = { os::vm_page_size(), 4096, 8192, 65536, 2*1024*1024 };
- const int num_page_sizes = sizeof(page_sizes) / sizeof(page_sizes[0]);
-
- for (int i = 0; i < num_page_sizes; i++) {
- intptr_t page_size = page_sizes[i];
-
- address a_page = (address)(10*page_size);
-
- // Check that address within page is returned as is
- assert(clamp_address_in_page(a_page, a_page, page_size) == a_page, "incorrect");
- assert(clamp_address_in_page(a_page + 128, a_page, page_size) == a_page + 128, "incorrect");
- assert(clamp_address_in_page(a_page + page_size - 1, a_page, page_size) == a_page + page_size - 1, "incorrect");
-
- // Check that address above page returns start of next page
- assert(clamp_address_in_page(a_page + page_size, a_page, page_size) == a_page + page_size, "incorrect");
- assert(clamp_address_in_page(a_page + page_size + 1, a_page, page_size) == a_page + page_size, "incorrect");
- assert(clamp_address_in_page(a_page + page_size*5 + 1, a_page, page_size) == a_page + page_size, "incorrect");
-
- // Check that address below page returns start of page
- assert(clamp_address_in_page(a_page - 1, a_page, page_size) == a_page, "incorrect");
- assert(clamp_address_in_page(a_page - 2*page_size - 1, a_page, page_size) == a_page, "incorrect");
- assert(clamp_address_in_page(a_page - 5*page_size - 1, a_page, page_size) == a_page, "incorrect");
- }
-}
-
-void GlobalDefinitions_test() {
- GlobalDefinitions::test_globals();
+void TestGlobalDefinitions_test() {
+ TestGlobalDefinitions::test();
}
#endif // PRODUCT
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -243,6 +243,36 @@
}
}
+inline const char* exact_unit_for_byte_size(size_t s) {
+#ifdef _LP64
+ if (s >= G && (s % G) == 0) {
+ return "G";
+ }
+#endif
+ if (s >= M && (s % M) == 0) {
+ return "M";
+ }
+ if (s >= K && (s % K) == 0) {
+ return "K";
+ }
+ return "B";
+}
+
+inline size_t byte_size_in_exact_unit(size_t s) {
+#ifdef _LP64
+ if (s >= G && (s % G) == 0) {
+ return s / G;
+ }
+#endif
+ if (s >= M && (s % M) == 0) {
+ return s / M;
+ }
+ if (s >= K && (s % K) == 0) {
+ return s / K;
+ }
+ return s;
+}
+
//----------------------------------------------------------------------------------------------------
// VM type definitions
@@ -328,7 +358,7 @@
// so far from the middle of the road that it is likely to be problematic in
// many C++ compilers.
//
-#define CAST_TO_FN_PTR(func_type, value) ((func_type)(castable_address(value)))
+#define CAST_TO_FN_PTR(func_type, value) (reinterpret_cast<func_type>(value))
#define CAST_FROM_FN_PTR(new_type, func_ptr) ((new_type)((address_word)(func_ptr)))
// Unsigned byte types for os and stream.hpp
--- a/hotspot/src/share/vm/utilities/growableArray.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -29,7 +29,6 @@
#include "memory/allocation.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
-#include "utilities/top.hpp"
// A growable array.
--- a/hotspot/src/share/vm/utilities/internalVMTests.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/internalVMTests.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -50,7 +50,7 @@
run_unit_test(TestMetaspaceAux_test);
run_unit_test(TestMetachunk_test);
run_unit_test(TestVirtualSpaceNode_test);
- run_unit_test(GlobalDefinitions_test);
+ run_unit_test(TestGlobalDefinitions_test);
run_unit_test(GCTimer_test);
run_unit_test(arrayOopDesc_test);
run_unit_test(CollectedHeap_test);
@@ -67,6 +67,7 @@
run_unit_test(Test_linked_list);
run_unit_test(TestChunkedList_test);
run_unit_test(JSON_test);
+ run_unit_test(Test_log_tag_combinations_limit);
run_unit_test(Test_logtarget);
run_unit_test(Test_logstream);
run_unit_test(Test_loghandle);
@@ -77,6 +78,9 @@
run_unit_test(Test_log_prefix);
run_unit_test(Test_log_big);
run_unit_test(Test_logtagset_duplicates);
+ run_unit_test(Test_log_file_startup_rotation);
+ run_unit_test(Test_log_file_startup_truncation);
+ run_unit_test(Test_invalid_log_file);
run_unit_test(DirectivesParser_test);
run_unit_test(Test_TempNewSymbol);
#if INCLUDE_VM_STRUCTS
--- a/hotspot/src/share/vm/utilities/ostream.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -31,7 +31,6 @@
#include "utilities/defaultStream.hpp"
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
-#include "utilities/top.hpp"
#include "utilities/xmlstream.hpp"
extern "C" void jio_print(const char* s); // Declarationtion of jvm method
--- a/hotspot/src/share/vm/utilities/pair.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/pair.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -26,7 +26,6 @@
#define SHARE_VM_UTILITIES_PAIR_HPP
#include "memory/allocation.hpp"
-#include "utilities/top.hpp"
template<typename T, typename V, typename ALLOC_BASE = ResourceObj>
class Pair : public ALLOC_BASE {
--- a/hotspot/src/share/vm/utilities/preserveException.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/preserveException.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -26,7 +26,7 @@
#define SHARE_VM_UTILITIES_PRESERVEEXCEPTION_HPP
#include "runtime/handles.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
// This file provides more support for exception handling; see also exceptions.hpp
class PreserveExceptionMark {
--- a/hotspot/src/share/vm/utilities/resourceHash.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/resourceHash.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -26,7 +26,6 @@
#define SHARE_VM_UTILITIES_RESOURCEHASH_HPP
#include "memory/allocation.hpp"
-#include "utilities/top.hpp"
template<typename K> struct ResourceHashtableFns {
typedef unsigned (*hash_fn)(K const&);
--- a/hotspot/src/share/vm/utilities/top.hpp Thu Apr 14 09:33:16 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_UTILITIES_TOP_HPP
-#define SHARE_VM_UTILITIES_TOP_HPP
-
-#include "oops/oopsHierarchy.hpp"
-#include "runtime/globals.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/exceptions.hpp"
-#include "utilities/globalDefinitions.hpp"
-#include "utilities/macros.hpp"
-#include "utilities/ostream.hpp"
-#include "utilities/sizes.hpp"
-#if INCLUDE_ALL_GCS
-#include "gc/g1/g1_globals.hpp"
-#endif // INCLUDE_ALL_GCS
-#ifdef COMPILER1
-#include "c1/c1_globals.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/c2_globals.hpp"
-#endif
-#if INCLUDE_JVMCI
-#include "jvmci/jvmci_globals.hpp"
-#endif
-
-// THIS FILE IS INTESIONALLY LEFT EMPTY
-// IT IS USED TO MINIMIZE THE NUMBER OF DEPENDENCIES IN includeDB
-
-#endif // SHARE_VM_UTILITIES_TOP_HPP
--- a/hotspot/src/share/vm/utilities/utf8.hpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/utf8.hpp Thu Apr 14 19:55:39 2016 -0700
@@ -26,7 +26,6 @@
#define SHARE_VM_UTILITIES_UTF8_HPP
#include "memory/allocation.hpp"
-#include "utilities/top.hpp"
// Low-level interface for UTF8 strings
--- a/hotspot/src/share/vm/utilities/vmError.cpp Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Thu Apr 14 19:55:39 2016 -0700
@@ -43,7 +43,6 @@
#include "utilities/defaultStream.hpp"
#include "utilities/errorReporter.hpp"
#include "utilities/events.hpp"
-#include "utilities/top.hpp"
#include "utilities/vmError.hpp"
// List of environment variables that should be reported in error log file.
--- a/hotspot/test/TEST.ROOT Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/TEST.ROOT Thu Apr 14 19:55:39 2016 -0700
@@ -30,6 +30,10 @@
keys=cte_test jcmd nmt regression gc stress
groups=TEST.groups [closed/TEST.groups]
+
+# Source files for classes that will be used at the beginning of each test suite run,
+# to determine additional characteristics of the system for use with the @requires tag.
+requires.extraPropDefns = ../../test/jtreg-ext/requires/VMProps.java
requires.properties=sun.arch.data.model
# Tests using jtreg 4.2 b01 features
--- a/hotspot/test/TEST.groups Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/TEST.groups Thu Apr 14 19:55:39 2016 -0700
@@ -387,7 +387,8 @@
:hotspot_fast_compiler_2 \
:hotspot_fast_compiler_3 \
:hotspot_fast_compiler_closed \
- :hotspot_fast_gc \
+ :hotspot_fast_gc_1 \
+ :hotspot_fast_gc_2 \
:hotspot_fast_gc_closed \
:hotspot_fast_gc_gcold \
:hotspot_fast_runtime \
--- a/hotspot/test/gc/TestHumongousReferenceObject.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/gc/TestHumongousReferenceObject.java Thu Apr 14 19:55:39 2016 -0700
@@ -27,26 +27,26 @@
* @test
* @summary Test that verifies that iteration over large, plain Java objects, that potentially cross region boundaries on G1, with references in them works.
* @requires vm.gc == "null"
- * @bug 8151499
+ * @bug 8151499 8153734
* @modules java.base/jdk.internal.vm.annotation
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseParallelGC -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=1M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=2M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
- * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx1g -XX:+UseG1GC -XX:G1HeapRegionSize=8M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseParallelGC -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=1M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=2M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
+ * @run main/othervm -XX:+EnableContended -XX:-RestrictContended -Xmx128m -XX:+UseG1GC -XX:G1HeapRegionSize=8M -XX:ContendedPaddingWidth=8192 TestHumongousReferenceObject
*/
public class TestHumongousReferenceObject {
/*
Due to 300 fields with 8K @Contended padding around each field, it takes 2.4M bytes per instance.
With small G1 regions, it is bound to cross regions. G1 should properly (card) mark the object nevertheless.
- With 1G heap, it is enough to allocate ~400 of these objects to provoke at least one GC.
+ With 128M heap, it is enough to allocate ~100 of these objects to provoke at least one GC.
*/
static volatile Object instance;
public static void main(String[] args) {
- for (int c = 0; c < 400; c++) {
+ for (int c = 0; c < 100; c++) {
instance = new TestHumongousReferenceObject();
}
}
--- a/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Thu Apr 14 19:55:39 2016 -0700
@@ -168,6 +168,11 @@
long maxHeapSize = getMax();
int gcTries = (shrinkHeapInSteps ? GC_TRIES : 1);
+ // Initial checks. This also links up everything in these helper methods,
+ // in case it brings more garbage.
+ forceGC(gcTries);
+ verifyRatio(minRatio, maxRatio);
+
// commit 0.5 of total heap size to have enough space
// to both shink and expand
while (getCommitted() < maxHeapSize / 2) {
@@ -215,7 +220,6 @@
if (previouslyCommitted <= getCommitted()) {
throw new RuntimeException("Heap was not shrinked.");
}
-
}
public static void forceGC(int gcTries) {
--- a/hotspot/test/gc/g1/Test2GbHeap.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/gc/g1/Test2GbHeap.java Thu Apr 14 19:55:39 2016 -0700
@@ -25,6 +25,9 @@
* @test Test2GbHeap
* @bug 8031686
* @summary Regression test to ensure we can start G1 with 2gb heap.
+ * Skip test on 32 bit Windows: it typically does not support the many and large virtual memory reservations needed.
+ * @requires (vm.gc == "G1" | vm.gc == "null")
+ * @requires !((sun.arch.data.model == "32") & (os.family == "windows"))
* @key gc
* @key regression
* @library /testlibrary
@@ -48,17 +51,6 @@
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(testArguments.toArray(new String[0]));
OutputAnalyzer output = new OutputAnalyzer(pb.start());
-
- // Avoid failing test for setups not supported.
- if (output.getOutput().contains("Could not reserve enough space for 2097152KB object heap")) {
- // Will fail on machines with too little memory (and Windows 32-bit VM), ignore such failures.
- output.shouldHaveExitValue(1);
- } else if (output.getOutput().contains("-XX:+UseG1GC not supported in this VM")) {
- // G1 is not supported on embedded, ignore such failures.
- output.shouldHaveExitValue(1);
- } else {
- // Normally everything should be fine.
- output.shouldHaveExitValue(0);
- }
+ output.shouldHaveExitValue(0);
}
}
--- a/hotspot/test/gc/g1/TestLargePageUseForAuxMemory.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/gc/g1/TestLargePageUseForAuxMemory.java Thu Apr 14 19:55:39 2016 -0700
@@ -36,6 +36,8 @@
*/
import java.lang.Math;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import jdk.test.lib.*;
import jdk.test.lib.Asserts;
@@ -47,14 +49,29 @@
static long smallPageSize;
static long allocGranularity;
+ static void checkSize(OutputAnalyzer output, long expectedSize, String pattern) {
+ String pageSizeStr = output.firstMatch(pattern, 1);
+
+ if (pageSizeStr == null) {
+ output.reportDiagnosticSummary();
+ throw new RuntimeException("Match from '" + pattern + "' got 'null' expected: " + expectedSize);
+ }
+
+ long size = parseMemoryString(pageSizeStr);
+ if (size != expectedSize) {
+ output.reportDiagnosticSummary();
+ throw new RuntimeException("Match from '" + pattern + "' got " + size + " expected: " + expectedSize);
+ }
+ }
+
static void checkSmallTables(OutputAnalyzer output, long expectedPageSize) throws Exception {
- output.shouldContain("G1 'Block offset table': pg_sz=" + expectedPageSize);
- output.shouldContain("G1 'Card counts table': pg_sz=" + expectedPageSize);
+ checkSize(output, expectedPageSize, "Block Offset Table: .*page_size=([^ ]+)");
+ checkSize(output, expectedPageSize, "Card Counts Table: .*page_size=([^ ]+)");
}
static void checkBitmaps(OutputAnalyzer output, long expectedPageSize) throws Exception {
- output.shouldContain("G1 'Prev Bitmap': pg_sz=" + expectedPageSize);
- output.shouldContain("G1 'Next Bitmap': pg_sz=" + expectedPageSize);
+ checkSize(output, expectedPageSize, "Prev Bitmap: .*page_size=([^ ]+)");
+ checkSize(output, expectedPageSize, "Next Bitmap: .*page_size=([^ ]+)");
}
static void testVM(String what, long heapsize, boolean cardsShouldUseLargePages, boolean bitmapShouldUseLargePages) throws Exception {
@@ -66,7 +83,7 @@
"-XX:G1HeapRegionSize=" + HEAP_REGION_SIZE,
"-Xms" + heapsize,
"-Xmx" + heapsize,
- "-XX:+TracePageSizes",
+ "-Xlog:pagesize",
"-XX:+UseLargePages",
"-XX:+IgnoreUnrecognizedVMOptions", // there is no ObjectAlignmentInBytes in 32 bit builds
"-XX:ObjectAlignmentInBytes=8",
@@ -82,7 +99,7 @@
"-XX:G1HeapRegionSize=" + HEAP_REGION_SIZE,
"-Xms" + heapsize,
"-Xmx" + heapsize,
- "-XX:+TracePageSizes",
+ "-Xlog:pagesize",
"-XX:-UseLargePages",
"-XX:+IgnoreUnrecognizedVMOptions", // there is no ObjectAlignmentInBytes in 32 bit builds
"-XX:ObjectAlignmentInBytes=8",
@@ -108,11 +125,6 @@
}
public static void main(String[] args) throws Exception {
- if (!Platform.isDebugBuild()) {
- System.out.println("Skip tests on non-debug builds because the required option TracePageSizes is a debug-only option.");
- return;
- }
-
// Size that a single card covers.
final int cardSize = 512;
WhiteBox wb = WhiteBox.getWhiteBox();
@@ -159,4 +171,24 @@
testVM("case5: only bitmap uses large pages (extra slack)", heapSizeForBitmapUsingLargePages + heapSizeDiffForBitmap, false, true);
testVM("case6: nothing uses large pages (barely not)", heapSizeForBitmapUsingLargePages - heapSizeDiffForBitmap, false, false);
}
+
+ public static long parseMemoryString(String value) {
+ long multiplier = 1;
+
+ if (value.endsWith("B")) {
+ multiplier = 1;
+ } else if (value.endsWith("K")) {
+ multiplier = 1024;
+ } else if (value.endsWith("M")) {
+ multiplier = 1024 * 1024;
+ } else if (value.endsWith("G")) {
+ multiplier = 1024 * 1024 * 1024;
+ } else {
+ throw new IllegalArgumentException("Expected memory string '" + value + "'to end with either of: B, K, M, G");
+ }
+
+ long longValue = Long.parseUnsignedLong(value.substring(0, value.length() - 1));
+
+ return longValue * multiplier;
+ }
}
--- a/hotspot/test/gc/g1/humongousObjects/TestHumongousThreshold.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/gc/g1/humongousObjects/TestHumongousThreshold.java Thu Apr 14 19:55:39 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -70,7 +70,7 @@
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
private static final int REGION_SIZE = WHITE_BOX.g1RegionSize();
private static final int MAX_CONTINUOUS_SIZE_CHECK = 129;
- private static final int NON_HUMONGOUS_DIVIDER = 10;
+ private static final int NON_HUMONGOUS_STEPS = 10;
/**
* The method allocates byte[] with specified size and checks that:
@@ -84,7 +84,7 @@
* @return allocated byte array
*/
- private static byte[] allocateAndCheck(int arraySize, boolean expectedHumongous) {
+ private static void allocateAndCheck(int arraySize, boolean expectedHumongous) {
byte[] storage = new byte[arraySize];
long objectSize = WHITE_BOX.getObjectSize(storage);
boolean shouldBeHumongous = objectSize > (REGION_SIZE / 2);
@@ -98,7 +98,6 @@
"Object should be allocated as " + (shouldBeHumongous ? "humongous"
: "non-humongous") + " but it wasn't; Allocation size = " + arraySize + "; Object size = "
+ objectSize + "; region size = " + REGION_SIZE);
- return storage;
}
public static void main(String[] args) {
@@ -108,7 +107,7 @@
int maxByteArrayNonHumongousSize = (REGION_SIZE / 2) - byteArrayMemoryOverhead;
// Increment for non-humongous testing
- int nonHumongousStep = maxByteArrayNonHumongousSize / NON_HUMONGOUS_DIVIDER;
+ int nonHumongousStep = maxByteArrayNonHumongousSize / NON_HUMONGOUS_STEPS;
// Maximum byte[] that takes one region
int maxByteArrayOneRegionSize = REGION_SIZE - byteArrayMemoryOverhead;
@@ -131,10 +130,10 @@
allocateAndCheck(i, false);
}
- // Testing allocations with byte[] with length from 0 to nonHumongousStep * NON_HUMONGOUS_DIVIDER
+ // Testing allocations with byte[] with length from 0 to nonHumongousStep * NON_HUMONGOUS_STEPS
System.out.format("Testing allocations with byte[] with length from 0 to %d with step %d%n",
- nonHumongousStep * NON_HUMONGOUS_DIVIDER, nonHumongousStep);
- for (int i = 0; i < NON_HUMONGOUS_DIVIDER; ++i) {
+ nonHumongousStep * NON_HUMONGOUS_STEPS, nonHumongousStep);
+ for (int i = 0; i < NON_HUMONGOUS_STEPS; ++i) {
allocateAndCheck(i * nonHumongousStep, false);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/plab/TestPLABEvacuationFailure.java Thu Apr 14 19:55:39 2016 -0700
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+ /*
+ * @test TestPLABEvacuationFailure
+ * @bug 8148376
+ * @summary Checks PLAB statistics on evacuation failure
+ * @requires vm.gc=="G1" | vm.gc=="null"
+ * @library /testlibrary /
+ * @modules java.management
+ * @build gc.g1.plab.lib.LogParser
+ * gc.g1.plab.lib.AppPLABEvacuationFailure
+ * @run main gc.g1.plab.TestPLABEvacuationFailure
+ */
+package gc.g1.plab;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Utils;
+
+import gc.g1.plab.lib.LogParser;
+import gc.g1.plab.lib.AppPLABEvacuationFailure;
+import gc.g1.plab.lib.PlabInfo;
+
+/**
+ * The test runs the AppPLABEvacuationFailure application to provoke a number of
+ * Evacuation Failures, parses GC log and analyzes PLAB statistics. The test checks
+ * that both fields 'failure_waste' and 'failure_used' for Evacuation Failure statistic
+ * are non zero, and zero for other statistics.
+ */
+public class TestPLABEvacuationFailure {
+
+ /* PLAB statistics fields which are checked.
+ * Test expects to find 0 in this fields in survivor statistics.
+ * Expects to find 0 in old statistics for GC when evacuation failure
+ * did not happen. And expects to find not 0 in old statistics in case when
+ * GC causes to evacuation failure.
+ */
+ private static final List<String> FAILURE_STAT_FIELDS = new ArrayList<>(Arrays.asList(
+ "failure used",
+ "failure wasted"));
+
+ private static final String[] COMMON_OPTIONS = {
+ "-Xlog:gc=debug,gc+plab=debug,gc+phases=trace",
+ "-XX:+UseG1GC",
+ "-XX:InitiatingHeapOccupancyPercent=100",
+ "-XX:-G1UseAdaptiveIHOP",
+ "-XX:G1HeapRegionSize=1m"};
+
+ private static final Pattern GC_ID_PATTERN = Pattern.compile("GC\\((\\d+)\\)");
+ private static List<Long> evacuationFailureIDs;
+ private static LogParser logParser;
+ private static String appPlabEvacFailureOutput;
+
+ public static void main(String[] args) throws Throwable {
+ // ParallelGCBufferWastePct, PLAB Size, ParallelGCBufferWastePct, MaxHeapSize, is plab fixed.
+ runTest(10, 1024, 3, 16, true);
+ runTest(15, 2048, 4, 256, true);
+ runTest(20, 65536, 7, 128, false);
+ runTest(25, 1024, 3, 16, true);
+ runTest(30, 16384, 7, 256, false);
+ runTest(10, 65536, 4, 32, false);
+ }
+
+ private static void runTest(int wastePct, int plabSize, int parGCThreads, int heapSize, boolean plabIsFixed) throws Throwable {
+ System.out.println("Test case details:");
+ System.out.println(" Heap size : " + heapSize + "M");
+ System.out.println(" Initial PLAB size : " + plabSize);
+ System.out.println(" Parallel GC buffer waste pct : " + wastePct);
+ System.out.println(" Parallel GC threads : " + parGCThreads);
+ System.out.println(" PLAB size is fixed: " + (plabIsFixed ? "yes" : "no"));
+ // Set up test GC and PLAB options
+ List<String> testOptions = new ArrayList<>();
+ Collections.addAll(testOptions, COMMON_OPTIONS);
+ Collections.addAll(testOptions, Utils.getTestJavaOpts());
+ Collections.addAll(testOptions,
+ "-XX:ParallelGCThreads=" + parGCThreads,
+ "-XX:ParallelGCBufferWastePct=" + wastePct,
+ "-XX:OldPLABSize=" + plabSize,
+ "-XX:YoungPLABSize=" + plabSize,
+ "-XX:" + (plabIsFixed ? "-" : "+") + "ResizePLAB",
+ "-XX:MaxHeapSize=" + heapSize + "m");
+ testOptions.add(AppPLABEvacuationFailure.class.getName());
+ OutputAnalyzer out = ProcessTools.executeTestJvm(testOptions.toArray(new String[testOptions.size()]));
+
+ appPlabEvacFailureOutput = out.getOutput();
+ if (out.getExitValue() != 0) {
+ System.out.println(appPlabEvacFailureOutput);
+ throw new RuntimeException("Expect exit code 0.");
+ }
+ // Get list of GC ID on evacuation failure
+ evacuationFailureIDs = getGcIdPlabEvacFailures(out);
+ logParser = new LogParser(appPlabEvacFailureOutput);
+ checkResults();
+ }
+
+ private static void checkResults() {
+
+ if (evacuationFailureIDs.isEmpty()) {
+ System.out.println(appPlabEvacFailureOutput);
+ throw new RuntimeException("AppPLABEvacuationFailure did not reach Evacuation Failure.");
+ }
+
+ Map<Long, PlabInfo> valuesToCheck = getNonEvacFailureSurvivorStats();
+ checkValuesIsZero(valuesToCheck, "Expect that SURVIVOR PLAB failure statistics should be 0 when no evacuation failure");
+
+ valuesToCheck = getNonEvacFailureOldStats();
+ checkValuesIsZero(valuesToCheck, "Expect that OLD PLAB failure statistics should be 0 when no evacuation failure");
+
+ valuesToCheck = getEvacFailureSurvivorStats();
+ checkValuesIsZero(valuesToCheck, "Expect that failure statistics should be 0 in SURVIVOR PLAB statistics at evacuation failure");
+
+ valuesToCheck = getEvacFailureOldStats();
+ checkValuesIsNotZero(valuesToCheck, "Expect that failure statistics should not be 0 in OLD PLAB statistics at evacuation failure");
+ }
+
+ /**
+ * Checks logItems for non-zero values. Throws RuntimeException if found.
+ *
+ * @param logItems
+ * @param errorMessage
+ */
+ private static void checkValuesIsZero(Map<Long, PlabInfo> logItems, String errorMessage) {
+ checkValues(logItems, errorMessage, true);
+ }
+
+ /**
+ * Checks logItems for zero values. Throws RuntimeException if found.
+ *
+ * @param logItems
+ * @param errorMessage
+ */
+ private static void checkValuesIsNotZero(Map<Long, PlabInfo> logItems, String errorMessage) {
+ checkValues(logItems, errorMessage, false);
+ }
+
+ private static void checkValues(Map<Long, PlabInfo> logItems, String errorMessage, boolean expectZero) {
+ logItems.entrySet()
+ .forEach(item -> item.getValue()
+ .values()
+ .forEach(items -> {
+ if (expectZero != (items == 0)) {
+ System.out.println(appPlabEvacFailureOutput);
+ throw new RuntimeException(errorMessage);
+ }
+ })
+ );
+ }
+
+ /**
+ * For tracking PLAB statistics for specified PLAB type - survivor and old
+ */
+ private static Map<Long, PlabInfo> getNonEvacFailureSurvivorStats() {
+ return logParser.getExcludedSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.SURVIVOR_STATS, FAILURE_STAT_FIELDS);
+ }
+
+ private static Map<Long, PlabInfo> getNonEvacFailureOldStats() {
+ return logParser.getExcludedSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.OLD_STATS, FAILURE_STAT_FIELDS);
+ }
+
+ private static Map<Long, PlabInfo> getEvacFailureSurvivorStats() {
+ return logParser.getSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.SURVIVOR_STATS, FAILURE_STAT_FIELDS);
+ }
+
+ private static Map<Long, PlabInfo> getEvacFailureOldStats() {
+ return logParser.getSpecifiedStats(evacuationFailureIDs, LogParser.ReportType.OLD_STATS, FAILURE_STAT_FIELDS);
+ }
+
+ private static List<Long> getGcIdPlabEvacFailures(OutputAnalyzer out) {
+ return out.asLines().stream()
+ .filter(line -> line.contains("Evacuation Failure"))
+ .map(line -> LogParser.getGcIdFromLine(line, GC_ID_PATTERN))
+ .collect(Collectors.toList());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/g1/plab/lib/AppPLABEvacuationFailure.java Thu Apr 14 19:55:39 2016 -0700
@@ -0,0 +1,54 @@
+/*
+ * 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 gc.g1.plab.lib;
+
+import java.util.ArrayList;
+
+/**
+ * Application that provokes Evacuation Failure
+ */
+public class AppPLABEvacuationFailure {
+
+ public static final int CHUNK = 10000;
+ public static ArrayList<Object> arr = new ArrayList<>();
+
+ public static void main(String[] args) {
+ System.gc();
+ // First attempt.
+ try {
+ while (true) {
+ arr.add(new byte[CHUNK]);
+ }
+ } catch (OutOfMemoryError oome) {
+ arr.clear();
+ }
+ // Second attempt.
+ try {
+ while (true) {
+ arr.add(new byte[CHUNK]);
+ }
+ } catch (OutOfMemoryError oome) {
+ arr.clear();
+ }
+ }
+}
--- a/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java Thu Apr 14 19:55:39 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -85,8 +85,7 @@
public static void heapBaseMinAddressTest() throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:HeapBaseMinAddress=1m",
- "-XX:+UnlockDiagnosticVMOptions",
- "-XX:+PrintCompressedOopsMode",
+ "-Xlog:gc+heap+coops=debug",
"-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("HeapBaseMinAddress must be at least");
--- a/hotspot/test/runtime/CompressedOops/UseCompressedOops.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/runtime/CompressedOops/UseCompressedOops.java Thu Apr 14 19:55:39 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -169,7 +169,6 @@
ArrayList<String> args = new ArrayList<>();
// Always run with these three:
- args.add("-XX:+UnlockDiagnosticVMOptions");
args.add("-XX:+PrintCompressedOopsMode");
args.add("-Xms32m");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Throwable/ThrowableIntrospectionSegfault.java Thu Apr 14 19:55:39 2016 -0700
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8033735
+ * @summary check backtrace field introspection
+ * @library /testlibrary
+ * @run main ThrowableIntrospectionSegfault
+ */
+
+import java.lang.reflect.*;
+
+public class ThrowableIntrospectionSegfault {
+ public static void main(java.lang.String[] unused) {
+ // Construct a throwable object.
+ Throwable throwable = new Throwable();
+ throwable.fillInStackTrace();
+
+ // Retrieve a reflection handle to the private backtrace field.
+ Class class1 = throwable.getClass();
+ Field field;
+ try {
+ field = class1.getDeclaredField("backtrace");
+ }
+ catch (NoSuchFieldException e) {
+ System.err.println("Can't retrieve field handle Throwable.backtrace: " + e.toString());
+ return;
+ }
+ field.setAccessible(true);
+
+ // Retrieve the value of the backtrace field.
+ Object backtrace;
+ try {
+ backtrace = field.get(throwable);
+ }
+ catch (IllegalAccessException e) {
+ System.err.println( "Can't retrieve field value for Throwable.backtrace: " + e.toString());
+ return;
+ }
+
+ try {
+
+ // Retrieve the class of throwable.backtrace[0][0].
+ Class class2 = ((Object[]) ((Object[]) backtrace)[2])[0].getClass();
+
+ // Segfault occurs while executing this line, to retrieve the name of
+ // this class.
+ String class2Name = class2.getName();
+
+ System.err.println("class2Name=" + class2Name);
+ return; // pass! Passes if it doesn't crash.
+ } catch (ClassCastException e) {
+ // Passes if it doesn't crash. Also if the backtrace changes this test might get
+ // ClassCastException and that's ok too.
+ System.out.println("Catch exception " + e);
+ return; // pass! Passes if it doesn't crash.
+ }
+ }
+}
--- a/hotspot/test/runtime/logging/ClassInitializationTest.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/runtime/logging/ClassInitializationTest.java Thu Apr 14 19:55:39 2016 -0700
@@ -62,6 +62,16 @@
out.shouldContain("[Initialized").shouldContain("without side effects]");
out.shouldHaveExitValue(0);
}
+
+ // (3) classinit should turn off.
+ pb = ProcessTools.createJavaProcessBuilder("-Xlog:classinit=off",
+ "-Xverify:all",
+ "-Xmx64m",
+ "BadMap50");
+ out = new OutputAnalyzer(pb.start());
+ out.shouldNotContain("[classinit]");
+ out.shouldNotContain("Fail over class verification to old verifier for: BadMap50");
+
}
public static class InnerClass {
public static void main(String[] args) throws Exception {
--- a/hotspot/test/runtime/logging/ClassResolutionTest.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/runtime/logging/ClassResolutionTest.java Thu Apr 14 19:55:39 2016 -0700
@@ -51,7 +51,8 @@
};
public static void main(String... args) throws Exception {
- Thing1Handler.getThingNumber();
+ int x = Thing1Handler.getThingNumber();
+ System.out.println("ThingNumber: "+Integer.toString(x));
}
}
@@ -62,6 +63,7 @@
ClassResolutionTestMain.class.getName());
OutputAnalyzer o = new OutputAnalyzer(pb.start());
o.shouldContain("[classresolve] ClassResolutionTest$ClassResolutionTestMain$Thing1Handler ClassResolutionTest$ClassResolutionTestMain$Thing1");
+ o.shouldContain("[classresolve] resolve JVM_CONSTANT_MethodHandle");
// (2) classresolve should turn off.
pb = ProcessTools.createJavaProcessBuilder("-Xlog:classresolve=debug",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/CompressedOopsTest.java Thu Apr 14 19:55:39 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8149991
+ * @requires (sun.arch.data.model == "64")
+ * @summary -Xlog:gc+heap+coops=info should have output from the code
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.Platform jdk.test.lib.ProcessTools
+ * @run driver CompressedOopsTest
+ */
+
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.Platform;
+import jdk.test.lib.ProcessTools;
+
+public class CompressedOopsTest {
+ static void analyzeOutputOn(ProcessBuilder pb) throws Exception {
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("[gc,heap,coops] Heap address");
+ output.shouldHaveExitValue(0);
+ }
+
+ static void analyzeOutputOff(ProcessBuilder pb) throws Exception {
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldNotContain("[gc,heap,coops]");
+ output.shouldHaveExitValue(0);
+ }
+
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+ "-Xlog:gc+heap+coops=info",
+ InnerClass.class.getName());
+ analyzeOutputOn(pb);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+ "-XX:+PrintCompressedOopsMode",
+ InnerClass.class.getName());
+ analyzeOutputOn(pb);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+ "-XX:+PrintCompressedOopsMode",
+ "-Xlog:gc+heap+coops=off",
+ InnerClass.class.getName());
+ analyzeOutputOff(pb);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:+UseCompressedOops",
+ "-Xlog:gc+heap+coops=info",
+ "-XX:-PrintCompressedOopsMode",
+ InnerClass.class.getName());
+ analyzeOutputOff(pb);
+ }
+
+ public static class InnerClass {
+ public static void main(String[] args) throws Exception {
+ System.out.println("Compressed Oops (gc+heap+coops) test");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/OsCpuLoggingTest.java Thu Apr 14 19:55:39 2016 -0700
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8151939
+ * @summary os+cpu output should contain some os,cpu information
+ * @library /testlibrary
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @build jdk.test.lib.OutputAnalyzer jdk.test.lib.ProcessTools
+ * @run driver OsCpuLoggingTest
+ */
+
+import java.io.File;
+import java.util.Map;
+import jdk.test.lib.*;
+
+public class OsCpuLoggingTest {
+
+ static void analyzeOutputForOsLog(OutputAnalyzer output) throws Exception {
+ // Aix has it's own logging
+ if (!Platform.isAix()) {
+ output.shouldContain("SafePoint Polling address");
+ }
+ output.shouldHaveExitValue(0);
+ }
+
+ static void analyzeOutputForOsCpuLog(OutputAnalyzer output) throws Exception {
+ output.shouldContain("CPU:total");
+ output.shouldHaveExitValue(0);
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xlog:os+cpu", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ analyzeOutputForOsCpuLog(output);
+
+ pb = ProcessTools.createJavaProcessBuilder("-Xlog:os", "-version");
+ output = new OutputAnalyzer(pb.start());
+ analyzeOutputForOsLog(output);
+ }
+}
--- a/hotspot/test/serviceability/logging/TestLogRotation.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/serviceability/logging/TestLogRotation.java Thu Apr 14 19:55:39 2016 -0700
@@ -102,8 +102,10 @@
smallFilesNumber++;
}
}
- if (logs.length != numberOfFiles) {
- throw new Error("There are only " + logs.length + " logs instead " + numberOfFiles);
+ // Expect one more log file since the number-of-files doesn't include the active log file
+ int expectedNumberOfFiles = numberOfFiles + 1;
+ if (logs.length != expectedNumberOfFiles) {
+ throw new Error("There are " + logs.length + " logs instead of the expected " + expectedNumberOfFiles);
}
if (smallFilesNumber > 1) {
throw new Error("There should maximum one log with size < " + logFileSizeK + "K");
--- a/hotspot/test/serviceability/logging/TestQuotedLogOutputs.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/serviceability/logging/TestQuotedLogOutputs.java Thu Apr 14 19:55:39 2016 -0700
@@ -101,7 +101,7 @@
output.shouldHaveExitValue(1);
// Ensure error message was logged
output.shouldMatch("([Mm]issing terminating quote)"
- + "|(Could not open log file '')"
+ + "|(Error opening log file '')"
+ "|(Output name can not be partially quoted)");
}
}
--- a/hotspot/test/serviceability/sa/DeadlockDetectionTest.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/serviceability/sa/DeadlockDetectionTest.java Thu Apr 14 19:55:39 2016 -0700
@@ -80,6 +80,12 @@
return;
}
+ if (Platform.isOSX()) {
+ // Coredump stackwalking is not implemented for Darwin
+ System.out.println("This test is not expected to work on OS X. Skipping");
+ return;
+ }
+
if (!LingeredApp.isLastModifiedWorking()) {
// Exact behaviour of the test depends on operating system and the test nature,
--- a/hotspot/test/serviceability/tmtools/jstack/JstackThreadTest.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstack/JstackThreadTest.java Thu Apr 14 19:55:39 2016 -0700
@@ -25,6 +25,8 @@
import jdk.test.lib.JDKToolLauncher;
import jdk.test.lib.OutputAnalyzer;
import jdk.test.lib.ProcessTools;
+import utils.Utils;
+import java.util.concurrent.CountDownLatch;
/*
* @test JstackThreadTest
@@ -32,23 +34,22 @@
* @summary jstack doesn't close quotation marks properly with threads' name greater than 1996 characters
* @library /testlibrary
* @build jdk.test.lib.*
- * @ignore 8153319
* @run main JstackThreadTest
*/
public class JstackThreadTest {
static class NamedThread extends Thread {
- NamedThread(String name) {
+ CountDownLatch latch;
+ NamedThread(String name, CountDownLatch latch) {
+ this.latch = latch;
setName(name);
+
}
@Override
public void run() {
- try {
- Thread.sleep(2000);
- } catch(Exception e){
- e.printStackTrace();
- }
- }
+ latch.countDown();
+ Utils.sleep();
}
+ }
public static void main(String[] args) throws Exception {
StringBuilder sb = new StringBuilder();
@@ -60,8 +61,11 @@
}
private static void testWithName(String name) throws Exception {
+ //parent thread countDown latch
+ CountDownLatch latch = new CountDownLatch(1);
// Start a thread with a long thread name
- NamedThread thread = new NamedThread(name);
+ NamedThread thread = new NamedThread(name, latch);
+ thread.setDaemon(true);
thread.start();
ProcessBuilder processBuilder = new ProcessBuilder();
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstack");
@@ -69,6 +73,8 @@
launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
processBuilder.command(launcher.getCommand());
System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", ""));
+ // Ensuring that Jstack will always run after NamedThread
+ latch.await();
OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
System.out.println(output.getOutput());
output.shouldContain("\""+ name + "\"");
--- a/hotspot/test/serviceability/tmtools/jstat/GcCapacityTest.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCapacityTest.java Thu Apr 14 19:55:39 2016 -0700
@@ -27,13 +27,13 @@
* @test
* @summary Test checks the consistency of the output
* displayed with jstat -gccapacity.
- * @ignore 8149778
* @library /test/lib/share/classes
* @library ../share
* @requires vm.opt.ExplicitGCInvokesConcurrent != true
* @build common.*
* @build utils.*
- * @run main/othervm -XX:+UsePerfData GcCapacityTest
+ * @ignore 8149778
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcCapacityTest
*/
public class GcCapacityTest {
--- a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest01.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest01.java Thu Apr 14 19:55:39 2016 -0700
@@ -34,7 +34,7 @@
* @build common.*
* @build utils.*
*
- * @run main/othervm -XX:+UsePerfData GcCauseTest01
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcCauseTest01
*/
import utils.*;
--- a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest02.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest02.java Thu Apr 14 19:55:39 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -32,7 +32,7 @@
* @build common.*
* @build utils.*
*
- * @run main/othervm -XX:+UsePerfData -Xms128M -XX:MaxMetaspaceSize=128M GcCauseTest02
+ * @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcCauseTest02
*/
import utils.*;
--- a/hotspot/test/serviceability/tmtools/jstat/GcCauseTest03.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcCauseTest03.java Thu Apr 14 19:55:39 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -32,7 +32,7 @@
* @build common.*
* @build utils.*
*
- * @run main/othervm -XX:+UsePerfData -Xms128M -XX:MaxMetaspaceSize=128M GcCauseTest03
+ * @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcCauseTest03
*/
import utils.*;
--- a/hotspot/test/serviceability/tmtools/jstat/GcNewTest.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcNewTest.java Thu Apr 14 19:55:39 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -33,7 +33,7 @@
* @library ../share
* @build common.*
* @build utils.*
- * @run main/othervm -XX:+UsePerfData GcNewTest
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcNewTest
*/
public class GcNewTest {
--- a/hotspot/test/serviceability/tmtools/jstat/GcTest01.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcTest01.java Thu Apr 14 19:55:39 2016 -0700
@@ -37,7 +37,7 @@
* @build common.*
* @build utils.*
*
- * @run main/othervm -XX:+UsePerfData GcTest01
+ * @run main/othervm -XX:+UsePerfData -Xmx128M GcTest01
*/
import utils.*;
--- a/hotspot/test/serviceability/tmtools/jstat/GcTest02.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/serviceability/tmtools/jstat/GcTest02.java Thu Apr 14 19:55:39 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -32,7 +32,7 @@
* @library ../share
* @build common.*
* @build utils.*
- * @run main/othervm -XX:+UsePerfData -Xms128M -XX:MaxMetaspaceSize=128M GcTest02
+ * @run main/othervm -XX:+UsePerfData -Xmx128M -XX:MaxMetaspaceSize=128M GcTest02
*/
public class GcTest02 {
@@ -58,10 +58,4 @@
// Assert that space has been utilized acordingly
JstatResults.assertSpaceUtilization(measurement2, targetMemoryUsagePercent);
}
-
- private static void assertThat(boolean result, String message) {
- if (!result) {
- throw new RuntimeException(message);
- };
- }
}
--- a/hotspot/test/testlibrary/jdk/test/lib/OutputAnalyzer.java Thu Apr 14 09:33:16 2016 -0700
+++ b/hotspot/test/testlibrary/jdk/test/lib/OutputAnalyzer.java Thu Apr 14 19:55:39 2016 -0700
@@ -378,14 +378,14 @@
* - exit code
* Note: the command line is printed by the ProcessTools
*/
- private void reportDiagnosticSummary() {
- String msg =
- " stdout: [" + stdout + "];\n" +
- " stderr: [" + stderr + "]\n" +
- " exitValue = " + getExitValue() + "\n";
+ public void reportDiagnosticSummary() {
+ String msg =
+ " stdout: [" + stdout + "];\n" +
+ " stderr: [" + stderr + "]\n" +
+ " exitValue = " + getExitValue() + "\n";
- System.err.println(msg);
- }
+ System.err.println(msg);
+ }
/**