Merge
This commit is contained in:
commit
f2fab8584e
2
.hgtags
2
.hgtags
@ -214,3 +214,5 @@ e517701a4d0e25ae9c7945bca6e1762a8c5d8aa6 jdk8-b88
|
||||
f09ab0c416185e3cba371e81bcb6a16060c90f44 jdk8-b90
|
||||
80b6c3172dc2cfceb022411292d290a967f9c728 jdk8-b91
|
||||
2fd6acba737b01e705e1f7c33588c922a3787f13 jdk8-b92
|
||||
b72ae39e1329fefae50d4690db4fde43f3841a95 jdk8-b93
|
||||
0d804e3b955dce406af6a79ac1cc35c696aff7fb jdk8-b94
|
||||
|
@ -214,3 +214,5 @@ e1a929afcfc492470d50be0b6b0e8dc77d3760b9 jdk8-b88
|
||||
69b773a221b956a3386933ecdbfeccee0edeac47 jdk8-b90
|
||||
cb51fb4789ac0b8be4056482077ddfb8f3bd3805 jdk8-b91
|
||||
3a36c926a7aafa9d4a892a45ef3678e87ad8359b jdk8-b92
|
||||
27c51c6e31c1ef36afa0e6efb031f9b13f26c12b jdk8-b93
|
||||
50d2bde060f2a9bbbe4da0c8986e20aca61f2e2e jdk8-b94
|
||||
|
@ -363,7 +363,11 @@ AC_ARG_WITH([devkit], [AS_HELP_STRING([--with-devkit],
|
||||
AC_MSG_ERROR([Cannot specify both --with-devkit and --with-tools-dir at the same time])
|
||||
fi
|
||||
TOOLS_DIR=$with_devkit/bin
|
||||
SYS_ROOT=$with_devkit/$host_alias/libc
|
||||
if test -d "$with_devkit/$host_alias/libc"; then
|
||||
SYS_ROOT=$with_devkit/$host_alias/libc
|
||||
elif test -d "$with_devkit/$host/sys-root"; then
|
||||
SYS_ROOT=$with_devkit/$host/sys-root
|
||||
fi
|
||||
])
|
||||
|
||||
])
|
||||
|
@ -162,7 +162,12 @@ AC_DEFUN([BPERF_SETUP_CCACHE],
|
||||
[disable using ccache to speed up recompilations @<:@enabled@:>@])],
|
||||
[ENABLE_CCACHE=${enable_ccache}], [ENABLE_CCACHE=yes])
|
||||
if test "x$ENABLE_CCACHE" = xyes; then
|
||||
OLD_PATH="$PATH"
|
||||
if test "x$TOOLS_DIR" != x; then
|
||||
PATH=$TOOLS_DIR:$PATH
|
||||
fi
|
||||
AC_PATH_PROG(CCACHE, ccache)
|
||||
PATH="$OLD_PATH"
|
||||
else
|
||||
AC_MSG_CHECKING([for ccache])
|
||||
AC_MSG_RESULT([explicitly disabled])
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -351,11 +351,7 @@ AC_ARG_WITH(cacerts-file, [AS_HELP_STRING([--with-cacerts-file],
|
||||
if test "x$with_cacerts_file" != x; then
|
||||
CACERTS_FILE=$with_cacerts_file
|
||||
else
|
||||
if test "x$OPENJDK" = "xtrue"; then
|
||||
CACERTS_FILE=${SRC_ROOT}/jdk/src/share/lib/security/cacerts
|
||||
else
|
||||
CACERTS_FILE=${SRC_ROOT}/jdk/src/closed/share/lib/security/cacerts.internal
|
||||
fi
|
||||
CACERTS_FILE=${SRC_ROOT}/jdk/src/share/lib/security/cacerts
|
||||
fi
|
||||
AC_SUBST(CACERTS_FILE)
|
||||
|
||||
|
@ -123,11 +123,17 @@ if test "x$SYS_ROOT" != "x/"; then
|
||||
if test "x$x_includes" = xNONE; then
|
||||
if test -f "$SYS_ROOT/usr/X11R6/include/X11/Xlib.h"; then
|
||||
x_includes="$SYS_ROOT/usr/X11R6/include"
|
||||
elif test -f "$SYS_ROOT/usr/include/X11/Xlib.h"; then
|
||||
x_includes="$SYS_ROOT/usr/include"
|
||||
fi
|
||||
fi
|
||||
if test "x$x_libraries" = xNONE; then
|
||||
if test -f "$SYS_ROOT/usr/X11R6/lib/libX11.so"; then
|
||||
x_libraries="$SYS_ROOT/usr/X11R6/lib"
|
||||
elif test "$SYS_ROOT/usr/lib64/libX11.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
|
||||
x_libraries="$SYS_ROOT/usr/lib64"
|
||||
elif test -f "$SYS_ROOT/usr/lib/libX11.so"; then
|
||||
x_libraries="$SYS_ROOT/usr/lib"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@ -153,8 +159,7 @@ fi
|
||||
if test "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||
if test -d "$SYS_ROOT/usr/X11R6"; then
|
||||
OPENWIN_HOME="$SYS_ROOT/usr/X11R6"
|
||||
fi
|
||||
if test -d "$SYS_ROOT/usr/include/X11"; then
|
||||
elif test -d "$SYS_ROOT/usr/include/X11"; then
|
||||
OPENWIN_HOME="$SYS_ROOT/usr"
|
||||
fi
|
||||
fi
|
||||
@ -359,12 +364,12 @@ else
|
||||
if test "x$FREETYPE2_FOUND" = xno; then
|
||||
AC_MSG_CHECKING([for freetype in some standard locations])
|
||||
|
||||
if test -s /usr/X11/include/ft2build.h && test -d /usr/X11/include/freetype2/freetype; then
|
||||
DEFAULT_FREETYPE_CFLAGS="-I/usr/X11/include/freetype2 -I/usr/X11/include"
|
||||
DEFAULT_FREETYPE_LIBS="-L/usr/X11/lib -lfreetype"
|
||||
if test -s $SYS_ROOT/usr/X11/include/ft2build.h && test -d $SYS_ROOT/usr/X11/include/freetype2/freetype; then
|
||||
DEFAULT_FREETYPE_CFLAGS="-I$SYS_ROOT/usr/X11/include/freetype2 -I$SYS_ROOT/usr/X11/include"
|
||||
DEFAULT_FREETYPE_LIBS="-L$SYS_ROOT/usr/X11/lib -lfreetype"
|
||||
fi
|
||||
if test -s /usr/include/ft2build.h && test -d /usr/include/freetype2/freetype; then
|
||||
DEFAULT_FREETYPE_CFLAGS="-I/usr/include/freetype2"
|
||||
if test -s $SYS_ROOT/usr/include/ft2build.h && test -d $SYS_ROOT/usr/include/freetype2/freetype; then
|
||||
DEFAULT_FREETYPE_CFLAGS="-I$SYS_ROOT/usr/include/freetype2"
|
||||
DEFAULT_FREETYPE_LIBS="-lfreetype"
|
||||
fi
|
||||
|
||||
|
@ -275,6 +275,8 @@ FREETYPE2_LIBS:=@FREETYPE2_LIBS@
|
||||
FREETYPE2_CFLAGS:=@FREETYPE2_CFLAGS@
|
||||
USING_SYSTEM_FT_LIB=@USING_SYSTEM_FT_LIB@
|
||||
CUPS_CFLAGS:=@CUPS_CFLAGS@
|
||||
ALSA_LIBS:=@ALSA_LIBS@
|
||||
ALSA_CFLAGS:=@ALSA_CFLAGS@
|
||||
|
||||
PACKAGE_PATH=@PACKAGE_PATH@
|
||||
|
||||
|
@ -629,7 +629,6 @@ CXX_FLAG_DEPS="-MMD -MF"
|
||||
|
||||
case $COMPILER_TYPE in
|
||||
CC )
|
||||
D_FLAG="-g"
|
||||
case $COMPILER_NAME in
|
||||
gcc )
|
||||
case $OPENJDK_TARGET_OS in
|
||||
@ -644,17 +643,17 @@ case $COMPILER_TYPE in
|
||||
C_O_FLAG_HI="-O3"
|
||||
C_O_FLAG_NORM="-O2"
|
||||
C_O_FLAG_NONE="-O0"
|
||||
CFLAGS_DEBUG_SYMBOLS="-g"
|
||||
CXXFLAGS_DEBUG_SYMBOLS="-g"
|
||||
if test "x$OPENJDK_TARGET_CPU_BITS" = "x64" && test "x$DEBUG_LEVEL" = "xfastdebug"; then
|
||||
CFLAGS_DEBUG_SYMBOLS="-g1"
|
||||
CXXFLAGS_DEBUG_SYMBOLS="-g1"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
CXX_O_FLAG_HI="$C_O_FLAG_HI"
|
||||
CXX_O_FLAG_NORM="$C_O_FLAG_NORM"
|
||||
CXX_O_FLAG_NONE="$C_O_FLAG_NONE"
|
||||
CFLAGS_DEBUG_SYMBOLS="-g"
|
||||
CXXFLAGS_DEBUG_SYMBOLS="-g"
|
||||
if test "x$OPENJDK_TARGET_CPU_BITS" = "x64" && test "x$DEBUG_LEVEL" = "xfastdebug"; then
|
||||
CFLAGS_DEBUG_SYMBOLS="-g1"
|
||||
CXXFLAGS_DEBUG_SYMBOLS="-g1"
|
||||
fi
|
||||
;;
|
||||
ossc )
|
||||
#
|
||||
@ -735,7 +734,6 @@ case $COMPILER_TYPE in
|
||||
esac
|
||||
;;
|
||||
CL )
|
||||
D_FLAG=
|
||||
C_O_FLAG_HIGHEST="-O2"
|
||||
C_O_FLAG_HI="-O1"
|
||||
C_O_FLAG_NORM="-O1"
|
||||
@ -861,6 +859,28 @@ esac
|
||||
|
||||
###############################################################################
|
||||
|
||||
# Adjust flags according to debug level.
|
||||
case $DEBUG_LEVEL in
|
||||
fastdebug )
|
||||
CFLAGS_JDK="$CFLAGS_JDK $CFLAGS_DEBUG_SYMBOLS"
|
||||
CXXFLAGS_JDK="$CXXFLAGS_JDK $CXXFLAGS_DEBUG_SYMBOLS"
|
||||
C_O_FLAG_HI="$C_O_FLAG_NORM"
|
||||
C_O_FLAG_NORM="$C_O_FLAG_NORM"
|
||||
CXX_O_FLAG_HI="$CXX_O_FLAG_NORM"
|
||||
CXX_O_FLAG_NORM="$CXX_O_FLAG_NORM"
|
||||
JAVAC_FLAGS="$JAVAC_FLAGS -g"
|
||||
;;
|
||||
slowdebug )
|
||||
CFLAGS_JDK="$CFLAGS_JDK $CFLAGS_DEBUG_SYMBOLS"
|
||||
CXXFLAGS_JDK="$CXXFLAGS_JDK $CXXFLAGS_DEBUG_SYMBOLS"
|
||||
C_O_FLAG_HI="$C_O_FLAG_NONE"
|
||||
C_O_FLAG_NORM="$C_O_FLAG_NONE"
|
||||
CXX_O_FLAG_HI="$CXX_O_FLAG_NONE"
|
||||
CXX_O_FLAG_NORM="$CXX_O_FLAG_NONE"
|
||||
JAVAC_FLAGS="$JAVAC_FLAGS -g"
|
||||
;;
|
||||
esac
|
||||
|
||||
CCXXFLAGS_JDK="$CCXXFLAGS_JDK $ADD_LP64"
|
||||
|
||||
# The package path is used only on macosx?
|
||||
@ -1004,23 +1024,6 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
# Adjust flags according to debug level.
|
||||
case $DEBUG_LEVEL in
|
||||
fastdebug )
|
||||
CFLAGS="$CFLAGS $D_FLAG"
|
||||
JAVAC_FLAGS="$JAVAC_FLAGS -g"
|
||||
;;
|
||||
slowdebug )
|
||||
CFLAGS="$CFLAGS $D_FLAG"
|
||||
C_O_FLAG_HI="$C_O_FLAG_NONE"
|
||||
C_O_FLAG_NORM="$C_O_FLAG_NONE"
|
||||
CXX_O_FLAG_HI="$CXX_O_FLAG_NONE"
|
||||
CXX_O_FLAG_NORM="$CXX_O_FLAG_NONE"
|
||||
JAVAC_FLAGS="$JAVAC_FLAGS -g"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
AC_SUBST(CFLAGS_JDKLIB)
|
||||
AC_SUBST(CFLAGS_JDKEXE)
|
||||
|
||||
|
@ -91,6 +91,15 @@ AC_DEFUN([TOOLCHAIN_FIND_VISUAL_STUDIO_BAT_FILE],
|
||||
AC_MSG_ERROR([Cannot locate a valid Visual Studio installation])
|
||||
fi
|
||||
|
||||
if test "x$VS100COMNTOOLS" != x; then
|
||||
TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([$VS100COMNTOOLS/../..], [VS100COMNTOOLS variable])
|
||||
fi
|
||||
if test "x$PROGRAMFILES" != x; then
|
||||
TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([$PROGRAMFILES/Microsoft Visual Studio 10.0], [well-known name])
|
||||
fi
|
||||
TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([C:/Program Files/Microsoft Visual Studio 10.0], [well-known name])
|
||||
TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([C:/Program Files (x86)/Microsoft Visual Studio 10.0], [well-known name])
|
||||
|
||||
if test "x$ProgramW6432" != x; then
|
||||
TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([$ProgramW6432/Microsoft SDKs/Windows/v7.1/Bin], [well-known name])
|
||||
fi
|
||||
@ -102,15 +111,6 @@ AC_DEFUN([TOOLCHAIN_FIND_VISUAL_STUDIO_BAT_FILE],
|
||||
fi
|
||||
TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([C:/Program Files/Microsoft SDKs/Windows/v7.1/Bin], [well-known name])
|
||||
TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT([C:/Program Files (x86)/Microsoft SDKs/Windows/v7.1/Bin], [well-known name])
|
||||
|
||||
if test "x$VS100COMNTOOLS" != x; then
|
||||
TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([$VS100COMNTOOLS/../..], [VS100COMNTOOLS variable])
|
||||
fi
|
||||
if test "x$PROGRAMFILES" != x; then
|
||||
TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([$PROGRAMFILES/Microsoft Visual Studio 10.0], [well-known name])
|
||||
fi
|
||||
TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([C:/Program Files/Microsoft Visual Studio 10.0], [well-known name])
|
||||
TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([C:/Program Files (x86)/Microsoft Visual Studio 10.0], [well-known name])
|
||||
])
|
||||
|
||||
# Check if the VS env variables were setup prior to running configure.
|
||||
@ -248,10 +248,23 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV],
|
||||
AC_MSG_NOTICE([Warning: msvcr100.dll not found in VCINSTALLDIR: $VCINSTALLDIR])
|
||||
fi
|
||||
fi
|
||||
# Try some fallback alternatives
|
||||
if test "x$MSVCR_DLL" = x; then
|
||||
if test -f "$SYSTEMROOT/system32/msvcr100.dll"; then
|
||||
AC_MSG_NOTICE([msvcr100.dll found in $SYSTEMROOT/system32])
|
||||
MSVCR_DLL="$SYSTEMROOT/system32/msvcr100.dll"
|
||||
# If visual studio express is installed, there is usually one with the debugger
|
||||
if test "x$VS100COMNTOOLS" != x; then
|
||||
if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
|
||||
MSVCR_DLL=`find "$VS100COMNTOOLS/.." -name msvcr100.dll | grep -i x64 | head --lines 1`
|
||||
AC_MSG_NOTICE([msvcr100.dll found in $VS100COMNTOOLS..: $VS100COMNTOOLS..])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "x$MSVCR_DLL" = x; then
|
||||
if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then
|
||||
# Fallback for 32bit builds, look in the windows directory.
|
||||
if test -f "$SYSTEMROOT/system32/msvcr100.dll"; then
|
||||
AC_MSG_NOTICE([msvcr100.dll found in $SYSTEMROOT/system32])
|
||||
MSVCR_DLL="$SYSTEMROOT/system32/msvcr100.dll"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
@ -108,7 +108,11 @@ define add_native_source
|
||||
# setting -showIncludes, all included files are printed. These are filtered out and
|
||||
# parsed into make dependences.
|
||||
ifeq ($(COMPILER_TYPE),CL)
|
||||
$$($1_$2_COMP) $$($1_$2_FLAGS) -showIncludes $$($1_$2_DEBUG_OUT_FLAGS) $(CC_OUT_OPTION)$$($1_$2_OBJ) $2 | $(TEE) $$($1_$2_DEP).raw | $(GREP) -v "^Note: including file:"
|
||||
($$($1_$2_COMP) $$($1_$2_FLAGS) -showIncludes $$($1_$2_DEBUG_OUT_FLAGS) \
|
||||
$(CC_OUT_OPTION)$$($1_$2_OBJ) $2 ; echo $$$$? > $$($1_$2_DEP).exitvalue) \
|
||||
| $(TEE) $$($1_$2_DEP).raw | $(GREP) -v "^Note: including file:" \
|
||||
&& exit `cat $$($1_$2_DEP).exitvalue`
|
||||
$(RM) $$($1_$2_DEP).exitvalue
|
||||
($(ECHO) $$@: \\ \
|
||||
&& $(SED) -e '/^Note: including file:/!d' \
|
||||
-e 's|Note: including file: *||' \
|
||||
|
123
common/makefiles/devkit/Makefile
Normal file
123
common/makefiles/devkit/Makefile
Normal file
@ -0,0 +1,123 @@
|
||||
#
|
||||
# Copyright (c) 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. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
##########################################################################################
|
||||
#
|
||||
# This Makefile, together with Tools.gmk, can be used to compile a set of
|
||||
# gcc based cross compilation, portable, self contained packages, capable
|
||||
# of building OpenJDK.
|
||||
#
|
||||
# In addition to the makefiles, access to Oracle Linux installation
|
||||
# media is required. This has been tested against Oracle Enterprise Linux
|
||||
# 5.5. Set variables RPM_DIR_x86_64 and RPM_DIR_i686 respectively to point
|
||||
# to directory containing the RPMs.
|
||||
#
|
||||
# By default this Makefile will build crosstools for:
|
||||
# * i686-unknown-linux-gnu
|
||||
# * x86_64-unknown-linux-gnu
|
||||
# The x86_64 version of the compilers will work in multi arch mode and will
|
||||
# be able to compile 32bit binaries with the -m32 flag. This makes the
|
||||
# explicit cross compiler for i686 somewhat redundant and is a known issue.
|
||||
#
|
||||
# To build the full set of crosstools, use a command line looking like this:
|
||||
#
|
||||
# make tars RPM_DIR_x86_64=/tmp/oel55-x86_64/Server/ RPM_DIR_i686=/tmp/oel55-i686/Server/
|
||||
#
|
||||
# To create a x86_64 package without the redundant i686 cross compiler, do
|
||||
# like this:
|
||||
#
|
||||
# make tars platforms=x86_64-unknown-linux-gnu RPM_DIR_x86_64=/tmp/oel55-x86_64/Server/ RPM_DIR_i686=/tmp/oel55-i686/Server/
|
||||
|
||||
#
|
||||
# Main makefile which iterates over all host and target platforms.
|
||||
#
|
||||
|
||||
os := $(shell uname -o)
|
||||
cpu := x86_64
|
||||
#$(shell uname -p)
|
||||
|
||||
#
|
||||
# This wrapper script can handle exactly these platforms
|
||||
#
|
||||
platforms := $(foreach p,x86_64 i686,$(p)-unknown-linux-gnu)
|
||||
#platforms := $(foreach p,x86_64,$(p)-unknown-linux-gnu)
|
||||
|
||||
# Figure out what platform this is building on.
|
||||
me := $(cpu)-$(if $(findstring Linux,$(os)),unknown-linux-gnu)
|
||||
|
||||
$(info Building on platform $(me))
|
||||
|
||||
all compile : $(platforms)
|
||||
|
||||
ifeq (,$(SKIP_ME))
|
||||
$(foreach p,$(filter-out $(me),$(platforms)),$(eval $(p) : $$(me)))
|
||||
endif
|
||||
|
||||
OUTPUT_ROOT = $(abspath ../../../build/devkit)
|
||||
RESULT = $(OUTPUT_ROOT)/result
|
||||
|
||||
submakevars = HOST=$@ BUILD=$(me) \
|
||||
RESULT=$(RESULT) PREFIX=$(RESULT)/$@ \
|
||||
OUTPUT_ROOT=$(OUTPUT_ROOT)
|
||||
$(platforms) :
|
||||
@echo 'Building compilers for $@'
|
||||
@echo 'Targets: $(platforms)'
|
||||
for p in $@ $(filter-out $@,$(platforms)); do \
|
||||
$(MAKE) -f Tools.gmk all $(submakevars) \
|
||||
TARGET=$$p || exit 1 ; \
|
||||
done
|
||||
@echo 'Building ccache program for $@'
|
||||
$(MAKE) -f Tools.gmk ccache $(submakevars) TARGET=$@
|
||||
@echo 'All done"'
|
||||
|
||||
$(foreach a,i686 x86_64,$(eval $(a) : $(filter $(a)%,$(platforms))))
|
||||
|
||||
ia32 : i686
|
||||
today := $(shell date +%Y%m%d)
|
||||
|
||||
|
||||
define Mktar
|
||||
$(1)_tar = $$(RESULT)/sdk-$(1)-$$(today).tar.gz
|
||||
$$($(1)_tar) : PLATFORM = $(1)
|
||||
TARFILES += $$($(1)_tar)
|
||||
$$($(1)_tar) : $(1) $$(shell find $$(RESULT)/$(1))
|
||||
endef
|
||||
|
||||
$(foreach p,$(platforms),$(eval $(call Mktar,$(p))))
|
||||
|
||||
tars : all $(TARFILES)
|
||||
onlytars : $(TARFILES)
|
||||
%.tar.gz :
|
||||
@echo 'Creating compiler package $@'
|
||||
cd $(RESULT)/$(PLATFORM) && tar -czf $@ *
|
||||
touch $@
|
||||
|
||||
clean :
|
||||
rm -rf build result
|
||||
|
||||
FORCE :
|
||||
.PHONY : $(configs) $(platforms)
|
||||
|
||||
|
473
common/makefiles/devkit/Tools.gmk
Normal file
473
common/makefiles/devkit/Tools.gmk
Normal file
@ -0,0 +1,473 @@
|
||||
#
|
||||
# Copyright (c) 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. 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.
|
||||
#
|
||||
|
||||
##########################################################################################
|
||||
#
|
||||
# Workhorse makefile for creating ONE cross compiler
|
||||
# Needs either to be from BUILD -> BUILD OR have
|
||||
# BUILD -> HOST prebuilt
|
||||
#
|
||||
# NOTE: There is a bug here. We don't limit the
|
||||
# PATH when building BUILD -> BUILD, which means that
|
||||
# if you configure after you've once build the BUILD->BUILD
|
||||
# compiler THAT one will be picked up as the compiler for itself.
|
||||
# This is not so great, especially if you did a partial delete
|
||||
# of the target tree.
|
||||
#
|
||||
# Fix this...
|
||||
#
|
||||
|
||||
$(info TARGET=$(TARGET))
|
||||
$(info HOST=$(HOST))
|
||||
$(info BUILD=$(BUILD))
|
||||
|
||||
ARCH := $(word 1,$(subst -, ,$(TARGET)))
|
||||
|
||||
##########################################################################################
|
||||
# Define external dependencies
|
||||
|
||||
# Latest that could be made to work.
|
||||
gcc_ver := gcc-4.7.3
|
||||
binutils_ver := binutils-2.22
|
||||
ccache_ver := ccache-3.1.9
|
||||
mpfr_ver := mpfr-3.0.1
|
||||
gmp_ver := gmp-4.3.2
|
||||
mpc_ver := mpc-1.0.1
|
||||
|
||||
GCC := http://ftp.gnu.org/pub/gnu/gcc/$(gcc_ver)/$(gcc_ver).tar.bz2
|
||||
BINUTILS := http://ftp.gnu.org/pub/gnu/binutils/$(binutils_ver).tar.bz2
|
||||
CCACHE := http://samba.org/ftp/ccache/$(ccache_ver).tar.gz
|
||||
MPFR := http://www.mpfr.org/${mpfr_ver}/${mpfr_ver}.tar.bz2
|
||||
GMP := http://ftp.gnu.org/pub/gnu/gmp/${gmp_ver}.tar.bz2
|
||||
MPC := http://www.multiprecision.org/mpc/download/${mpc_ver}.tar.gz
|
||||
|
||||
# RPMs in OEL5.5
|
||||
RPM_LIST := \
|
||||
kernel-headers \
|
||||
glibc-2 glibc-headers glibc-devel \
|
||||
cups-libs cups-devel \
|
||||
libX11 libX11-devel \
|
||||
xorg-x11-proto-devel \
|
||||
alsa-lib alsa-lib-devel \
|
||||
libXext libXext-devel \
|
||||
libXtst libXtst-devel \
|
||||
libXrender libXrender-devel \
|
||||
freetype freetype-devel \
|
||||
libXt libXt-devel \
|
||||
libSM libSM-devel \
|
||||
libICE libICE-devel \
|
||||
libXi libXi-devel \
|
||||
libXdmcp libXdmcp-devel \
|
||||
libXau libXau-devel \
|
||||
libgcc
|
||||
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
RPM_DIR ?= $(RPM_DIR_x86_64)
|
||||
RPM_ARCHS := x86_64
|
||||
ifeq ($(BUILD),$(HOST))
|
||||
ifeq ($(TARGET),$(HOST))
|
||||
# When building the native compiler for x86_64, enable mixed mode.
|
||||
RPM_ARCHS += i386 i686
|
||||
endif
|
||||
endif
|
||||
else
|
||||
RPM_DIR ?= $(RPM_DIR_i686)
|
||||
RPM_ARCHS := i386 i686
|
||||
endif
|
||||
|
||||
# Sort to remove duplicates
|
||||
RPM_FILE_LIST := $(sort $(foreach a,$(RPM_ARCHS),$(wildcard $(patsubst %,$(RPM_DIR)/%*$a.rpm,$(RPM_LIST)))))
|
||||
|
||||
ifeq ($(RPM_FILE_LIST),)
|
||||
$(error Found no RPMs, RPM_DIR must point to list of directories to search for RPMs)
|
||||
endif
|
||||
|
||||
##########################################################################################
|
||||
# Define common directories and files
|
||||
|
||||
# Ensure we have 32-bit libs also for x64. We enable mixed-mode.
|
||||
ifeq (x86_64,$(ARCH))
|
||||
LIBDIRS := lib64 lib
|
||||
CFLAGS_lib := -m32
|
||||
else
|
||||
LIBDIRS := lib
|
||||
endif
|
||||
|
||||
# Define directories
|
||||
RESULT := $(OUTPUT_ROOT)/result
|
||||
BUILDDIR := $(OUTPUT_ROOT)/$(HOST)/$(TARGET)
|
||||
PREFIX := $(RESULT)/$(HOST)
|
||||
TARGETDIR := $(PREFIX)/$(TARGET)
|
||||
SYSROOT := $(TARGETDIR)/sys-root
|
||||
DOWNLOAD := $(OUTPUT_ROOT)/download
|
||||
SRCDIR := $(OUTPUT_ROOT)/src
|
||||
|
||||
# Marker file for unpacking rpms
|
||||
rpms := $(SYSROOT)/rpms_unpacked
|
||||
|
||||
# Need to patch libs that are linker scripts to use non-absolute paths
|
||||
libs := $(SYSROOT)/libs_patched
|
||||
|
||||
##########################################################################################
|
||||
# Unpack source packages
|
||||
|
||||
# Generate downloading + unpacking of sources.
|
||||
define Download
|
||||
$(1)_DIR = $(abspath $(SRCDIR)/$(basename $(basename $(notdir $($(1))))))
|
||||
$(1)_CFG = $$($(1)_DIR)/configure
|
||||
$(1)_FILE = $(DOWNLOAD)/$(notdir $($(1)))
|
||||
|
||||
$$($(1)_CFG) : $$($(1)_FILE)
|
||||
mkdir -p $$(SRCDIR)
|
||||
tar -C $$(SRCDIR) -x$$(if $$(findstring .gz, $$<),z,j)f $$<
|
||||
$$(foreach p,$$(abspath $$(wildcard $$(notdir $$($(1)_DIR)).patch)), \
|
||||
echo PATCHING $$(p) ; \
|
||||
patch -d $$($(1)_DIR) -p1 -i $$(p) ; \
|
||||
)
|
||||
touch $$@
|
||||
|
||||
$$($(1)_FILE) :
|
||||
wget -P $(DOWNLOAD) $$($(1))
|
||||
endef
|
||||
|
||||
# Download and unpack all source packages
|
||||
$(foreach p,GCC BINUTILS CCACHE MPFR GMP MPC,$(eval $(call Download,$(p))))
|
||||
|
||||
##########################################################################################
|
||||
# Unpack RPMS
|
||||
|
||||
# Note. For building linux you should install rpm2cpio.
|
||||
define unrpm
|
||||
$(SYSROOT)/$(notdir $(1)).unpacked \
|
||||
: $(1)
|
||||
$$(rpms) : $(SYSROOT)/$(notdir $(1)).unpacked
|
||||
endef
|
||||
|
||||
%.unpacked :
|
||||
$(info Unpacking target rpms and libraries from $<)
|
||||
@(mkdir -p $(@D); \
|
||||
cd $(@D); \
|
||||
rpm2cpio $< | \
|
||||
cpio --extract --make-directories \
|
||||
-f \
|
||||
"./usr/share/doc/*" \
|
||||
"./usr/share/man/*" \
|
||||
"./usr/X11R6/man/*" \
|
||||
"*/X11/locale/*" \
|
||||
|| die ; )
|
||||
touch $@
|
||||
|
||||
$(foreach p,$(RPM_FILE_LIST),$(eval $(call unrpm,$(p))))
|
||||
|
||||
##########################################################################################
|
||||
|
||||
# Note: MUST create a <sys-root>/usr/lib even if not really needed.
|
||||
# gcc will use a path relative to it to resolve lib64. (x86_64).
|
||||
# we're creating multi-lib compiler with 32bit libc as well, so we should
|
||||
# have it anyway, but just to make sure...
|
||||
# Patch libc.so and libpthread.so to force linking against libraries in sysroot
|
||||
# and not the ones installed on the build machine.
|
||||
$(libs) : $(rpms)
|
||||
@echo Patching libc and pthreads
|
||||
@(for f in `find $(SYSROOT) -name libc.so -o -name libpthread.so`; do \
|
||||
(cat $$f | sed -e 's|/usr/lib64/||g' \
|
||||
-e 's|/usr/lib/||g' \
|
||||
-e 's|/lib64/||g' \
|
||||
-e 's|/lib/||g' ) > $$f.tmp ; \
|
||||
mv $$f.tmp $$f ; \
|
||||
done)
|
||||
@mkdir -p $(SYSROOT)/usr/lib
|
||||
@touch $@
|
||||
|
||||
##########################################################################################
|
||||
|
||||
# Define marker files for each source package to be compiled
|
||||
$(foreach t,binutils mpfr gmp mpc gcc ccache,$(eval $(t) = $(TARGETDIR)/$($(t)_ver).done))
|
||||
|
||||
##########################################################################################
|
||||
|
||||
# Default base config
|
||||
CONFIG = --target=$(TARGET) \
|
||||
--host=$(HOST) --build=$(BUILD) \
|
||||
--prefix=$(PREFIX)
|
||||
|
||||
PATHEXT = $(RESULT)/$(BUILD)/bin:
|
||||
|
||||
PATHPRE = PATH=$(PATHEXT)$(PATH)
|
||||
BUILDPAR = -j16
|
||||
|
||||
# Default commands to when making
|
||||
MAKECMD =
|
||||
INSTALLCMD = install
|
||||
|
||||
|
||||
declare_tools = CC$(1)=$(2)gcc LD$(1)=$(2)ld AR$(1)=$(2)ar AS$(1)=$(2)as RANLIB$(1)=$(2)ranlib CXX$(1)=$(2)g++ OBJDUMP$(1)=$(2)objdump
|
||||
|
||||
ifeq ($(HOST),$(BUILD))
|
||||
ifeq ($(HOST),$(TARGET))
|
||||
TOOLS = $(call declare_tools,_FOR_TARGET,)
|
||||
endif
|
||||
endif
|
||||
|
||||
TOOLS ?= $(call declare_tools,_FOR_TARGET,$(TARGET)-)
|
||||
|
||||
##########################################################################################
|
||||
|
||||
# Create a TARGET bfd + libiberty only.
|
||||
# Configure one or two times depending on mulitlib arch.
|
||||
# If multilib, the second should be 32-bit, and we resolve
|
||||
# CFLAG_<name> to most likely -m32.
|
||||
define mk_bfd
|
||||
$$(info Libs for $(1))
|
||||
$$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile \
|
||||
: CFLAGS += $$(CFLAGS_$(1))
|
||||
$$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile \
|
||||
: LIBDIRS = --libdir=$(TARGETDIR)/$(1)
|
||||
|
||||
bfdlib += $$(TARGETDIR)/$$(binutils_ver)-$(subst /,-,$(1)).done
|
||||
bfdmakes += $$(BUILDDIR)/$$(binutils_ver)-$(subst /,-,$(1))/Makefile
|
||||
endef
|
||||
|
||||
# Create one set of bfds etc for each multilib arch
|
||||
$(foreach l,$(LIBDIRS),$(eval $(call mk_bfd,$(l))))
|
||||
|
||||
# Only build these two libs.
|
||||
$(bfdlib) : MAKECMD = all-libiberty all-bfd
|
||||
$(bfdlib) : INSTALLCMD = install-libiberty install-bfd
|
||||
|
||||
# Building targets libbfd + libiberty. HOST==TARGET, i.e not
|
||||
# for a cross env.
|
||||
$(bfdmakes) : CONFIG = --target=$(TARGET) \
|
||||
--host=$(TARGET) --build=$(BUILD) \
|
||||
--prefix=$(TARGETDIR) \
|
||||
--with-sysroot=$(SYSROOT) \
|
||||
$(LIBDIRS)
|
||||
|
||||
$(bfdmakes) : TOOLS = $(call declare_tools,_FOR_TARGET,$(TARGET)-) $(call declare_tools,,$(TARGET)-)
|
||||
|
||||
##########################################################################################
|
||||
|
||||
$(gcc) \
|
||||
$(binutils) \
|
||||
$(gmp) \
|
||||
$(mpfr) \
|
||||
$(mpc) \
|
||||
$(bfdmakes) \
|
||||
$(ccache) : ENVS += $(TOOLS)
|
||||
|
||||
# libdir to work around hateful bfd stuff installing into wrong dirs...
|
||||
# ensure we have 64 bit bfd support in the HOST library. I.e our
|
||||
# compiler on i686 will know 64 bit symbols, BUT later
|
||||
# we build just the libs again for TARGET, then with whatever the arch
|
||||
# wants.
|
||||
$(BUILDDIR)/$(binutils_ver)/Makefile : CONFIG += --enable-64-bit-bfd --libdir=$(PREFIX)/$(word 1,$(LIBDIRS))
|
||||
|
||||
# Makefile creation. Simply run configure in build dir.
|
||||
$(bfdmakes) \
|
||||
$(BUILDDIR)/$(binutils_ver)/Makefile \
|
||||
: $(BINUTILS_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
@mkdir -p $(@D)
|
||||
( \
|
||||
cd $(@D) ; \
|
||||
$(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
|
||||
$(BINUTILS_CFG) \
|
||||
$(CONFIG) \
|
||||
--with-sysroot=$(SYSROOT) \
|
||||
--disable-nls \
|
||||
--program-prefix=$(TARGET)- \
|
||||
--enable-multilib \
|
||||
) > $(@D)/log.config 2>&1
|
||||
@echo 'done'
|
||||
|
||||
$(BUILDDIR)/$(mpfr_ver)/Makefile \
|
||||
: $(MPFR_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
@mkdir -p $(@D)
|
||||
( \
|
||||
cd $(@D) ; \
|
||||
$(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
|
||||
$(MPFR_CFG) \
|
||||
$(CONFIG) \
|
||||
--program-prefix=$(TARGET)- \
|
||||
--enable-shared=no \
|
||||
--with-gmp=$(PREFIX) \
|
||||
) > $(@D)/log.config 2>&1
|
||||
@echo 'done'
|
||||
|
||||
$(BUILDDIR)/$(gmp_ver)/Makefile \
|
||||
: $(GMP_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
@mkdir -p $(@D)
|
||||
( \
|
||||
cd $(@D) ; \
|
||||
$(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
|
||||
$(GMP_CFG) \
|
||||
--host=$(HOST) --build=$(BUILD) \
|
||||
--prefix=$(PREFIX) \
|
||||
--disable-nls \
|
||||
--program-prefix=$(TARGET)- \
|
||||
--enable-shared=no \
|
||||
--with-mpfr=$(PREFIX) \
|
||||
) > $(@D)/log.config 2>&1
|
||||
@echo 'done'
|
||||
|
||||
$(BUILDDIR)/$(mpc_ver)/Makefile \
|
||||
: $(MPC_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
@mkdir -p $(@D)
|
||||
( \
|
||||
cd $(@D) ; \
|
||||
$(PATHPRE) $(ENVS) CFLAGS="$(CFLAGS)" \
|
||||
$(MPC_CFG) \
|
||||
$(CONFIG) \
|
||||
--program-prefix=$(TARGET)- \
|
||||
--enable-shared=no \
|
||||
--with-mpfr=$(PREFIX) \
|
||||
--with-gmp=$(PREFIX) \
|
||||
) > $(@D)/log.config 2>&1
|
||||
@echo 'done'
|
||||
|
||||
# Only valid if glibc target -> linux
|
||||
# proper destructor handling for c++
|
||||
ifneq (,$(findstring linux,$(TARGET)))
|
||||
$(BUILDDIR)/$(gcc_ver)/Makefile : CONFIG += --enable-__cxa_atexit
|
||||
endif
|
||||
|
||||
# Want:
|
||||
# c,c++
|
||||
# shared libs
|
||||
# multilib (-m32/-m64 on x64)
|
||||
# skip native language.
|
||||
# and link and assemble with the binutils we created
|
||||
# earlier, so --with-gnu*
|
||||
$(BUILDDIR)/$(gcc_ver)/Makefile \
|
||||
: $(GCC_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
mkdir -p $(@D)
|
||||
( \
|
||||
cd $(@D) ; \
|
||||
$(PATHPRE) $(ENVS) $(GCC_CFG) $(EXTRA_CFLAGS) \
|
||||
$(CONFIG) \
|
||||
--with-sysroot=$(SYSROOT) \
|
||||
--enable-languages=c,c++ \
|
||||
--enable-shared \
|
||||
--enable-multilib \
|
||||
--disable-nls \
|
||||
--with-gnu-as \
|
||||
--with-gnu-ld \
|
||||
--with-mpfr=$(PREFIX) \
|
||||
--with-gmp=$(PREFIX) \
|
||||
--with-mpc=$(PREFIX) \
|
||||
) > $(@D)/log.config 2>&1
|
||||
@echo 'done'
|
||||
|
||||
# need binutils for gcc
|
||||
$(gcc) : $(binutils)
|
||||
|
||||
# as of 4.3 or so need these for doing config
|
||||
$(BUILDDIR)/$(gcc_ver)/Makefile : $(gmp) $(mpfr) $(mpc)
|
||||
$(mpfr) : $(gmp)
|
||||
$(mpc) : $(gmp) $(mpfr)
|
||||
|
||||
##########################################################################################
|
||||
# very straightforward. just build a ccache. it is only for host.
|
||||
$(BUILDDIR)/$(ccache_ver)/Makefile \
|
||||
: $(CCACHE_CFG)
|
||||
$(info Configuring $@. Log in $(@D)/log.config)
|
||||
@mkdir -p $(@D)
|
||||
@( \
|
||||
cd $(@D) ; \
|
||||
$(PATHPRE) $(ENVS) $(CCACHE_CFG) \
|
||||
$(CONFIG) \
|
||||
) > $(@D)/log.config 2>&1
|
||||
@echo 'done'
|
||||
|
||||
gccpatch = $(TARGETDIR)/gcc-patched
|
||||
|
||||
##########################################################################################
|
||||
# For some reason cpp is not created as a target-compiler
|
||||
ifeq ($(HOST),$(TARGET))
|
||||
$(gccpatch) : $(gcc) link_libs
|
||||
@echo -n 'Creating compiler symlinks...'
|
||||
@for f in cpp; do \
|
||||
if [ ! -e $(PREFIX)/bin/$(TARGET)-$$f ];\
|
||||
then \
|
||||
cd $(PREFIX)/bin && \
|
||||
ln -s $$f $(TARGET)-$$f ; \
|
||||
fi \
|
||||
done
|
||||
@touch $@
|
||||
@echo 'done'
|
||||
|
||||
##########################################################################################
|
||||
# Ugly at best. Seems that when we compile host->host compiler, that are NOT
|
||||
# the BUILD compiler, the result will not try searching for libs in package root.
|
||||
# "Solve" this by create links from the target libdirs to where they are.
|
||||
link_libs:
|
||||
@echo -n 'Creating library symlinks...'
|
||||
@$(foreach l,$(LIBDIRS), \
|
||||
for f in `cd $(PREFIX)/$(l) && ls`; do \
|
||||
if [ ! -e $(TARGETDIR)/$(l)/$$f ]; then \
|
||||
mkdir -p $(TARGETDIR)/$(l) && \
|
||||
cd $(TARGETDIR)/$(l)/ && \
|
||||
ln -s $(if $(findstring /,$(l)),../,)../../$(l)/$$f $$f; \
|
||||
fi \
|
||||
done;)
|
||||
@echo 'done'
|
||||
else
|
||||
$(gccpatch) :
|
||||
@echo 'done'
|
||||
endif
|
||||
|
||||
##########################################################################################
|
||||
# Build in two steps.
|
||||
# make <default>
|
||||
# make install.
|
||||
# Use path to our build hosts cross tools
|
||||
# Always need to build cross tools for build host self.
|
||||
$(TARGETDIR)/%.done : $(BUILDDIR)/%/Makefile
|
||||
$(info Building $(basename $@). Log in $(<D)/log.build)
|
||||
$(PATHPRE) $(ENVS) $(MAKE) $(BUILDPAR) -f $< -C $(<D) $(MAKECMD) $(MAKECMD.$(notdir $@)) > $(<D)/log.build 2>&1
|
||||
@echo -n 'installing...'
|
||||
$(PATHPRE) $(MAKE) $(INSTALLPAR) -f $< -C $(<D) $(INSTALLCMD) $(MAKECMD.$(notdir $@)) > $(<D)/log.install 2>&1
|
||||
@touch $@
|
||||
@echo 'done'
|
||||
|
||||
##########################################################################################
|
||||
|
||||
bfdlib : $(bfdlib)
|
||||
binutils : $(binutils)
|
||||
rpms : $(rpms)
|
||||
libs : $(libs)
|
||||
sysroot : rpms libs
|
||||
gcc : sysroot $(gcc) $(gccpatch)
|
||||
all : binutils gcc bfdlib
|
||||
|
||||
# this is only built for host. so separate.
|
||||
ccache : $(ccache)
|
||||
|
||||
.PHONY : gcc all binutils bfdlib link_libs rpms libs sysroot
|
@ -214,3 +214,5 @@ fe4150590ee597f4e125fea950aa3b352622cc2d jdk8-b89
|
||||
c8286839d0df04aba819ec4bef12b86babccf30e jdk8-b90
|
||||
8f7ffb296385f85a4a6d53f9f2d4a7b13a8fa1ff jdk8-b91
|
||||
717aa26f8e0a1c0e768aebb3a763aca56db0c83e jdk8-b92
|
||||
8dc9d7ccbb2d77fd89bc321bb02e67c152aca257 jdk8-b93
|
||||
22f5d7f261d9d61a953d2d9a53f2e9ce0ca361d1 jdk8-b94
|
||||
|
@ -346,3 +346,8 @@ b19517cecc2e91636d7c16ba2f35e3d3dc628099 hs25-b33
|
||||
7cbdf0e3725c0c56a2ff7540fc70b6d4b5890d04 jdk8-b91
|
||||
38da9f4f67096745f851318d792d6468aa1f6cf8 hs25-b34
|
||||
092018493d3bbeb1c24278fd8c40ff3d76e1fed7 jdk8-b92
|
||||
573d86d412cd9d3df7912194c1a540be50e9544e jdk8-b93
|
||||
b786c04b7be15194febe88dc1f0c9443e737a84b hs25-b35
|
||||
3c78a14da19d26d6937af5f98b97e2a21c653b04 hs25-b36
|
||||
1beed1f6f9edefe47ba8ed1355fbd3e7606b8288 jdk8-b94
|
||||
69689078dff8b21e6df30870464f5d736eebdf72 hs25-b37
|
||||
|
@ -96,9 +96,10 @@ public class DictionaryEntry extends sun.jvm.hotspot.utilities.HashtableEntry {
|
||||
|
||||
public boolean containsProtectionDomain(Oop protectionDomain) {
|
||||
InstanceKlass ik = (InstanceKlass) klass();
|
||||
if (protectionDomain.equals(ik.getProtectionDomain())) {
|
||||
return true; // Succeeds trivially
|
||||
}
|
||||
// Currently unimplemented and not used.
|
||||
// if (protectionDomain.equals(ik.getJavaMirror().getProtectionDomain())) {
|
||||
// return true; // Succeeds trivially
|
||||
// }
|
||||
for (ProtectionDomainEntry current = pdSet(); current != null;
|
||||
current = current.next()) {
|
||||
if (protectionDomain.equals(current.protectionDomain())) {
|
||||
|
@ -75,8 +75,6 @@ public class InstanceKlass extends Klass {
|
||||
javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
|
||||
constants = new MetadataField(type.getAddressField("_constants"), 0);
|
||||
classLoaderData = type.getAddressField("_class_loader_data");
|
||||
protectionDomain = new OopField(type.getOopField("_protection_domain"), 0);
|
||||
signers = new OopField(type.getOopField("_signers"), 0);
|
||||
sourceFileName = type.getAddressField("_source_file_name");
|
||||
sourceDebugExtension = type.getAddressField("_source_debug_extension");
|
||||
innerClasses = type.getAddressField("_inner_classes");
|
||||
@ -136,8 +134,6 @@ public class InstanceKlass extends Klass {
|
||||
private static CIntField javaFieldsCount;
|
||||
private static MetadataField constants;
|
||||
private static AddressField classLoaderData;
|
||||
private static OopField protectionDomain;
|
||||
private static OopField signers;
|
||||
private static AddressField sourceFileName;
|
||||
private static AddressField sourceDebugExtension;
|
||||
private static AddressField innerClasses;
|
||||
@ -350,8 +346,6 @@ public class InstanceKlass extends Klass {
|
||||
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
|
||||
public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
|
||||
public Oop getClassLoader() { return getClassLoaderData().getClassLoader(); }
|
||||
public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
|
||||
public ObjArray getSigners() { return (ObjArray) signers.getValue(this); }
|
||||
public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
|
||||
public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getAddress())); }
|
||||
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
|
||||
@ -541,8 +535,6 @@ public class InstanceKlass extends Klass {
|
||||
// visitor.doOop(methods, true);
|
||||
// visitor.doOop(localInterfaces, true);
|
||||
// visitor.doOop(transitiveInterfaces, true);
|
||||
visitor.doOop(protectionDomain, true);
|
||||
visitor.doOop(signers, true);
|
||||
visitor.doCInt(nonstaticFieldSize, true);
|
||||
visitor.doCInt(staticFieldSize, true);
|
||||
visitor.doCInt(staticOopFieldCount, true);
|
||||
|
@ -204,13 +204,13 @@ public class HeapGXLWriter extends AbstractHeapGraphWriter {
|
||||
Oop loader = ik.getClassLoader();
|
||||
writeEdge(instance, loader, "loaded-by");
|
||||
|
||||
// write signers
|
||||
Oop signers = ik.getSigners();
|
||||
writeEdge(instance, signers, "signed-by");
|
||||
// write signers NYI
|
||||
// Oop signers = ik.getJavaMirror().getSigners();
|
||||
writeEdge(instance, null, "signed-by");
|
||||
|
||||
// write protection domain
|
||||
Oop protectionDomain = ik.getProtectionDomain();
|
||||
writeEdge(instance, protectionDomain, "protection-domain");
|
||||
// write protection domain NYI
|
||||
// Oop protectionDomain = ik.getJavaMirror().getProtectionDomain();
|
||||
writeEdge(instance, null, "protection-domain");
|
||||
|
||||
// write edges for static reference fields from this class
|
||||
for (Iterator itr = refFields.iterator(); itr.hasNext();) {
|
||||
|
@ -477,8 +477,8 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
if (k instanceof InstanceKlass) {
|
||||
InstanceKlass ik = (InstanceKlass) k;
|
||||
writeObjectID(ik.getClassLoader());
|
||||
writeObjectID(ik.getSigners());
|
||||
writeObjectID(ik.getProtectionDomain());
|
||||
writeObjectID(null); // ik.getJavaMirror().getSigners());
|
||||
writeObjectID(null); // ik.getJavaMirror().getProtectionDomain());
|
||||
// two reserved id fields
|
||||
writeObjectID(null);
|
||||
writeObjectID(null);
|
||||
@ -516,8 +516,8 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
|
||||
if (bottomKlass instanceof InstanceKlass) {
|
||||
InstanceKlass ik = (InstanceKlass) bottomKlass;
|
||||
writeObjectID(ik.getClassLoader());
|
||||
writeObjectID(ik.getSigners());
|
||||
writeObjectID(ik.getProtectionDomain());
|
||||
writeObjectID(null); // ik.getJavaMirror().getSigners());
|
||||
writeObjectID(null); // ik.getJavaMirror().getProtectionDomain());
|
||||
} else {
|
||||
writeObjectID(null);
|
||||
writeObjectID(null);
|
||||
|
@ -47,8 +47,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
|
||||
private static final int FIELD_IS_SYNTHETIC = 13;
|
||||
private static final int FIELD_IS_INTERFACE = 14;
|
||||
private static final int FIELD_CLASS_LOADER = 15;
|
||||
private static final int FIELD_PROTECTION_DOMAIN = 16;
|
||||
private static final int FIELD_SIGNERS = 17;
|
||||
private static final int FIELD_STATICS = 18;
|
||||
private static final int FIELD_UNDEFINED = -1;
|
||||
|
||||
@ -100,10 +98,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
|
||||
return Boolean.valueOf(ik.isInterface());
|
||||
case FIELD_CLASS_LOADER:
|
||||
return factory.newJSJavaObject(ik.getClassLoader());
|
||||
case FIELD_PROTECTION_DOMAIN:
|
||||
return factory.newJSJavaObject(ik.getProtectionDomain());
|
||||
case FIELD_SIGNERS:
|
||||
return factory.newJSJavaObject(ik.getSigners());
|
||||
case FIELD_STATICS:
|
||||
return getStatics();
|
||||
case FIELD_UNDEFINED:
|
||||
@ -246,8 +240,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
|
||||
addField("isSynthetic", FIELD_IS_SYNTHETIC);
|
||||
addField("isInterface", FIELD_IS_INTERFACE);
|
||||
addField("classLoader", FIELD_CLASS_LOADER);
|
||||
addField("protectionDomain", FIELD_PROTECTION_DOMAIN);
|
||||
addField("signers", FIELD_SIGNERS);
|
||||
addField("statics", FIELD_STATICS);
|
||||
}
|
||||
|
||||
|
@ -486,7 +486,7 @@ $(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/services/%
|
||||
JFR_EXISTS=$(shell if [ -d $(HS_ALT_SRC) ]; then echo 1; else echo 0; fi)
|
||||
# export jfr.h
|
||||
ifeq ($JFR_EXISTS,1)
|
||||
$(EXPORT_INCLUDE_DIR)/%: $(HS_ALT_SRC)/share/vm/jfr/agent/%
|
||||
$(EXPORT_INCLUDE_DIR)/%: $(HS_ALT_SRC)/share/vm/jfr/%
|
||||
$(install-file)
|
||||
else
|
||||
$(EXPORT_INCLUDE_DIR)/jfr.h:
|
||||
|
@ -69,7 +69,7 @@ CXXFLAGS += -DASSERT
|
||||
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
|
||||
# Compiler warnings are treated as errors
|
||||
ifneq ($(COMPILER_WARNINGS_FATAL),false)
|
||||
CFLAGS_WARN = -Werror
|
||||
CFLAGS_WARN = $(WARNINGS_ARE_ERRORS)
|
||||
endif
|
||||
CFLAGS += $(CFLAGS_WARN)
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
# flags.make - with macro settings
|
||||
# vm.make - to support making "$(MAKE) -v vm.make" in makefiles
|
||||
# adlc.make -
|
||||
# trace.make - generate tracing event and type definitions
|
||||
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
|
||||
# sa.make - generate SA jar file and natives
|
||||
#
|
||||
@ -119,6 +120,7 @@ SIMPLE_DIRS = \
|
||||
$(PLATFORM_DIR)/generated/dependencies \
|
||||
$(PLATFORM_DIR)/generated/adfiles \
|
||||
$(PLATFORM_DIR)/generated/jvmtifiles \
|
||||
$(PLATFORM_DIR)/generated/tracefiles \
|
||||
$(PLATFORM_DIR)/generated/dtracefiles
|
||||
|
||||
TARGETS = debug fastdebug optimized product
|
||||
@ -128,7 +130,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
|
||||
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
|
||||
|
||||
# dtrace.make is used on BSD versions that implement Dtrace (like MacOS X)
|
||||
BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make dtrace.make
|
||||
BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make trace.make sa.make dtrace.make
|
||||
|
||||
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
|
||||
SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
|
||||
@ -331,6 +333,16 @@ jvmti.make: $(BUILDTREE_MAKE)
|
||||
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
|
||||
) > $@
|
||||
|
||||
trace.make: $(BUILDTREE_MAKE)
|
||||
@echo Creating $@ ...
|
||||
$(QUIETLY) ( \
|
||||
$(BUILDTREE_COMMENT); \
|
||||
echo; \
|
||||
echo include flags.make; \
|
||||
echo; \
|
||||
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
|
||||
) > $@
|
||||
|
||||
sa.make: $(BUILDTREE_MAKE)
|
||||
@echo Creating $@ ...
|
||||
$(QUIETLY) ( \
|
||||
|
@ -71,6 +71,11 @@ ifeq ($(SPEC),)
|
||||
CC = $(CC32)
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CLANG), true)
|
||||
CXX = clang++
|
||||
CC = clang
|
||||
endif
|
||||
|
||||
HOSTCXX = $(CXX)
|
||||
HOSTCC = $(CC)
|
||||
endif
|
||||
@ -79,21 +84,79 @@ ifeq ($(SPEC),)
|
||||
endif
|
||||
|
||||
|
||||
# -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
|
||||
# prints the numbers (e.g. "2.95", "3.2.1")
|
||||
CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1)
|
||||
CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2)
|
||||
|
||||
# check for precompiled headers support
|
||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 4 \) \))" "0"
|
||||
# Allow the user to turn off precompiled headers from the command line.
|
||||
ifneq ($(USE_PRECOMPILED_HEADER),0)
|
||||
PRECOMPILED_HEADER_DIR=.
|
||||
PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
|
||||
PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch
|
||||
endif
|
||||
ifeq ($(USE_CLANG), true)
|
||||
CC_VER_MAJOR := $(shell $(CC) -v 2>&1 | grep version | sed "s/.*version \([0-9]*\.[0-9]*\).*/\1/" | cut -d'.' -f1)
|
||||
CC_VER_MINOR := $(shell $(CC) -v 2>&1 | grep version | sed "s/.*version \([0-9]*\.[0-9]*\).*/\1/" | cut -d'.' -f2)
|
||||
else
|
||||
# -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
|
||||
# prints the numbers (e.g. "2.95", "3.2.1")
|
||||
CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1)
|
||||
CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2)
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CLANG), true)
|
||||
# clang has precompiled headers support by default, but the user can switch
|
||||
# it off by using 'USE_PRECOMPILED_HEADER=0'.
|
||||
ifdef LP64
|
||||
ifeq ($(USE_PRECOMPILED_HEADER),)
|
||||
USE_PRECOMPILED_HEADER=1
|
||||
endif
|
||||
else
|
||||
# We don't support precompiled headers on 32-bit builds because there some files are
|
||||
# compiled with -fPIC while others are compiled without (see 'NONPIC_OBJ_FILES' rules.make)
|
||||
# Clang produces an error if the PCH file was compiled with other options than the actual compilation unit.
|
||||
USE_PRECOMPILED_HEADER=0
|
||||
endif
|
||||
|
||||
ifeq ($(USE_PRECOMPILED_HEADER),1)
|
||||
|
||||
ifndef LP64
|
||||
$(error " Precompiled Headers only supported on 64-bit platforms!")
|
||||
endif
|
||||
|
||||
PRECOMPILED_HEADER_DIR=.
|
||||
PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
|
||||
PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.pch
|
||||
|
||||
PCH_FLAG = -include precompiled.hpp
|
||||
PCH_FLAG/DEFAULT = $(PCH_FLAG)
|
||||
PCH_FLAG/NO_PCH = -DNO_PCH
|
||||
PCH_FLAG/BY_FILE = $(PCH_FLAG/$@)$(PCH_FLAG/DEFAULT$(PCH_FLAG/$@))
|
||||
|
||||
VM_PCH_FLAG/LIBJVM = $(PCH_FLAG/BY_FILE)
|
||||
VM_PCH_FLAG/AOUT =
|
||||
VM_PCH_FLAG = $(VM_PCH_FLAG/$(LINK_INTO))
|
||||
|
||||
# We only use precompiled headers for the JVM build
|
||||
CFLAGS += $(VM_PCH_FLAG)
|
||||
|
||||
# There are some files which don't like precompiled headers
|
||||
# The following files are build with 'OPT_CFLAGS/NOOPT' (-O0) in the opt build.
|
||||
# But Clang doesn't support a precompiled header which was compiled with -O3
|
||||
# to be used in a compilation unit which uses '-O0'. We could also prepare an
|
||||
# extra '-O0' PCH file for the opt build and use it here, but it's probably
|
||||
# not worth the effort as long as only two files need this special handling.
|
||||
PCH_FLAG/loopTransform.o = $(PCH_FLAG/NO_PCH)
|
||||
PCH_FLAG/sharedRuntimeTrig.o = $(PCH_FLAG/NO_PCH)
|
||||
PCH_FLAG/sharedRuntimeTrans.o = $(PCH_FLAG/NO_PCH)
|
||||
|
||||
endif
|
||||
else # ($(USE_CLANG), true)
|
||||
# check for precompiled headers support
|
||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 4 \) \))" "0"
|
||||
# Allow the user to turn off precompiled headers from the command line.
|
||||
ifneq ($(USE_PRECOMPILED_HEADER),0)
|
||||
PRECOMPILED_HEADER_DIR=.
|
||||
PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
|
||||
PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
|
||||
ifeq ($(USE_PRECOMPILED_HEADER),0)
|
||||
CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
|
||||
endif
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# Compiler flags
|
||||
@ -115,17 +178,31 @@ endif
|
||||
CFLAGS += $(VM_PICFLAG)
|
||||
CFLAGS += -fno-rtti
|
||||
CFLAGS += -fno-exceptions
|
||||
CFLAGS += -pthread
|
||||
CFLAGS += -fcheck-new
|
||||
# version 4 and above support fvisibility=hidden (matches jni_x86.h file)
|
||||
# except 4.1.2 gives pointless warnings that can't be disabled (afaik)
|
||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
||||
CFLAGS += -fvisibility=hidden
|
||||
ifeq ($(USE_CLANG),)
|
||||
CFLAGS += -pthread
|
||||
CFLAGS += -fcheck-new
|
||||
# version 4 and above support fvisibility=hidden (matches jni_x86.h file)
|
||||
# except 4.1.2 gives pointless warnings that can't be disabled (afaik)
|
||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
||||
CFLAGS += -fvisibility=hidden
|
||||
endif
|
||||
else
|
||||
CFLAGS += -fvisibility=hidden
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CLANG), true)
|
||||
# Before Clang 3.1, we had to pass the stack alignment specification directly to llvm with the help of '-mllvm'
|
||||
# Starting with version 3.1, Clang understands the '-mstack-alignment' (and rejects '-mllvm -stack-alignment')
|
||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 1 \) \))" "0"
|
||||
STACK_ALIGNMENT_OPT = -mno-omit-leaf-frame-pointer -mstack-alignment=16
|
||||
else
|
||||
STACK_ALIGNMENT_OPT = -mno-omit-leaf-frame-pointer -mllvm -stack-alignment=16
|
||||
endif
|
||||
endif
|
||||
|
||||
ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
|
||||
ARCHFLAG/i486 = -m32 -march=i586
|
||||
ARCHFLAG/amd64 = -m64
|
||||
ARCHFLAG/amd64 = -m64 $(STACK_ALIGNMENT_OPT)
|
||||
ARCHFLAG/ia64 =
|
||||
ARCHFLAG/sparc = -m32 -mcpu=v9
|
||||
ARCHFLAG/sparcv9 = -m64 -mcpu=v9
|
||||
@ -163,14 +240,25 @@ ifneq ($(COMPILER_WARNINGS_FATAL),false)
|
||||
WARNINGS_ARE_ERRORS = -Werror
|
||||
endif
|
||||
|
||||
# Except for a few acceptable ones
|
||||
# Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
|
||||
# conversions which might affect the values. To avoid that, we need to turn
|
||||
# it off explicitly.
|
||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
||||
ifeq ($(USE_CLANG), true)
|
||||
# However we need to clean the code up before we can unrestrictedly enable this option with Clang
|
||||
WARNINGS_ARE_ERRORS += -Wno-unused-value -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
|
||||
WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-compare
|
||||
# Not yet supported by clang in Xcode 4.6.2
|
||||
# WARNINGS_ARE_ERRORS += -Wno-tautological-constant-out-of-range-compare
|
||||
WARNINGS_ARE_ERRORS += -Wno-delete-non-virtual-dtor -Wno-deprecated -Wno-format -Wno-dynamic-class-memaccess
|
||||
WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
|
||||
endif
|
||||
|
||||
WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef
|
||||
else
|
||||
WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
|
||||
|
||||
ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
||||
# Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
|
||||
# conversions which might affect the values. Only enable it in earlier versions.
|
||||
WARNING_FLAGS = -Wunused-function
|
||||
ifeq ($(USE_CLANG),)
|
||||
WARNINGS_FLAGS += -Wconversion
|
||||
endif
|
||||
endif
|
||||
|
||||
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
|
||||
@ -214,14 +302,24 @@ endif
|
||||
|
||||
OPT_CFLAGS/NOOPT=-O0
|
||||
|
||||
# 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation.
|
||||
ifneq "$(shell expr \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) = 3 \) \))" "0"
|
||||
OPT_CFLAGS/mulnode.o += -O0
|
||||
# Work around some compiler bugs.
|
||||
ifeq ($(USE_CLANG), true)
|
||||
ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 2), 1)
|
||||
OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT)
|
||||
endif
|
||||
else
|
||||
# 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation.
|
||||
ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 3), 1)
|
||||
OPT_CFLAGS/mulnode.o += $(OPT_CFLAGS/NOOPT)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Flags for generating make dependency flags.
|
||||
ifneq ("${CC_VER_MAJOR}", "2")
|
||||
DEPFLAGS = -fpch-deps -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
|
||||
DEPFLAGS = -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
|
||||
ifeq ($(USE_CLANG),)
|
||||
ifneq ($(CC_VER_MAJOR), 2)
|
||||
DEPFLAGS += -fpch-deps
|
||||
endif
|
||||
endif
|
||||
|
||||
# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
|
||||
@ -249,13 +347,15 @@ endif
|
||||
# statically link libstdc++.so, work with gcc but ignored by g++
|
||||
STATIC_STDCXX = -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
|
||||
|
||||
# statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x.
|
||||
ifneq ("${CC_VER_MAJOR}", "2")
|
||||
STATIC_LIBGCC += -static-libgcc
|
||||
endif
|
||||
ifeq ($(USE_CLANG),)
|
||||
# statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x.
|
||||
ifneq ("${CC_VER_MAJOR}", "2")
|
||||
STATIC_LIBGCC += -static-libgcc
|
||||
endif
|
||||
|
||||
ifeq ($(BUILDARCH), ia64)
|
||||
LFLAGS += -Wl,-relax
|
||||
ifeq ($(BUILDARCH), ia64)
|
||||
LFLAGS += -Wl,-relax
|
||||
endif
|
||||
endif
|
||||
|
||||
# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
|
||||
@ -296,25 +396,31 @@ endif
|
||||
#------------------------------------------------------------------------
|
||||
# Debug flags
|
||||
|
||||
# Use the stabs format for debugging information (this is the default
|
||||
# on gcc-2.91). It's good enough, has all the information about line
|
||||
# numbers and local variables, and libjvm.so is only about 16M.
|
||||
# Change this back to "-g" if you want the most expressive format.
|
||||
# (warning: that could easily inflate libjvm.so to 150M!)
|
||||
# Note: The Itanium gcc compiler crashes when using -gstabs.
|
||||
DEBUG_CFLAGS/ia64 = -g
|
||||
DEBUG_CFLAGS/amd64 = -g
|
||||
DEBUG_CFLAGS/arm = -g
|
||||
DEBUG_CFLAGS/ppc = -g
|
||||
DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
|
||||
DEBUG_CFLAGS += -gstabs
|
||||
ifeq ($(USE_CLANG), true)
|
||||
# Restrict the debug information created by Clang to avoid
|
||||
# too big object files and speed the build up a little bit
|
||||
# (see http://llvm.org/bugs/show_bug.cgi?id=7554)
|
||||
CFLAGS += -flimit-debug-info
|
||||
endif
|
||||
|
||||
# DEBUG_BINARIES overrides everything, use full -g debug information
|
||||
# DEBUG_BINARIES uses full -g debug information for all configs
|
||||
ifeq ($(DEBUG_BINARIES), true)
|
||||
DEBUG_CFLAGS = -g
|
||||
CFLAGS += $(DEBUG_CFLAGS)
|
||||
CFLAGS += -g
|
||||
else
|
||||
# Use the stabs format for debugging information (this is the default
|
||||
# on gcc-2.91). It's good enough, has all the information about line
|
||||
# numbers and local variables, and libjvm.so is only about 16M.
|
||||
# Change this back to "-g" if you want the most expressive format.
|
||||
# (warning: that could easily inflate libjvm.so to 150M!)
|
||||
# Note: The Itanium gcc compiler crashes when using -gstabs.
|
||||
DEBUG_CFLAGS/ia64 = -g
|
||||
DEBUG_CFLAGS/amd64 = -g
|
||||
DEBUG_CFLAGS/arm = -g
|
||||
DEBUG_CFLAGS/ppc = -g
|
||||
DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
|
||||
DEBUG_CFLAGS += -gstabs
|
||||
endif
|
||||
endif
|
||||
|
||||
# If we are building HEADLESS, pass on to VM
|
||||
|
@ -19,7 +19,7 @@
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
TYPE=MINIMAL1
|
||||
@ -32,6 +32,7 @@ INCLUDE_SERVICES ?= false
|
||||
INCLUDE_MANAGEMENT ?= false
|
||||
INCLUDE_ALL_GCS ?= false
|
||||
INCLUDE_NMT ?= false
|
||||
INCLUDE_TRACE ?= false
|
||||
INCLUDE_CDS ?= false
|
||||
|
||||
CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1999, 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
|
||||
@ -80,7 +80,7 @@ default: vm_build_preliminaries the_vm
|
||||
@echo All done.
|
||||
|
||||
# This is an explicit dependency for the sake of parallel makes.
|
||||
vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff sa_stuff dtrace_stuff
|
||||
vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff trace_stuff sa_stuff dtrace_stuff
|
||||
@# We need a null action here, so implicit rules don't get consulted.
|
||||
|
||||
$(Cached_plat): $(Plat_File)
|
||||
@ -94,6 +94,10 @@ ad_stuff: $(Cached_plat) $(adjust-mflags)
|
||||
jvmti_stuff: $(Cached_plat) $(adjust-mflags)
|
||||
@$(MAKE) -f jvmti.make $(MFLAGS-adjusted)
|
||||
|
||||
# generate trace files
|
||||
trace_stuff: jvmti_stuff $(Cached_plat) $(adjust-mflags)
|
||||
@$(MAKE) -f trace.make $(MFLAGS-adjusted)
|
||||
|
||||
ifeq ($(OS_VENDOR), Darwin)
|
||||
# generate dtrace header files
|
||||
dtrace_stuff: $(Cached_plat) $(adjust-mflags)
|
||||
|
121
hotspot/make/bsd/makefiles/trace.make
Normal file
121
hotspot/make/bsd/makefiles/trace.make
Normal file
@ -0,0 +1,121 @@
|
||||
#
|
||||
# Copyright (c) 2003, 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.
|
||||
#
|
||||
#
|
||||
|
||||
# This makefile (trace.make) is included from the trace.make in the
|
||||
# build directories.
|
||||
#
|
||||
# It knows how to build and run the tools to generate trace files.
|
||||
|
||||
include $(GAMMADIR)/make/bsd/makefiles/rules.make
|
||||
include $(GAMMADIR)/make/altsrc.make
|
||||
|
||||
# #########################################################################
|
||||
|
||||
HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
|
||||
echo "true"; else echo "false";\
|
||||
fi)
|
||||
|
||||
TOPDIR = $(shell echo `pwd`)
|
||||
GENERATED = $(TOPDIR)/../generated
|
||||
JvmtiOutDir = $(GENERATED)/jvmtifiles
|
||||
TraceOutDir = $(GENERATED)/tracefiles
|
||||
|
||||
TraceAltSrcDir = $(HS_ALT_SRC)/share/vm/trace
|
||||
TraceSrcDir = $(HS_COMMON_SRC)/share/vm/trace
|
||||
|
||||
# set VPATH so make knows where to look for source files
|
||||
Src_Dirs_V += $(TraceSrcDir) $(TraceAltSrcDir)
|
||||
VPATH += $(Src_Dirs_V:%=%:)
|
||||
|
||||
TraceGeneratedNames = \
|
||||
traceEventClasses.hpp \
|
||||
traceEventIds.hpp \
|
||||
traceTypes.hpp
|
||||
|
||||
ifeq ($(HAS_ALT_SRC), true)
|
||||
TraceGeneratedNames += \
|
||||
traceRequestables.hpp \
|
||||
traceEventControl.hpp
|
||||
|
||||
ifneq ($(INCLUDE_TRACE), false)
|
||||
TraceGeneratedNames += traceProducer.cpp
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
|
||||
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
|
||||
|
||||
XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
|
||||
|
||||
XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \
|
||||
$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
|
||||
ifeq ($(HAS_ALT_SRC), true)
|
||||
XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
|
||||
endif
|
||||
|
||||
.PHONY: all clean cleanall
|
||||
|
||||
# #########################################################################
|
||||
|
||||
all: $(TraceGeneratedFiles)
|
||||
|
||||
GENERATE_CODE= \
|
||||
$(QUIETLY) echo Generating $@; \
|
||||
$(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
|
||||
test -f $@
|
||||
|
||||
$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
ifeq ($(HAS_ALT_SRC), false)
|
||||
|
||||
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
else
|
||||
|
||||
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
endif
|
||||
|
||||
# #########################################################################
|
||||
|
||||
|
||||
clean cleanall:
|
||||
rm $(TraceGeneratedFiles)
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1999, 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
|
||||
@ -19,7 +19,7 @@
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# Rules to build JVM and related libraries, included from vm.make in the build
|
||||
@ -52,7 +52,7 @@ endif
|
||||
# Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
|
||||
# The adfiles directory contains ad_<arch>.[ch]pp.
|
||||
# The jvmtifiles directory contains jvmti*.[ch]pp
|
||||
Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles
|
||||
Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
|
||||
VPATH += $(Src_Dirs_V:%=%:)
|
||||
|
||||
# set INCLUDES for C preprocessor.
|
||||
@ -66,7 +66,7 @@ else
|
||||
SYMFLAG =
|
||||
endif
|
||||
|
||||
# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
|
||||
# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
|
||||
# in $(GAMMADIR)/make/defs.make
|
||||
ifeq ($(HOTSPOT_BUILD_VERSION),)
|
||||
BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)\""
|
||||
@ -93,7 +93,7 @@ CXXFLAGS = \
|
||||
|
||||
# This is VERY important! The version define must only be supplied to vm_version.o
|
||||
# If not, ccache will not re-use the cache at all, since the version string might contain
|
||||
# a time and date.
|
||||
# a time and date.
|
||||
CXXFLAGS/vm_version.o += ${JRE_VERSION}
|
||||
|
||||
CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
|
||||
@ -105,10 +105,6 @@ ifdef DEFAULT_LIBPATH
|
||||
CXXFLAGS += -DDEFAULT_LIBPATH="\"$(DEFAULT_LIBPATH)\""
|
||||
endif
|
||||
|
||||
ifndef JAVASE_EMBEDDED
|
||||
CFLAGS += -DINCLUDE_TRACE
|
||||
endif
|
||||
|
||||
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
|
||||
CFLAGS += $(CFLAGS_WARN/BYFILE)
|
||||
|
||||
@ -126,7 +122,11 @@ ifneq ($(OS_VENDOR), Darwin)
|
||||
LFLAGS += -Xlinker -z -Xlinker noexecstack
|
||||
endif
|
||||
|
||||
LIBS += -lm -pthread
|
||||
LIBS += -lm
|
||||
|
||||
ifeq ($(USE_CLANG),)
|
||||
LIBS += -pthread
|
||||
endif
|
||||
|
||||
# By default, link the *.o into the library, not the executable.
|
||||
LINK_INTO$(LINK_INTO) = LIBJVM
|
||||
@ -161,15 +161,15 @@ SOURCE_PATHS+=$(HS_COMMON_SRC)/os/posix/vm
|
||||
SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
|
||||
SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
|
||||
|
||||
ifndef JAVASE_EMBEDDED
|
||||
SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
|
||||
CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
|
||||
CORE_PATHS+=$(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
|
||||
|
||||
ifneq ($(INCLUDE_TRACE), false)
|
||||
CORE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
|
||||
find $(HS_ALT_SRC)/share/vm/jfr -type d; \
|
||||
fi)
|
||||
endif
|
||||
|
||||
CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
|
||||
CORE_PATHS+=$(GENERATED)/jvmtifiles
|
||||
|
||||
COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
|
||||
COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2006, 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
|
||||
@ -19,7 +19,7 @@
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# The common definitions for hotspot builds.
|
||||
@ -236,7 +236,7 @@ ifneq ($(ALT_JDK_IMAGE_DIR),)
|
||||
JDK_IMAGE_DIR=$(ALT_JDK_IMAGE_DIR)
|
||||
endif
|
||||
|
||||
# The platform dependent defs.make defines platform specific variable such
|
||||
# The platform dependent defs.make defines platform specific variable such
|
||||
# as ARCH, EXPORT_LIST etc. We must place the include here after BOOTDIR is defined.
|
||||
include $(GAMMADIR)/make/$(OSNAME)/makefiles/defs.make
|
||||
|
||||
@ -258,7 +258,7 @@ ifneq ($(OSNAME),windows)
|
||||
# LIBARCH - directory name in JDK/JRE
|
||||
|
||||
# Use uname output for SRCARCH, but deal with platform differences. If ARCH
|
||||
# is not explicitly listed below, it is treated as x86.
|
||||
# is not explicitly listed below, it is treated as x86.
|
||||
SRCARCH = $(ARCH/$(filter sparc sparc64 ia64 amd64 x86_64 arm ppc zero,$(ARCH)))
|
||||
ARCH/ = x86
|
||||
ARCH/sparc = sparc
|
||||
@ -337,8 +337,5 @@ EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jni.h
|
||||
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/$(JDK_INCLUDE_SUBDIR)/jni_md.h
|
||||
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jmm.h
|
||||
|
||||
ifndef JAVASE_EMBEDDED
|
||||
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jfr.h
|
||||
endif
|
||||
|
||||
.PHONY: $(HS_ALT_MAKE)/defs.make
|
||||
|
||||
|
@ -19,13 +19,13 @@
|
||||
# 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 ($(INCLUDE_JVMTI), false)
|
||||
CXXFLAGS += -DINCLUDE_JVMTI=0
|
||||
CFLAGS += -DINCLUDE_JVMTI=0
|
||||
|
||||
Src_Files_EXCLUDE += jvmtiGetLoadedClasses.cpp forte.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \
|
||||
Src_Files_EXCLUDE += 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 \
|
||||
@ -87,7 +87,7 @@ ifeq ($(INCLUDE_ALL_GCS), false)
|
||||
g1BlockOffsetTable.cpp g1CardCounts.cpp g1CollectedHeap.cpp g1CollectorPolicy.cpp \
|
||||
g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp \
|
||||
g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp \
|
||||
g1RemSet.cpp g1SATBCardTableModRefBS.cpp g1_globals.cpp heapRegion.cpp \
|
||||
g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1_globals.cpp heapRegion.cpp \
|
||||
heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \
|
||||
ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp \
|
||||
adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp \
|
||||
@ -100,7 +100,7 @@ ifeq ($(INCLUDE_ALL_GCS), false)
|
||||
parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \
|
||||
gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \
|
||||
mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(INCLUDE_NMT), false)
|
||||
CXXFLAGS += -DINCLUDE_NMT=0
|
||||
@ -110,3 +110,5 @@ ifeq ($(INCLUDE_NMT), false)
|
||||
memBaseline.cpp memPtr.cpp memRecorder.cpp memReporter.cpp memSnapshot.cpp memTrackWorker.cpp \
|
||||
memTracker.cpp nmtDCmd.cpp
|
||||
endif
|
||||
|
||||
-include $(HS_ALT_MAKE)/excludeSrc.make
|
||||
|
@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
|
||||
|
||||
HS_MAJOR_VER=25
|
||||
HS_MINOR_VER=0
|
||||
HS_BUILD_NUMBER=34
|
||||
HS_BUILD_NUMBER=37
|
||||
|
||||
JDK_MAJOR_VER=1
|
||||
JDK_MINOR_VER=8
|
||||
|
@ -68,7 +68,7 @@ CXXFLAGS += -DASSERT
|
||||
|
||||
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
|
||||
# Compiler warnings are treated as errors
|
||||
CFLAGS_WARN = -Werror
|
||||
CFLAGS_WARN = $(WARNINGS_ARE_ERRORS)
|
||||
CFLAGS += $(CFLAGS_WARN)
|
||||
|
||||
OBJECTNAMES = \
|
||||
|
@ -47,6 +47,7 @@
|
||||
# flags.make - with macro settings
|
||||
# vm.make - to support making "$(MAKE) -v vm.make" in makefiles
|
||||
# adlc.make -
|
||||
# trace.make - generate tracing event and type definitions
|
||||
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
|
||||
# sa.make - generate SA jar file and natives
|
||||
#
|
||||
@ -114,7 +115,8 @@ COMPILER = $(shell sed -n 's/^compiler[ ]*=[ ]*//p' $(PLATFORM_FILE))
|
||||
SIMPLE_DIRS = \
|
||||
$(PLATFORM_DIR)/generated/dependencies \
|
||||
$(PLATFORM_DIR)/generated/adfiles \
|
||||
$(PLATFORM_DIR)/generated/jvmtifiles
|
||||
$(PLATFORM_DIR)/generated/jvmtifiles \
|
||||
$(PLATFORM_DIR)/generated/tracefiles
|
||||
|
||||
TARGETS = debug fastdebug optimized product
|
||||
SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
|
||||
@ -122,7 +124,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
|
||||
# For dependencies and recursive makes.
|
||||
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
|
||||
|
||||
BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make
|
||||
BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make trace.make sa.make
|
||||
|
||||
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
|
||||
SRCARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
|
||||
@ -269,6 +271,8 @@ flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst
|
||||
echo && \
|
||||
echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \
|
||||
echo "SYSDEFS += \$$(HOTSPOT_EXTRA_SYSDEFS)"; \
|
||||
[ -n "$(INCLUDE_TRACE)" ] && \
|
||||
echo && echo "INCLUDE_TRACE = $(INCLUDE_TRACE)"; \
|
||||
echo; \
|
||||
[ -n "$(SPEC)" ] && \
|
||||
echo "include $(SPEC)"; \
|
||||
@ -337,6 +341,16 @@ jvmti.make: $(BUILDTREE_MAKE)
|
||||
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
|
||||
) > $@
|
||||
|
||||
trace.make: $(BUILDTREE_MAKE)
|
||||
@echo Creating $@ ...
|
||||
$(QUIETLY) ( \
|
||||
$(BUILDTREE_COMMENT); \
|
||||
echo; \
|
||||
echo include flags.make; \
|
||||
echo; \
|
||||
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
|
||||
) > $@
|
||||
|
||||
sa.make: $(BUILDTREE_MAKE)
|
||||
@echo Creating $@ ...
|
||||
$(QUIETLY) ( \
|
||||
|
@ -36,8 +36,14 @@ ifeq ($(SPEC),)
|
||||
HOSTCC = gcc
|
||||
STRIP = $(ALT_COMPILER_PATH)/strip
|
||||
else
|
||||
CXX = g++
|
||||
CC = gcc
|
||||
ifeq ($(USE_CLANG), true)
|
||||
CXX = clang++
|
||||
CC = clang
|
||||
else
|
||||
CXX = g++
|
||||
CC = gcc
|
||||
endif
|
||||
|
||||
HOSTCXX = $(CXX)
|
||||
HOSTCC = $(CC)
|
||||
STRIP = strip
|
||||
@ -46,19 +52,79 @@ ifeq ($(SPEC),)
|
||||
endif
|
||||
|
||||
|
||||
# -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
|
||||
# prints the numbers (e.g. "2.95", "3.2.1")
|
||||
CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1)
|
||||
CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2)
|
||||
|
||||
# check for precompiled headers support
|
||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 4 \) \))" "0"
|
||||
# Allow the user to turn off precompiled headers from the command line.
|
||||
ifneq ($(USE_PRECOMPILED_HEADER),0)
|
||||
PRECOMPILED_HEADER_DIR=.
|
||||
PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
|
||||
PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch
|
||||
ifeq ($(USE_CLANG), true)
|
||||
CC_VER_MAJOR := $(shell $(CC) -v 2>&1 | grep version | sed "s/.*version \([0-9]*\.[0-9]*\).*/\1/" | cut -d'.' -f1)
|
||||
CC_VER_MINOR := $(shell $(CC) -v 2>&1 | grep version | sed "s/.*version \([0-9]*\.[0-9]*\).*/\1/" | cut -d'.' -f2)
|
||||
else
|
||||
# -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
|
||||
# prints the numbers (e.g. "2.95", "3.2.1")
|
||||
CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1)
|
||||
CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2)
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(USE_CLANG), true)
|
||||
# Clang has precompiled headers support by default, but the user can switch
|
||||
# it off by using 'USE_PRECOMPILED_HEADER=0'.
|
||||
ifdef LP64
|
||||
ifeq ($(USE_PRECOMPILED_HEADER),)
|
||||
USE_PRECOMPILED_HEADER=1
|
||||
endif
|
||||
else
|
||||
# We don't support precompiled headers on 32-bit builds because there some files are
|
||||
# compiled with -fPIC while others are compiled without (see 'NONPIC_OBJ_FILES' rules.make)
|
||||
# Clang produces an error if the PCH file was compiled with other options than the actual compilation unit.
|
||||
USE_PRECOMPILED_HEADER=0
|
||||
endif
|
||||
|
||||
ifeq ($(USE_PRECOMPILED_HEADER),1)
|
||||
|
||||
ifndef LP64
|
||||
$(error " Precompiled Headers only supported on 64-bit platforms!")
|
||||
endif
|
||||
|
||||
PRECOMPILED_HEADER_DIR=.
|
||||
PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
|
||||
PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.pch
|
||||
|
||||
PCH_FLAG = -include precompiled.hpp
|
||||
PCH_FLAG/DEFAULT = $(PCH_FLAG)
|
||||
PCH_FLAG/NO_PCH = -DNO_PCH
|
||||
PCH_FLAG/BY_FILE = $(PCH_FLAG/$@)$(PCH_FLAG/DEFAULT$(PCH_FLAG/$@))
|
||||
|
||||
VM_PCH_FLAG/LIBJVM = $(PCH_FLAG/BY_FILE)
|
||||
VM_PCH_FLAG/AOUT =
|
||||
VM_PCH_FLAG = $(VM_PCH_FLAG/$(LINK_INTO))
|
||||
|
||||
# We only use precompiled headers for the JVM build
|
||||
CFLAGS += $(VM_PCH_FLAG)
|
||||
|
||||
# There are some files which don't like precompiled headers
|
||||
# The following files are build with 'OPT_CFLAGS/NOOPT' (-O0) in the opt build.
|
||||
# But Clang doesn't support a precompiled header which was compiled with -O3
|
||||
# to be used in a compilation unit which uses '-O0'. We could also prepare an
|
||||
# extra '-O0' PCH file for the opt build and use it here, but it's probably
|
||||
# not worth the effoert as long as only two files need this special handling.
|
||||
PCH_FLAG/loopTransform.o = $(PCH_FLAG/NO_PCH)
|
||||
PCH_FLAG/sharedRuntimeTrig.o = $(PCH_FLAG/NO_PCH)
|
||||
PCH_FLAG/sharedRuntimeTrans.o = $(PCH_FLAG/NO_PCH)
|
||||
|
||||
endif
|
||||
else # ($(USE_CLANG), true)
|
||||
# check for precompiled headers support
|
||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 4 \) \))" "0"
|
||||
# Allow the user to turn off precompiled headers from the command line.
|
||||
ifneq ($(USE_PRECOMPILED_HEADER),0)
|
||||
PRECOMPILED_HEADER_DIR=.
|
||||
PRECOMPILED_HEADER_SRC=$(GAMMADIR)/src/share/vm/precompiled/precompiled.hpp
|
||||
PRECOMPILED_HEADER=$(PRECOMPILED_HEADER_DIR)/precompiled.hpp.gch
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
|
||||
ifeq ($(USE_PRECOMPILED_HEADER),0)
|
||||
CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
|
||||
endif
|
||||
|
||||
|
||||
@ -83,16 +149,30 @@ CFLAGS += $(VM_PICFLAG)
|
||||
CFLAGS += -fno-rtti
|
||||
CFLAGS += -fno-exceptions
|
||||
CFLAGS += -D_REENTRANT
|
||||
CFLAGS += -fcheck-new
|
||||
# version 4 and above support fvisibility=hidden (matches jni_x86.h file)
|
||||
# except 4.1.2 gives pointless warnings that can't be disabled (afaik)
|
||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
||||
CFLAGS += -fvisibility=hidden
|
||||
ifeq ($(USE_CLANG),)
|
||||
CFLAGS += -fcheck-new
|
||||
# version 4 and above support fvisibility=hidden (matches jni_x86.h file)
|
||||
# except 4.1.2 gives pointless warnings that can't be disabled (afaik)
|
||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
||||
CFLAGS += -fvisibility=hidden
|
||||
endif
|
||||
else
|
||||
CFLAGS += -fvisibility=hidden
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CLANG), true)
|
||||
# Before Clang 3.1, we had to pass the stack alignment specification directly to llvm with the help of '-mllvm'
|
||||
# Starting with version 3.1, Clang understands the '-mstack-alignment' (and rejects '-mllvm -stack-alignment')
|
||||
ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 1 \) \))" "0"
|
||||
STACK_ALIGNMENT_OPT = -mno-omit-leaf-frame-pointer -mstack-alignment=16
|
||||
else
|
||||
STACK_ALIGNMENT_OPT = -mno-omit-leaf-frame-pointer -mllvm -stack-alignment=16
|
||||
endif
|
||||
endif
|
||||
|
||||
ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
|
||||
ARCHFLAG/i486 = -m32 -march=i586
|
||||
ARCHFLAG/amd64 = -m64
|
||||
ARCHFLAG/amd64 = -m64 $(STACK_ALIGNMENT_OPT)
|
||||
ARCHFLAG/ia64 =
|
||||
ARCHFLAG/sparc = -m32 -mcpu=v9
|
||||
ARCHFLAG/sparcv9 = -m64 -mcpu=v9
|
||||
@ -126,12 +206,22 @@ endif
|
||||
# Compiler warnings are treated as errors
|
||||
WARNINGS_ARE_ERRORS = -Werror
|
||||
|
||||
ifeq ($(USE_CLANG), true)
|
||||
# However we need to clean the code up before we can unrestrictedly enable this option with Clang
|
||||
WARNINGS_ARE_ERRORS += -Wno-unused-value -Wno-logical-op-parentheses -Wno-parentheses-equality -Wno-parentheses
|
||||
WARNINGS_ARE_ERRORS += -Wno-switch -Wno-tautological-constant-out-of-range-compare -Wno-tautological-compare
|
||||
WARNINGS_ARE_ERRORS += -Wno-delete-non-virtual-dtor -Wno-deprecated -Wno-format -Wno-dynamic-class-memaccess
|
||||
WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body
|
||||
endif
|
||||
|
||||
WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function
|
||||
|
||||
# Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
|
||||
# conversions which might affect the values. Only enable it in earlier versions.
|
||||
ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
||||
WARNING_FLAGS += -Wconversion
|
||||
ifeq ($(USE_CLANG),)
|
||||
# Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
|
||||
# conversions which might affect the values. Only enable it in earlier versions.
|
||||
ifeq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
|
||||
WARNING_FLAGS += -Wconversion
|
||||
endif
|
||||
endif
|
||||
|
||||
CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
|
||||
@ -165,19 +255,24 @@ endif
|
||||
|
||||
OPT_CFLAGS/NOOPT=-O0
|
||||
|
||||
# 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation.
|
||||
ifneq "$(shell expr \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) = 3 \) \))" "0"
|
||||
OPT_CFLAGS/mulnode.o += -O0
|
||||
# Work around some compiler bugs.
|
||||
ifeq ($(USE_CLANG), true)
|
||||
ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 2), 1)
|
||||
OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT)
|
||||
endif
|
||||
else
|
||||
# 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation.
|
||||
ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 3), 1)
|
||||
OPT_CFLAGS/mulnode.o += $(OPT_CFLAGS/NOOPT)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Flags for generating make dependency flags.
|
||||
ifneq ("${CC_VER_MAJOR}", "2")
|
||||
DEPFLAGS = -fpch-deps -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
|
||||
endif
|
||||
|
||||
# -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
|
||||
ifeq ($(USE_PRECOMPILED_HEADER),0)
|
||||
CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
|
||||
DEPFLAGS = -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
|
||||
ifeq ($(USE_CLANG),)
|
||||
ifneq ("${CC_VER_MAJOR}", "2")
|
||||
DEPFLAGS += -fpch-deps
|
||||
endif
|
||||
endif
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
@ -186,24 +281,33 @@ endif
|
||||
# statically link libstdc++.so, work with gcc but ignored by g++
|
||||
STATIC_STDCXX = -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
|
||||
|
||||
# statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x.
|
||||
ifneq ("${CC_VER_MAJOR}", "2")
|
||||
STATIC_LIBGCC += -static-libgcc
|
||||
endif
|
||||
ifeq ($(USE_CLANG),)
|
||||
# statically link libgcc and/or libgcc_s, libgcc does not exist before gcc-3.x.
|
||||
ifneq ("${CC_VER_MAJOR}", "2")
|
||||
STATIC_LIBGCC += -static-libgcc
|
||||
endif
|
||||
|
||||
ifeq ($(BUILDARCH), ia64)
|
||||
LFLAGS += -Wl,-relax
|
||||
ifeq ($(BUILDARCH), ia64)
|
||||
LFLAGS += -Wl,-relax
|
||||
endif
|
||||
endif
|
||||
|
||||
# Enable linker optimization
|
||||
LFLAGS += -Xlinker -O1
|
||||
|
||||
# If this is a --hash-style=gnu system, use --hash-style=both
|
||||
# The gnu .hash section won't work on some Linux systems like SuSE 10.
|
||||
_HAS_HASH_STYLE_GNU:=$(shell $(CC) -dumpspecs | grep -- '--hash-style=gnu')
|
||||
ifneq ($(_HAS_HASH_STYLE_GNU),)
|
||||
ifeq ($(USE_CLANG),)
|
||||
# If this is a --hash-style=gnu system, use --hash-style=both
|
||||
# The gnu .hash section won't work on some Linux systems like SuSE 10.
|
||||
_HAS_HASH_STYLE_GNU:=$(shell $(CC) -dumpspecs | grep -- '--hash-style=gnu')
|
||||
ifneq ($(_HAS_HASH_STYLE_GNU),)
|
||||
LDFLAGS_HASH_STYLE = -Wl,--hash-style=both
|
||||
endif
|
||||
else
|
||||
# Don't know how to find out the 'hash style' of a system as '-dumpspecs'
|
||||
# doesn't work for Clang. So for now we'll alwys use --hash-style=both
|
||||
LDFLAGS_HASH_STYLE = -Wl,--hash-style=both
|
||||
endif
|
||||
|
||||
LFLAGS += $(LDFLAGS_HASH_STYLE)
|
||||
|
||||
# Use $(MAPFLAG:FILENAME=real_file_name) to specify a map file.
|
||||
@ -221,6 +325,13 @@ AOUT_FLAGS += -Xlinker -export-dynamic
|
||||
#------------------------------------------------------------------------
|
||||
# Debug flags
|
||||
|
||||
ifeq ($(USE_CLANG), true)
|
||||
# Restrict the debug information created by Clang to avoid
|
||||
# too big object files and speed the build up a little bit
|
||||
# (see http://llvm.org/bugs/show_bug.cgi?id=7554)
|
||||
CFLAGS += -flimit-debug-info
|
||||
endif
|
||||
|
||||
# DEBUG_BINARIES uses full -g debug information for all configs
|
||||
ifeq ($(DEBUG_BINARIES), true)
|
||||
CFLAGS += -g
|
||||
@ -237,7 +348,12 @@ else
|
||||
DEBUG_CFLAGS/ppc = -g
|
||||
DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
|
||||
DEBUG_CFLAGS += -gstabs
|
||||
ifeq ($(USE_CLANG), true)
|
||||
# Clang doesn't understand -gstabs
|
||||
OPT_CFLAGS += -g
|
||||
else
|
||||
OPT_CFLAGS += -gstabs
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
|
||||
@ -247,7 +363,12 @@ else
|
||||
FASTDEBUG_CFLAGS/ppc = -g
|
||||
FASTDEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(FASTDEBUG_CFLAGS/$(BUILDARCH)),)
|
||||
FASTDEBUG_CFLAGS += -gstabs
|
||||
ifeq ($(USE_CLANG), true)
|
||||
# Clang doesn't understand -gstabs
|
||||
OPT_CFLAGS += -g
|
||||
else
|
||||
OPT_CFLAGS += -gstabs
|
||||
endif
|
||||
endif
|
||||
|
||||
OPT_CFLAGS/ia64 = -g
|
||||
@ -256,7 +377,12 @@ else
|
||||
OPT_CFLAGS/ppc = -g
|
||||
OPT_CFLAGS += $(OPT_CFLAGS/$(BUILDARCH))
|
||||
ifeq ($(OPT_CFLAGS/$(BUILDARCH)),)
|
||||
OPT_CFLAGS += -gstabs
|
||||
ifeq ($(USE_CLANG), true)
|
||||
# Clang doesn't understand -gstabs
|
||||
OPT_CFLAGS += -g
|
||||
else
|
||||
OPT_CFLAGS += -gstabs
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -19,7 +19,7 @@
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
TYPE=MINIMAL1
|
||||
@ -32,6 +32,7 @@ INCLUDE_SERVICES ?= false
|
||||
INCLUDE_MANAGEMENT ?= false
|
||||
INCLUDE_ALL_GCS ?= false
|
||||
INCLUDE_NMT ?= false
|
||||
INCLUDE_TRACE ?= false
|
||||
INCLUDE_CDS ?= false
|
||||
|
||||
CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1999, 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
|
||||
@ -80,7 +80,7 @@ default: vm_build_preliminaries the_vm
|
||||
@echo All done.
|
||||
|
||||
# This is an explicit dependency for the sake of parallel makes.
|
||||
vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff sa_stuff
|
||||
vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) trace_stuff jvmti_stuff sa_stuff
|
||||
@# We need a null action here, so implicit rules don't get consulted.
|
||||
|
||||
$(Cached_plat): $(Plat_File)
|
||||
@ -94,6 +94,10 @@ ad_stuff: $(Cached_plat) $(adjust-mflags)
|
||||
jvmti_stuff: $(Cached_plat) $(adjust-mflags)
|
||||
@$(MAKE) -f jvmti.make $(MFLAGS-adjusted)
|
||||
|
||||
# generate trace files
|
||||
trace_stuff: jvmti_stuff $(Cached_plat) $(adjust-mflags)
|
||||
@$(MAKE) -f trace.make $(MFLAGS-adjusted)
|
||||
|
||||
# generate SA jar files and native header
|
||||
sa_stuff:
|
||||
@$(MAKE) -f sa.make $(MFLAGS-adjusted)
|
||||
|
120
hotspot/make/linux/makefiles/trace.make
Normal file
120
hotspot/make/linux/makefiles/trace.make
Normal file
@ -0,0 +1,120 @@
|
||||
#
|
||||
# Copyright (c) 2003, 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.
|
||||
#
|
||||
#
|
||||
|
||||
# This makefile (trace.make) is included from the trace.make in the
|
||||
# build directories.
|
||||
#
|
||||
# It knows how to build and run the tools to generate trace files.
|
||||
|
||||
include $(GAMMADIR)/make/linux/makefiles/rules.make
|
||||
include $(GAMMADIR)/make/altsrc.make
|
||||
|
||||
# #########################################################################
|
||||
|
||||
HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
|
||||
echo "true"; else echo "false";\
|
||||
fi)
|
||||
|
||||
TOPDIR = $(shell echo `pwd`)
|
||||
GENERATED = $(TOPDIR)/../generated
|
||||
JvmtiOutDir = $(GENERATED)/jvmtifiles
|
||||
TraceOutDir = $(GENERATED)/tracefiles
|
||||
|
||||
TraceAltSrcDir = $(HS_ALT_SRC)/share/vm/trace
|
||||
TraceSrcDir = $(HS_COMMON_SRC)/share/vm/trace
|
||||
|
||||
# set VPATH so make knows where to look for source files
|
||||
Src_Dirs_V += $(TraceSrcDir) $(TraceAltSrcDir)
|
||||
VPATH += $(Src_Dirs_V:%=%:)
|
||||
|
||||
TraceGeneratedNames = \
|
||||
traceEventClasses.hpp \
|
||||
traceEventIds.hpp \
|
||||
traceTypes.hpp
|
||||
|
||||
ifeq ($(HAS_ALT_SRC), true)
|
||||
TraceGeneratedNames += \
|
||||
traceRequestables.hpp \
|
||||
traceEventControl.hpp
|
||||
|
||||
ifneq ($(INCLUDE_TRACE), false)
|
||||
TraceGeneratedNames += traceProducer.cpp
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
|
||||
|
||||
XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
|
||||
|
||||
XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \
|
||||
$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
|
||||
ifeq ($(HAS_ALT_SRC), true)
|
||||
XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
|
||||
endif
|
||||
|
||||
.PHONY: all clean cleanall
|
||||
|
||||
# #########################################################################
|
||||
|
||||
all: $(TraceGeneratedFiles)
|
||||
|
||||
GENERATE_CODE= \
|
||||
$(QUIETLY) echo Generating $@; \
|
||||
$(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
|
||||
test -f $@
|
||||
|
||||
$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
ifeq ($(HAS_ALT_SRC), false)
|
||||
|
||||
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
else
|
||||
|
||||
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
endif
|
||||
|
||||
# #########################################################################
|
||||
|
||||
clean cleanall:
|
||||
rm $(TraceGeneratedFiles)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1999, 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
|
||||
@ -19,7 +19,7 @@
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# Rules to build JVM and related libraries, included from vm.make in the build
|
||||
@ -52,7 +52,7 @@ endif
|
||||
# Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
|
||||
# The adfiles directory contains ad_<arch>.[ch]pp.
|
||||
# The jvmtifiles directory contains jvmti*.[ch]pp
|
||||
Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles
|
||||
Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
|
||||
VPATH += $(Src_Dirs_V:%=%:)
|
||||
|
||||
# set INCLUDES for C preprocessor.
|
||||
@ -72,7 +72,7 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
|
||||
# HOTSPOT_RELEASE_VERSION and HOTSPOT_BUILD_VERSION are defined
|
||||
# in $(GAMMADIR)/make/defs.make
|
||||
ifeq ($(HOTSPOT_BUILD_VERSION),)
|
||||
BUILD_VERSION = -DHOTSPOT_RELEASE_VERSION="\"$(HOTSPOT_RELEASE_VERSION)\""
|
||||
@ -99,7 +99,7 @@ CXXFLAGS = \
|
||||
|
||||
# This is VERY important! The version define must only be supplied to vm_version.o
|
||||
# If not, ccache will not re-use the cache at all, since the version string might contain
|
||||
# a time and date.
|
||||
# a time and date.
|
||||
CXXFLAGS/vm_version.o += ${JRE_VERSION}
|
||||
|
||||
CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
|
||||
@ -108,12 +108,6 @@ CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
|
||||
CXXFLAGS += $(CXXFLAGS/BYFILE)
|
||||
|
||||
|
||||
ifndef JAVASE_EMBEDDED
|
||||
ifneq (${ARCH},arm)
|
||||
CFLAGS += -DINCLUDE_TRACE
|
||||
endif
|
||||
endif
|
||||
|
||||
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
|
||||
CFLAGS += $(CFLAGS_WARN/BYFILE)
|
||||
|
||||
@ -158,16 +152,14 @@ SOURCE_PATHS+=$(HS_COMMON_SRC)/os/posix/vm
|
||||
SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
|
||||
SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
|
||||
|
||||
ifndef JAVASE_EMBEDDED
|
||||
ifneq (${ARCH},arm)
|
||||
SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
|
||||
CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
|
||||
CORE_PATHS+=$(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
|
||||
|
||||
ifneq ($(INCLUDE_TRACE), false)
|
||||
CORE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
|
||||
find $(HS_ALT_SRC)/share/vm/jfr -type d; \
|
||||
fi)
|
||||
endif
|
||||
endif
|
||||
|
||||
CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
|
||||
CORE_PATHS+=$(GENERATED)/jvmtifiles
|
||||
|
||||
COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
|
||||
COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
|
||||
@ -316,7 +308,7 @@ endif
|
||||
# With more recent Redhat releases (or the cutting edge version Fedora), if
|
||||
# SELinux is configured to be enabled, the runtime linker will fail to apply
|
||||
# the text relocation to libjvm.so considering that it is built as a non-PIC
|
||||
# DSO. To workaround that, we run chcon to libjvm.so after it is built. See
|
||||
# DSO. To workaround that, we run chcon to libjvm.so after it is built. See
|
||||
# details in bug 6538311.
|
||||
$(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT)
|
||||
$(QUIETLY) { \
|
||||
|
@ -47,6 +47,7 @@
|
||||
# flags.make - with macro settings
|
||||
# vm.make - to support making "$(MAKE) -v vm.make" in makefiles
|
||||
# adlc.make -
|
||||
# trace.make - generate tracing event and type definitions
|
||||
# jvmti.make - generate JVMTI bindings from the spec (JSR-163)
|
||||
# sa.make - generate SA jar file and natives
|
||||
#
|
||||
@ -107,7 +108,8 @@ COMPILER = $(shell sed -n 's/^compiler[ ]*=[ ]*//p' $(PLATFORM_FILE))
|
||||
SIMPLE_DIRS = \
|
||||
$(PLATFORM_DIR)/generated/dependencies \
|
||||
$(PLATFORM_DIR)/generated/adfiles \
|
||||
$(PLATFORM_DIR)/generated/jvmtifiles
|
||||
$(PLATFORM_DIR)/generated/jvmtifiles \
|
||||
$(PLATFORM_DIR)/generated/tracefiles
|
||||
|
||||
TARGETS = debug fastdebug optimized product
|
||||
SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
|
||||
@ -115,7 +117,7 @@ SUBMAKE_DIRS = $(addprefix $(PLATFORM_DIR)/,$(TARGETS))
|
||||
# For dependencies and recursive makes.
|
||||
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OS_FAMILY)/makefiles/buildtree.make
|
||||
|
||||
BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make sa.make
|
||||
BUILDTREE_TARGETS = Makefile flags.make flags_vm.make vm.make adlc.make jvmti.make trace.make sa.make
|
||||
|
||||
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OS_FAMILY) \
|
||||
ARCH=$(ARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH) VARIANT=$(VARIANT)
|
||||
@ -327,6 +329,16 @@ jvmti.make: $(BUILDTREE_MAKE)
|
||||
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
|
||||
) > $@
|
||||
|
||||
trace.make: $(BUILDTREE_MAKE)
|
||||
@echo Creating $@ ...
|
||||
$(QUIETLY) ( \
|
||||
$(BUILDTREE_COMMENT); \
|
||||
echo; \
|
||||
echo include flags.make; \
|
||||
echo; \
|
||||
echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(@F)"; \
|
||||
) > $@
|
||||
|
||||
sa.make: $(BUILDTREE_MAKE)
|
||||
@echo Creating $@ ...
|
||||
$(QUIETLY) ( \
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1998, 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
|
||||
@ -73,7 +73,7 @@ default: vm_build_preliminaries the_vm
|
||||
@echo All done.
|
||||
|
||||
# This is an explicit dependency for the sake of parallel makes.
|
||||
vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff sa_stuff
|
||||
vm_build_preliminaries: checks $(Cached_plat) $(AD_Files_If_Required) jvmti_stuff trace_stuff sa_stuff
|
||||
@# We need a null action here, so implicit rules don't get consulted.
|
||||
|
||||
$(Cached_plat): $(Plat_File)
|
||||
@ -87,6 +87,10 @@ ad_stuff: $(Cached_plat) $(adjust-mflags)
|
||||
jvmti_stuff: $(Cached_plat) $(adjust-mflags)
|
||||
@$(MAKE) -f jvmti.make $(MFLAGS-adjusted)
|
||||
|
||||
# generate trace files
|
||||
trace_stuff: jvmti_stuff $(Cached_plat) $(adjust-mflags)
|
||||
@$(MAKE) -f trace.make $(MFLAGS-adjusted)
|
||||
|
||||
# generate SA jar files and native header
|
||||
sa_stuff:
|
||||
@$(MAKE) -f sa.make $(MFLAGS-adjusted)
|
||||
@ -127,5 +131,5 @@ realclean:
|
||||
rm -fr $(GENERATED)
|
||||
|
||||
.PHONY: default vm_build_preliminaries
|
||||
.PHONY: lists ad_stuff jvmti_stuff sa_stuff the_vm clean realclean
|
||||
.PHONY: lists ad_stuff jvmti_stuff trace_stuff sa_stuff the_vm clean realclean
|
||||
.PHONY: checks check_os_version install
|
||||
|
116
hotspot/make/solaris/makefiles/trace.make
Normal file
116
hotspot/make/solaris/makefiles/trace.make
Normal file
@ -0,0 +1,116 @@
|
||||
#
|
||||
# Copyright (c) 2003, 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.
|
||||
#
|
||||
#
|
||||
|
||||
# This makefile (trace.make) is included from the trace.make in the
|
||||
# build directories.
|
||||
#
|
||||
# It knows how to build and run the tools to generate trace files.
|
||||
|
||||
include $(GAMMADIR)/make/solaris/makefiles/rules.make
|
||||
include $(GAMMADIR)/make/altsrc.make
|
||||
|
||||
# #########################################################################
|
||||
|
||||
HAS_ALT_SRC:=$(shell if [ -d $(HS_ALT_SRC)/share/vm/trace ]; then \
|
||||
echo "true"; else echo "false";\
|
||||
fi)
|
||||
|
||||
TOPDIR = $(shell echo `pwd`)
|
||||
GENERATED = $(TOPDIR)/../generated
|
||||
JvmtiOutDir = $(GENERATED)/jvmtifiles
|
||||
TraceOutDir = $(GENERATED)/tracefiles
|
||||
|
||||
TraceAltSrcDir = $(HS_ALT_SRC)/share/vm/trace
|
||||
TraceSrcDir = $(HS_COMMON_SRC)/share/vm/trace
|
||||
|
||||
# set VPATH so make knows where to look for source files
|
||||
Src_Dirs_V += $(TraceSrcDir) $(TraceAltSrcDir)
|
||||
VPATH += $(Src_Dirs_V:%=%:)
|
||||
|
||||
TraceGeneratedNames = \
|
||||
traceEventClasses.hpp \
|
||||
traceEventIds.hpp \
|
||||
traceTypes.hpp
|
||||
|
||||
ifeq ($(HAS_ALT_SRC), true)
|
||||
TraceGeneratedNames += \
|
||||
traceRequestables.hpp \
|
||||
traceEventControl.hpp \
|
||||
traceProducer.cpp
|
||||
endif
|
||||
|
||||
TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)
|
||||
|
||||
XSLT = $(REMOTE) $(RUN.JAVA) -classpath $(JvmtiOutDir) jvmtiGen
|
||||
|
||||
XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \
|
||||
$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
|
||||
ifeq ($(HAS_ALT_SRC), true)
|
||||
XML_DEPS += $(TraceAltSrcDir)/traceevents.xml
|
||||
endif
|
||||
|
||||
.PHONY: all clean cleanall
|
||||
|
||||
# #########################################################################
|
||||
|
||||
all: $(TraceGeneratedFiles)
|
||||
|
||||
GENERATE_CODE= \
|
||||
$(QUIETLY) echo Generating $@; \
|
||||
$(XSLT) -IN $(word 1,$^) -XSL $(word 2,$^) -OUT $@; \
|
||||
test -f $@
|
||||
|
||||
$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
ifeq ($(HAS_ALT_SRC), false)
|
||||
|
||||
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
else
|
||||
|
||||
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
|
||||
$(GENERATE_CODE)
|
||||
|
||||
endif
|
||||
|
||||
# #########################################################################
|
||||
|
||||
clean cleanall:
|
||||
rm $(TraceGeneratedFiles)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1998, 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
|
||||
@ -19,7 +19,7 @@
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# Rules to build JVM and related libraries, included from vm.make in the build
|
||||
@ -48,7 +48,7 @@ include $(MAKEFILES_DIR)/$(BUILDARCH).make
|
||||
# Src_Dirs_V is everything in src/share/vm/*, plus the right os/*/vm and cpu/*/vm
|
||||
# The adfiles directory contains ad_<arch>.[ch]pp.
|
||||
# The jvmtifiles directory contains jvmti*.[ch]pp
|
||||
Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles
|
||||
Src_Dirs_V += $(GENERATED)/adfiles $(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
|
||||
VPATH += $(Src_Dirs_V:%=%:)
|
||||
|
||||
# set INCLUDES for C preprocessor
|
||||
@ -87,7 +87,7 @@ CXXFLAGS = \
|
||||
|
||||
# This is VERY important! The version define must only be supplied to vm_version.o
|
||||
# If not, ccache will not re-use the cache at all, since the version string might contain
|
||||
# a time and date.
|
||||
# a time and date.
|
||||
CXXFLAGS/vm_version.o += ${JRE_VERSION}
|
||||
|
||||
CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
|
||||
@ -103,7 +103,7 @@ CFLAGS += $(CFLAGS_WARN)
|
||||
CFLAGS += $(CFLAGS/NOEX)
|
||||
|
||||
# Extra flags from gnumake's invocation or environment
|
||||
CFLAGS += $(EXTRA_CFLAGS) -DINCLUDE_TRACE
|
||||
CFLAGS += $(EXTRA_CFLAGS)
|
||||
|
||||
# Math Library (libm.so), do not use -lm.
|
||||
# There might be two versions of libm.so on the build system:
|
||||
@ -137,9 +137,7 @@ else
|
||||
LIBS += -lsocket -lsched -ldl $(LIBM) -lthread -lc -ldemangle
|
||||
endif # sparcWorks
|
||||
|
||||
ifeq ("${Platform_arch}", "sparc")
|
||||
LIBS += -lkstat
|
||||
endif
|
||||
|
||||
# By default, link the *.o into the library, not the executable.
|
||||
LINK_INTO$(LINK_INTO) = LIBJVM
|
||||
@ -177,12 +175,14 @@ SOURCE_PATHS+=$(HS_COMMON_SRC)/os/posix/vm
|
||||
SOURCE_PATHS+=$(HS_COMMON_SRC)/cpu/$(Platform_arch)/vm
|
||||
SOURCE_PATHS+=$(HS_COMMON_SRC)/os_cpu/$(Platform_os_arch)/vm
|
||||
|
||||
SOURCE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
|
||||
CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
|
||||
CORE_PATHS+=$(GENERATED)/jvmtifiles $(GENERATED)/tracefiles
|
||||
|
||||
ifneq ($(INCLUDE_TRACE), false)
|
||||
CORE_PATHS+=$(shell if [ -d $(HS_ALT_SRC)/share/vm/jfr ]; then \
|
||||
find $(HS_ALT_SRC)/share/vm/jfr -type d; \
|
||||
fi)
|
||||
|
||||
CORE_PATHS=$(foreach path,$(SOURCE_PATHS),$(call altsrc,$(path)) $(path))
|
||||
CORE_PATHS+=$(GENERATED)/jvmtifiles
|
||||
endif
|
||||
|
||||
COMPILER1_PATHS := $(call altsrc,$(HS_COMMON_SRC)/share/vm/c1)
|
||||
COMPILER1_PATHS += $(HS_COMMON_SRC)/share/vm/c1
|
||||
@ -287,7 +287,7 @@ else
|
||||
LINK_VM = $(LINK_LIB.CXX)
|
||||
endif
|
||||
# making the library:
|
||||
$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(LIBJVM.o) $(LIBJVM_MAPFILE)
|
||||
$(LIBJVM): $(ADD_GNU_DEBUGLINK) $(FIX_EMPTY_SEC_HDR_FLAGS) $(LIBJVM.o) $(LIBJVM_MAPFILE)
|
||||
ifeq ($(filter -sbfast -xsbfast, $(CFLAGS_BROWSE)),)
|
||||
@echo Linking vm...
|
||||
$(QUIETLY) $(LINK_LIB.CXX/PRE_HOOK)
|
||||
|
@ -196,6 +196,12 @@ HS_BUILD_VER=$(HOTSPOT_RELEASE_VERSION)-$(HOTSPOT_BUILD_VERSION)
|
||||
|
||||
# End VERSIONINFO parameters
|
||||
|
||||
# if hotspot-only build and/or OPENJDK isn't passed down, need to set OPENJDK
|
||||
!ifndef OPENJDK
|
||||
!if !exists($(WorkSpace)\src\closed)
|
||||
OPENJDK=true
|
||||
!endif
|
||||
!endif
|
||||
|
||||
# We don't support SA on ia64, and we can't
|
||||
# build it if we are using a version of Vis Studio
|
||||
@ -273,6 +279,7 @@ $(variantDir)\local.make: checks
|
||||
@ echo HS_COMPANY=$(COMPANY_NAME) >> $@
|
||||
@ echo HS_FILEDESC=$(HS_FILEDESC) >> $@
|
||||
@ echo HOTSPOT_VM_DISTRO=$(HOTSPOT_VM_DISTRO) >> $@
|
||||
@ if "$(OPENJDK)" NEQ "" echo OPENJDK=$(OPENJDK) >> $@
|
||||
@ echo HS_COPYRIGHT=$(HOTSPOT_VM_COPYRIGHT) >> $@
|
||||
@ echo HS_NAME=$(PRODUCT_NAME) $(JDK_MKTG_VERSION) >> $@
|
||||
@ echo HS_BUILD_VER=$(HS_BUILD_VER) >> $@
|
||||
|
@ -71,13 +71,11 @@ for sd in \
|
||||
BASE_PATHS="${BASE_PATHS} ${COMMONSRC}/${sd}"
|
||||
done
|
||||
|
||||
BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles"
|
||||
BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles ${GENERATED}/tracefiles"
|
||||
|
||||
if [ -d "${ALTSRC}/share/vm/jfr" ]; then
|
||||
BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/agent"
|
||||
BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/agent/isolated_deps/util"
|
||||
BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/jvm"
|
||||
BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr"
|
||||
BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr"
|
||||
BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/buffers"
|
||||
fi
|
||||
|
||||
BASE_PATHS="${BASE_PATHS} ${COMMONSRC}/share/vm/prims/wbtestmethods"
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
# 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
|
||||
@ -30,15 +30,19 @@
|
||||
JvmtiOutDir=jvmtifiles
|
||||
!include $(WorkSpace)/make/windows/makefiles/jvmti.make
|
||||
|
||||
# Pick up rules for building trace
|
||||
TraceOutDir=tracefiles
|
||||
!include $(WorkSpace)/make/windows/makefiles/trace.make
|
||||
|
||||
# Pick up rules for building SA
|
||||
!include $(WorkSpace)/make/windows/makefiles/sa.make
|
||||
|
||||
AdlcOutDir=adfiles
|
||||
|
||||
!if ("$(Variant)" == "compiler2") || ("$(Variant)" == "tiered")
|
||||
default:: $(AdlcOutDir)/ad_$(Platform_arch_model).cpp $(AdlcOutDir)/dfa_$(Platform_arch_model).cpp $(JvmtiGeneratedFiles) buildobjfiles
|
||||
default:: $(AdlcOutDir)/ad_$(Platform_arch_model).cpp $(AdlcOutDir)/dfa_$(Platform_arch_model).cpp $(JvmtiGeneratedFiles) $(TraceGeneratedFiles) buildobjfiles
|
||||
!else
|
||||
default:: $(JvmtiGeneratedFiles) buildobjfiles
|
||||
default:: $(JvmtiGeneratedFiles) $(TraceGeneratedFiles) buildobjfiles
|
||||
!endif
|
||||
|
||||
buildobjfiles:
|
||||
|
@ -19,7 +19,7 @@
|
||||
# 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 $(WorkSpace)/make/windows/makefiles/rules.make
|
||||
@ -72,7 +72,7 @@ ProjectCreatorIncludesPRIVATE=\
|
||||
-ignorePath ppc \
|
||||
-ignorePath zero \
|
||||
-hidePath .hg
|
||||
|
||||
|
||||
|
||||
# This is referenced externally by both the IDE and batch builds
|
||||
ProjectCreatorOptions=
|
||||
@ -89,7 +89,7 @@ ProjectCreatorIDEOptions = \
|
||||
-disablePch bytecodeInterpreter.cpp \
|
||||
-disablePch bytecodeInterpreterWithChecks.cpp \
|
||||
-disablePch getThread_windows_$(Platform_arch).cpp \
|
||||
-disablePch_compiler2 opcodes.cpp
|
||||
-disablePch_compiler2 opcodes.cpp
|
||||
|
||||
# Common options for the IDE builds for core, c1, and c2
|
||||
ProjectCreatorIDEOptions=\
|
||||
@ -115,7 +115,7 @@ ProjectCreatorIDEOptions=\
|
||||
-define TARGET_OS_ARCH_windows_x86 \
|
||||
-define TARGET_OS_FAMILY_windows \
|
||||
-define TARGET_COMPILER_visCPP \
|
||||
-define INCLUDE_TRACE \
|
||||
-define INCLUDE_TRACE=1 \
|
||||
$(ProjectCreatorIncludesPRIVATE)
|
||||
|
||||
# Add in build-specific options
|
||||
@ -203,4 +203,12 @@ ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
|
||||
-additionalFile jvmtiEnter.cpp \
|
||||
-additionalFile jvmtiEnterTrace.cpp \
|
||||
-additionalFile jvmti.h \
|
||||
-additionalFile bytecodeInterpreterWithChecks.cpp
|
||||
-additionalFile bytecodeInterpreterWithChecks.cpp \
|
||||
-additionalFile traceEventClasses.hpp \
|
||||
-additionalFile traceEventIds.hpp \
|
||||
!if "$(OPENJDK)" != "true"
|
||||
-additionalFile traceRequestables.hpp \
|
||||
-additionalFile traceEventControl.hpp \
|
||||
-additionalFile traceProducer.cpp \
|
||||
!endif
|
||||
-additionalFile traceTypes.hpp
|
||||
|
121
hotspot/make/windows/makefiles/trace.make
Normal file
121
hotspot/make/windows/makefiles/trace.make
Normal file
@ -0,0 +1,121 @@
|
||||
#
|
||||
# Copyright (c) 2003, 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.
|
||||
#
|
||||
#
|
||||
|
||||
# This makefile (trace.make) is included from the trace.make in the
|
||||
# build directories.
|
||||
#
|
||||
# It knows how to build and run the tools to generate trace files.
|
||||
|
||||
!include $(WorkSpace)/make/windows/makefiles/rules.make
|
||||
|
||||
# #########################################################################
|
||||
|
||||
|
||||
TraceAltSrcDir = $(WorkSpace)/src/closed/share/vm/trace
|
||||
TraceSrcDir = $(WorkSpace)/src/share/vm/trace
|
||||
|
||||
TraceGeneratedNames = \
|
||||
traceEventClasses.hpp \
|
||||
traceEventIds.hpp \
|
||||
traceTypes.hpp
|
||||
|
||||
|
||||
!if "$(OPENJDK)" != "true"
|
||||
TraceGeneratedNames = $(TraceGeneratedNames) \
|
||||
traceRequestables.hpp \
|
||||
traceEventControl.hpp \
|
||||
traceProducer.cpp
|
||||
!endif
|
||||
|
||||
|
||||
#Note: TraceGeneratedFiles must be kept in sync with TraceGeneratedNames by hand.
|
||||
#Should be equivalent to "TraceGeneratedFiles = $(TraceGeneratedNames:%=$(TraceOutDir)/%)"
|
||||
TraceGeneratedFiles = \
|
||||
$(TraceOutDir)/traceEventClasses.hpp \
|
||||
$(TraceOutDir)/traceEventIds.hpp \
|
||||
$(TraceOutDir)/traceTypes.hpp
|
||||
|
||||
!if "$(OPENJDK)" != "true"
|
||||
TraceGeneratedFiles = $(TraceGeneratedFiles) \
|
||||
$(TraceOutDir)/traceRequestables.hpp \
|
||||
$(TraceOutDir)/traceEventControl.hpp \
|
||||
$(TraceOutDir)/traceProducer.cpp
|
||||
!endif
|
||||
|
||||
XSLT = $(QUIETLY) $(REMOTE) $(RUN_JAVA) -classpath $(JvmtiOutDir) jvmtiGen
|
||||
|
||||
XML_DEPS = $(TraceSrcDir)/trace.xml $(TraceSrcDir)/tracetypes.xml \
|
||||
$(TraceSrcDir)/trace.dtd $(TraceSrcDir)/xinclude.mod
|
||||
|
||||
!if "$(OPENJDK)" != "true"
|
||||
XML_DEPS = $(XML_DEPS) $(TraceAltSrcDir)/traceevents.xml
|
||||
!endif
|
||||
|
||||
.PHONY: all clean cleanall
|
||||
|
||||
# #########################################################################
|
||||
|
||||
default::
|
||||
@if not exist $(TraceOutDir) mkdir $(TraceOutDir)
|
||||
|
||||
$(TraceOutDir)/traceEventIds.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventIds.xsl $(XML_DEPS)
|
||||
@echo Generating $@
|
||||
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventIds.xsl -OUT $(TraceOutDir)/traceEventIds.hpp
|
||||
|
||||
$(TraceOutDir)/traceTypes.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceTypes.xsl $(XML_DEPS)
|
||||
@echo Generating $@
|
||||
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceTypes.xsl -OUT $(TraceOutDir)/traceTypes.hpp
|
||||
|
||||
!if "$(OPENJDK)" == "true"
|
||||
|
||||
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
|
||||
@echo Generating $@
|
||||
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
|
||||
|
||||
!else
|
||||
|
||||
$(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
|
||||
@echo Generating $@
|
||||
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
|
||||
|
||||
$(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
|
||||
@echo Generating $@
|
||||
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceProducer.xsl -OUT $(TraceOutDir)/traceProducer.cpp
|
||||
|
||||
$(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
|
||||
@echo Generating $@
|
||||
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp
|
||||
|
||||
$(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
|
||||
@echo Generating $@
|
||||
@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventControl.xsl -OUT $(TraceOutDir)/traceEventControl.hpp
|
||||
|
||||
!endif
|
||||
|
||||
# #########################################################################
|
||||
|
||||
cleanall :
|
||||
rm $(TraceGeneratedFiles)
|
||||
|
||||
|
@ -66,10 +66,6 @@ CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_BUILD_TARGET=\"$(BUILD_FLAVOR)\""
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_BUILD_USER=\"$(BuildUser)\""
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "HOTSPOT_VM_DISTRO=\"$(HOTSPOT_VM_DISTRO)\""
|
||||
|
||||
!ifndef JAVASE_EMBEDDED
|
||||
CXX_FLAGS=$(CXX_FLAGS) /D "INCLUDE_TRACE"
|
||||
!endif
|
||||
|
||||
CXX_FLAGS=$(CXX_FLAGS) $(CXX_INCLUDE_DIRS)
|
||||
|
||||
# Define that so jni.h is on correct side
|
||||
@ -144,6 +140,7 @@ CXX_USE_PCH=$(CXX_DONT_USE_PCH)
|
||||
VM_PATH=../generated
|
||||
VM_PATH=$(VM_PATH);../generated/adfiles
|
||||
VM_PATH=$(VM_PATH);../generated/jvmtifiles
|
||||
VM_PATH=$(VM_PATH);../generated/tracefiles
|
||||
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/c1
|
||||
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/compiler
|
||||
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/code
|
||||
@ -172,10 +169,8 @@ VM_PATH=$(VM_PATH);$(WorkSpace)/src/cpu/$(Platform_arch)/vm
|
||||
VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/opto
|
||||
|
||||
!if exists($(ALTSRC)\share\vm\jfr)
|
||||
VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/agent
|
||||
VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/agent/isolated_deps/util
|
||||
VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/jvm
|
||||
VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr
|
||||
VM_PATH=$(VM_PATH);$(ALTSRC)/share/vm/jfr/buffers
|
||||
!endif
|
||||
|
||||
VM_PATH={$(VM_PATH)}
|
||||
@ -384,16 +379,13 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi
|
||||
{..\generated\jvmtifiles}.cpp.obj::
|
||||
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
|
||||
|
||||
{..\generated\tracefiles}.cpp.obj::
|
||||
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
|
||||
|
||||
{$(ALTSRC)\share\vm\jfr}.cpp.obj::
|
||||
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
|
||||
|
||||
{$(ALTSRC)\share\vm\jfr\agent}.cpp.obj::
|
||||
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
|
||||
|
||||
{$(ALTSRC)\share\vm\jfr\agent\isolated_deps\util}.cpp.obj::
|
||||
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
|
||||
|
||||
{$(ALTSRC)\share\vm\jfr\jvm}.cpp.obj::
|
||||
{$(ALTSRC)\share\vm\jfr\buffers}.cpp.obj::
|
||||
$(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
|
||||
|
||||
default::
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 1999, 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
|
||||
@ -45,6 +45,12 @@ BootStrapDir=$(HOTSPOTJDKDIST)
|
||||
!endif
|
||||
!endif
|
||||
|
||||
# if hotspot-only build and/or OPENJDK isn't passed down, need to set OPENJDK
|
||||
!ifndef OPENJDK
|
||||
!if !exists($(WorkSpace)\src\closed)
|
||||
OPENJDK=true
|
||||
!endif
|
||||
!endif
|
||||
|
||||
|
||||
!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/projectcreator.make
|
||||
@ -54,6 +60,10 @@ BootStrapDir=$(HOTSPOTJDKDIST)
|
||||
JvmtiOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\jvmtifiles
|
||||
!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/jvmti.make
|
||||
|
||||
# Pick up rules for building trace
|
||||
TraceOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\tracefiles
|
||||
!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/trace.make
|
||||
|
||||
!if "$(Variant)" == "compiler2"
|
||||
# Pick up rules for building adlc
|
||||
!include $(HOTSPOTWORKSPACE)/make/windows/makefiles/adlc.make
|
||||
@ -66,7 +76,7 @@ JvmtiOutDir=$(HOTSPOTBUILDSPACE)\$(Variant)\generated\jvmtifiles
|
||||
|
||||
HS_INTERNAL_NAME=jvm
|
||||
|
||||
default:: $(AdditionalTargets) $(JvmtiGeneratedFiles)
|
||||
default:: $(AdditionalTargets) $(JvmtiGeneratedFiles) $(TraceGeneratedFiles)
|
||||
|
||||
!include $(HOTSPOTWORKSPACE)/make/hotspot_version
|
||||
|
||||
|
@ -1065,7 +1065,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
|
||||
const int slop_factor = 2*wordSize;
|
||||
|
||||
const int fixed_size = ((sizeof(BytecodeInterpreter) + slop_factor) >> LogBytesPerWord) + // what is the slop factor?
|
||||
//6815692//Method::extra_stack_words() + // extra push slots for MH adapters
|
||||
Method::extra_stack_entries() + // extra stack for jsr 292
|
||||
frame::memory_parameter_word_sp_offset + // register save area + param window
|
||||
(native ? frame::interpreter_frame_extra_outgoing_argument_words : 0); // JNI, class
|
||||
|
||||
@ -1221,9 +1221,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
|
||||
// Full size expression stack
|
||||
__ ld_ptr(constMethod, O3);
|
||||
__ lduh(O3, in_bytes(ConstMethod::max_stack_offset()), O3);
|
||||
guarantee(!EnableInvokeDynamic, "no support yet for java.lang.invoke.MethodHandle"); //6815692
|
||||
//6815692//if (EnableInvokeDynamic)
|
||||
//6815692// __ inc(O3, Method::extra_stack_entries());
|
||||
__ inc(O3, Method::extra_stack_entries());
|
||||
__ sll(O3, LogBytesPerWord, O3);
|
||||
__ sub(O2, O3, O3);
|
||||
// __ sub(O3, wordSize, O3); // so prepush doesn't look out of bounds
|
||||
@ -2084,9 +2082,7 @@ static int size_activation_helper(int callee_extra_locals, int max_stack, int mo
|
||||
|
||||
const int fixed_size = sizeof(BytecodeInterpreter)/wordSize + // interpreter state object
|
||||
frame::memory_parameter_word_sp_offset; // register save area + param window
|
||||
const int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
return (round_to(max_stack +
|
||||
extra_stack +
|
||||
slop_factor +
|
||||
fixed_size +
|
||||
monitor_size +
|
||||
@ -2173,8 +2169,7 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill,
|
||||
// Need +1 here because stack_base points to the word just above the first expr stack entry
|
||||
// and stack_limit is supposed to point to the word just below the last expr stack entry.
|
||||
// See generate_compute_interpreter_state.
|
||||
int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
to_fill->_stack_limit = stack_base - (method->max_stack() + 1 + extra_stack);
|
||||
to_fill->_stack_limit = stack_base - (method->max_stack() + 1);
|
||||
to_fill->_monitor_base = (BasicObjectLock*) monitor_base;
|
||||
|
||||
// sparc specific
|
||||
|
@ -252,6 +252,16 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Could be a zombie method
|
||||
if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Could be a zombie method
|
||||
if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// It should be safe to construct the sender though it might not be valid
|
||||
|
||||
frame sender(_SENDER_SP, younger_sp, adjusted_stack);
|
||||
@ -294,10 +304,10 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
return jcw_safe;
|
||||
}
|
||||
|
||||
// If the frame size is 0 something is bad because every nmethod has a non-zero frame size
|
||||
// If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
|
||||
// because you must allocate window space
|
||||
|
||||
if (sender_blob->frame_size() == 0) {
|
||||
if (sender_blob->frame_size() <= 0) {
|
||||
assert(!sender_blob->is_nmethod(), "should count return address at least");
|
||||
return false;
|
||||
}
|
||||
|
@ -521,7 +521,7 @@ void InterpreterMacroAssembler::empty_expression_stack() {
|
||||
// Compute max expression stack+register save area
|
||||
ld_ptr(Lmethod, in_bytes(Method::const_offset()), Gframe_size);
|
||||
lduh(Gframe_size, in_bytes(ConstMethod::max_stack_offset()), Gframe_size); // Load max stack.
|
||||
add( Gframe_size, frame::memory_parameter_word_sp_offset, Gframe_size );
|
||||
add(Gframe_size, frame::memory_parameter_word_sp_offset+Method::extra_stack_entries(), Gframe_size );
|
||||
|
||||
//
|
||||
// now set up a stack frame with the size computed above
|
||||
|
@ -507,7 +507,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
|
||||
|
||||
const int extra_space =
|
||||
rounded_vm_local_words + // frame local scratch space
|
||||
//6815692//Method::extra_stack_words() + // extra push slots for MH adapters
|
||||
Method::extra_stack_entries() + // extra stack for jsr 292
|
||||
frame::memory_parameter_word_sp_offset + // register save area
|
||||
(native_call ? frame::interpreter_frame_extra_outgoing_argument_words : 0);
|
||||
|
||||
@ -1558,7 +1558,6 @@ static int size_activation_helper(int callee_extra_locals, int max_stack, int mo
|
||||
round_to(callee_extra_locals * Interpreter::stackElementWords, WordsPerLong);
|
||||
const int max_stack_words = max_stack * Interpreter::stackElementWords;
|
||||
return (round_to((max_stack_words
|
||||
//6815692//+ Method::extra_stack_words()
|
||||
+ rounded_vm_local_words
|
||||
+ frame::memory_parameter_word_sp_offset), WordsPerLong)
|
||||
// already rounded
|
||||
|
@ -539,12 +539,11 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
|
||||
|
||||
// compute full expression stack limit
|
||||
|
||||
const int extra_stack = 0; //6815692//Method::extra_stack_words();
|
||||
__ movptr(rdx, Address(rbx, Method::const_offset()));
|
||||
__ load_unsigned_short(rdx, Address(rdx, ConstMethod::max_stack_offset())); // get size of expression stack in words
|
||||
__ negptr(rdx); // so we can subtract in next step
|
||||
// Allocate expression stack
|
||||
__ lea(rsp, Address(rsp, rdx, Address::times_ptr, -extra_stack));
|
||||
__ lea(rsp, Address(rsp, rdx, Address::times_ptr, -Method::extra_stack_words()));
|
||||
__ movptr(STATE(_stack_limit), rsp);
|
||||
}
|
||||
|
||||
@ -692,10 +691,9 @@ void InterpreterGenerator::generate_stack_overflow_check(void) {
|
||||
// Always give one monitor to allow us to start interp if sync method.
|
||||
// Any additional monitors need a check when moving the expression stack
|
||||
const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
|
||||
const int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
__ movptr(rax, Address(rbx, Method::const_offset()));
|
||||
__ load_unsigned_short(rax, Address(rax, ConstMethod::max_stack_offset())); // get size of expression stack in words
|
||||
__ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), extra_stack + one_monitor));
|
||||
__ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor+Method::extra_stack_words()));
|
||||
__ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size));
|
||||
|
||||
#ifdef ASSERT
|
||||
@ -2265,8 +2263,7 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
|
||||
const int overhead_size = sizeof(BytecodeInterpreter)/wordSize +
|
||||
( frame::sender_sp_offset - frame::link_offset) + 2;
|
||||
|
||||
const int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
|
||||
const int method_stack = (method->max_locals() + method->max_stack()) *
|
||||
Interpreter::stackElementWords;
|
||||
return overhead_size + method_stack + stub_code;
|
||||
}
|
||||
@ -2331,8 +2328,7 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill,
|
||||
// Need +1 here because stack_base points to the word just above the first expr stack entry
|
||||
// and stack_limit is supposed to point to the word just below the last expr stack entry.
|
||||
// See generate_compute_interpreter_state.
|
||||
int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
to_fill->_stack_limit = stack_base - (method->max_stack() + extra_stack + 1);
|
||||
to_fill->_stack_limit = stack_base - (method->max_stack() + 1);
|
||||
to_fill->_monitor_base = (BasicObjectLock*) monitor_base;
|
||||
|
||||
to_fill->_self_link = to_fill;
|
||||
@ -2380,8 +2376,7 @@ int AbstractInterpreter::layout_activation(Method* method,
|
||||
monitor_size);
|
||||
|
||||
// Now with full size expression stack
|
||||
int extra_stack = 0; //6815692//Method::extra_stack_entries();
|
||||
int full_frame_size = short_frame_size + (method->max_stack() + extra_stack) * BytesPerWord;
|
||||
int full_frame_size = short_frame_size + method->max_stack() * BytesPerWord;
|
||||
|
||||
// and now with only live portion of the expression stack
|
||||
short_frame_size = short_frame_size + tempcount * BytesPerWord;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -33,6 +33,7 @@
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/javaCalls.hpp"
|
||||
#include "runtime/monitorChunk.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/signature.hpp"
|
||||
#include "runtime/stubCodeGenerator.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -54,16 +55,22 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
address sp = (address)_sp;
|
||||
address fp = (address)_fp;
|
||||
address unextended_sp = (address)_unextended_sp;
|
||||
// sp must be within the stack
|
||||
bool sp_safe = (sp <= thread->stack_base()) &&
|
||||
(sp >= thread->stack_base() - thread->stack_size());
|
||||
|
||||
// consider stack guards when trying to determine "safe" stack pointers
|
||||
static size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
|
||||
size_t usable_stack_size = thread->stack_size() - stack_guard_size;
|
||||
|
||||
// sp must be within the usable part of the stack (not in guards)
|
||||
bool sp_safe = (sp < thread->stack_base()) &&
|
||||
(sp >= thread->stack_base() - usable_stack_size);
|
||||
|
||||
|
||||
if (!sp_safe) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// unextended sp must be within the stack and above or equal sp
|
||||
bool unextended_sp_safe = (unextended_sp <= thread->stack_base()) &&
|
||||
bool unextended_sp_safe = (unextended_sp < thread->stack_base()) &&
|
||||
(unextended_sp >= sp);
|
||||
|
||||
if (!unextended_sp_safe) {
|
||||
@ -71,7 +78,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
}
|
||||
|
||||
// an fp must be within the stack and above (but not equal) sp
|
||||
bool fp_safe = (fp <= thread->stack_base()) && (fp > sp);
|
||||
// second evaluation on fp+ is added to handle situation where fp is -1
|
||||
bool fp_safe = (fp < thread->stack_base() && (fp > sp) && (((fp + (return_addr_offset * sizeof(void*))) < thread->stack_base())));
|
||||
|
||||
// We know sp/unextended_sp are safe only fp is questionable here
|
||||
|
||||
@ -86,6 +94,13 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
// other generic buffer blobs are more problematic so we just assume they are
|
||||
// ok. adapter blobs never have a frame complete and are never ok.
|
||||
|
||||
// check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc
|
||||
|
||||
if (!Interpreter::contains(_pc) && _cb->frame_size() <= 0) {
|
||||
//assert(0, "Invalid frame_size");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_cb->is_frame_complete_at(_pc)) {
|
||||
if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
|
||||
return false;
|
||||
@ -107,7 +122,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
address jcw = (address)entry_frame_call_wrapper();
|
||||
|
||||
bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > fp);
|
||||
bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp);
|
||||
|
||||
return jcw_safe;
|
||||
|
||||
@ -134,12 +149,6 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
sender_pc = (address) *(sender_sp-1);
|
||||
}
|
||||
|
||||
// We must always be able to find a recognizable pc
|
||||
CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
|
||||
if (sender_pc == NULL || sender_blob == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// If the potential sender is the interpreter then we can do some more checking
|
||||
if (Interpreter::contains(sender_pc)) {
|
||||
@ -149,7 +158,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
// is really a frame pointer.
|
||||
|
||||
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
|
||||
bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp > sender_sp);
|
||||
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
|
||||
|
||||
if (!saved_fp_safe) {
|
||||
return false;
|
||||
@ -163,6 +172,17 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
}
|
||||
|
||||
// We must always be able to find a recognizable pc
|
||||
CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
|
||||
if (sender_pc == NULL || sender_blob == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Could be a zombie method
|
||||
if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Could just be some random pointer within the codeBlob
|
||||
if (!sender_blob->code_contains(sender_pc)) {
|
||||
return false;
|
||||
@ -174,10 +194,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
}
|
||||
|
||||
// Could be the call_stub
|
||||
|
||||
if (StubRoutines::returns_to_call_stub(sender_pc)) {
|
||||
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
|
||||
bool saved_fp_safe = ((address)saved_fp <= thread->stack_base()) && (saved_fp > sender_sp);
|
||||
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
|
||||
|
||||
if (!saved_fp_safe) {
|
||||
return false;
|
||||
@ -190,15 +209,24 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
// Validate the JavaCallWrapper an entry frame must have
|
||||
address jcw = (address)sender.entry_frame_call_wrapper();
|
||||
|
||||
bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > (address)sender.fp());
|
||||
bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp());
|
||||
|
||||
return jcw_safe;
|
||||
}
|
||||
|
||||
// If the frame size is 0 something is bad because every nmethod has a non-zero frame size
|
||||
if (sender_blob->is_nmethod()) {
|
||||
nmethod* nm = sender_blob->as_nmethod_or_null();
|
||||
if (nm != NULL) {
|
||||
if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
|
||||
// because the return address counts against the callee's frame.
|
||||
|
||||
if (sender_blob->frame_size() == 0) {
|
||||
if (sender_blob->frame_size() <= 0) {
|
||||
assert(!sender_blob->is_nmethod(), "should count return address at least");
|
||||
return false;
|
||||
}
|
||||
@ -208,7 +236,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
// should not be anything but the call stub (already covered), the interpreter (already covered)
|
||||
// or an nmethod.
|
||||
|
||||
assert(sender_blob->is_nmethod(), "Impossible call chain");
|
||||
if (!sender_blob->is_nmethod()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Could put some more validation for the potential non-interpreted sender
|
||||
// frame we'd create by calling sender if I could think of any. Wait for next crash in forte...
|
||||
|
@ -1565,8 +1565,7 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
|
||||
// be sure to change this if you add/subtract anything to/from the overhead area
|
||||
const int overhead_size = -frame::interpreter_frame_initial_sp_offset;
|
||||
|
||||
const int extra_stack = Method::extra_stack_entries();
|
||||
const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
|
||||
const int method_stack = (method->max_locals() + method->max_stack()) *
|
||||
Interpreter::stackElementWords;
|
||||
return overhead_size + method_stack + stub_code;
|
||||
}
|
||||
|
@ -1574,8 +1574,7 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
|
||||
-(frame::interpreter_frame_initial_sp_offset) + entry_size;
|
||||
|
||||
const int stub_code = frame::entry_frame_after_call_words;
|
||||
const int extra_stack = Method::extra_stack_entries();
|
||||
const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
|
||||
const int method_stack = (method->max_locals() + method->max_stack()) *
|
||||
Interpreter::stackElementWords;
|
||||
return (overhead_size + method_stack + stub_code);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -94,7 +94,7 @@ public:
|
||||
// flags that support signal based suspend/resume on Bsd are in a
|
||||
// separate class to avoid confusion with many flags in OSThread that
|
||||
// are used by VM level suspend/resume.
|
||||
os::Bsd::SuspendResume sr;
|
||||
os::SuspendResume sr;
|
||||
|
||||
// _ucontext and _siginfo are used by SR_handler() to save thread context,
|
||||
// and they will later be used to walk the stack or reposition thread PC.
|
||||
|
@ -626,8 +626,6 @@ void os::Bsd::hotspot_sigmask(Thread* thread) {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// create new thread
|
||||
|
||||
static address highest_vm_reserved_address();
|
||||
|
||||
// check if it's safe to start a new thread
|
||||
static bool _thread_safety_check(Thread* thread) {
|
||||
return true;
|
||||
@ -935,10 +933,10 @@ jlong os::elapsed_frequency() {
|
||||
return (1000 * 1000);
|
||||
}
|
||||
|
||||
// XXX: For now, code this as if BSD does not support vtime.
|
||||
bool os::supports_vtime() { return false; }
|
||||
bool os::supports_vtime() { return true; }
|
||||
bool os::enable_vtime() { return false; }
|
||||
bool os::vtime_enabled() { return false; }
|
||||
|
||||
double os::elapsedVTime() {
|
||||
// better than nothing, but not much
|
||||
return elapsedTime();
|
||||
@ -1854,17 +1852,118 @@ static volatile jint pending_signals[NSIG+1] = { 0 };
|
||||
|
||||
// Bsd(POSIX) specific hand shaking semaphore.
|
||||
#ifdef __APPLE__
|
||||
static semaphore_t sig_sem;
|
||||
typedef semaphore_t os_semaphore_t;
|
||||
#define SEM_INIT(sem, value) semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, value)
|
||||
#define SEM_WAIT(sem) semaphore_wait(sem);
|
||||
#define SEM_POST(sem) semaphore_signal(sem);
|
||||
#define SEM_WAIT(sem) semaphore_wait(sem)
|
||||
#define SEM_POST(sem) semaphore_signal(sem)
|
||||
#define SEM_DESTROY(sem) semaphore_destroy(mach_task_self(), sem)
|
||||
#else
|
||||
static sem_t sig_sem;
|
||||
typedef sem_t os_semaphore_t;
|
||||
#define SEM_INIT(sem, value) sem_init(&sem, 0, value)
|
||||
#define SEM_WAIT(sem) sem_wait(&sem);
|
||||
#define SEM_POST(sem) sem_post(&sem);
|
||||
#define SEM_WAIT(sem) sem_wait(&sem)
|
||||
#define SEM_POST(sem) sem_post(&sem)
|
||||
#define SEM_DESTROY(sem) sem_destroy(&sem)
|
||||
#endif
|
||||
|
||||
class Semaphore : public StackObj {
|
||||
public:
|
||||
Semaphore();
|
||||
~Semaphore();
|
||||
void signal();
|
||||
void wait();
|
||||
bool trywait();
|
||||
bool timedwait(unsigned int sec, int nsec);
|
||||
private:
|
||||
jlong currenttime() const;
|
||||
semaphore_t _semaphore;
|
||||
};
|
||||
|
||||
Semaphore::Semaphore() : _semaphore(0) {
|
||||
SEM_INIT(_semaphore, 0);
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore() {
|
||||
SEM_DESTROY(_semaphore);
|
||||
}
|
||||
|
||||
void Semaphore::signal() {
|
||||
SEM_POST(_semaphore);
|
||||
}
|
||||
|
||||
void Semaphore::wait() {
|
||||
SEM_WAIT(_semaphore);
|
||||
}
|
||||
|
||||
jlong Semaphore::currenttime() const {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (tv.tv_sec * NANOSECS_PER_SEC) + (tv.tv_usec * 1000);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
bool Semaphore::trywait() {
|
||||
return timedwait(0, 0);
|
||||
}
|
||||
|
||||
bool Semaphore::timedwait(unsigned int sec, int nsec) {
|
||||
kern_return_t kr = KERN_ABORTED;
|
||||
mach_timespec_t waitspec;
|
||||
waitspec.tv_sec = sec;
|
||||
waitspec.tv_nsec = nsec;
|
||||
|
||||
jlong starttime = currenttime();
|
||||
|
||||
kr = semaphore_timedwait(_semaphore, waitspec);
|
||||
while (kr == KERN_ABORTED) {
|
||||
jlong totalwait = (sec * NANOSECS_PER_SEC) + nsec;
|
||||
|
||||
jlong current = currenttime();
|
||||
jlong passedtime = current - starttime;
|
||||
|
||||
if (passedtime >= totalwait) {
|
||||
waitspec.tv_sec = 0;
|
||||
waitspec.tv_nsec = 0;
|
||||
} else {
|
||||
jlong waittime = totalwait - (current - starttime);
|
||||
waitspec.tv_sec = waittime / NANOSECS_PER_SEC;
|
||||
waitspec.tv_nsec = waittime % NANOSECS_PER_SEC;
|
||||
}
|
||||
|
||||
kr = semaphore_timedwait(_semaphore, waitspec);
|
||||
}
|
||||
|
||||
return kr == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool Semaphore::trywait() {
|
||||
return sem_trywait(&_semaphore) == 0;
|
||||
}
|
||||
|
||||
bool Semaphore::timedwait(unsigned int sec, int nsec) {
|
||||
struct timespec ts;
|
||||
jlong endtime = unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
|
||||
|
||||
while (1) {
|
||||
int result = sem_timedwait(&_semaphore, &ts);
|
||||
if (result == 0) {
|
||||
return true;
|
||||
} else if (errno == EINTR) {
|
||||
continue;
|
||||
} else if (errno == ETIMEDOUT) {
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
static os_semaphore_t sig_sem;
|
||||
static Semaphore sr_semaphore;
|
||||
|
||||
void os::signal_init_pd() {
|
||||
// Initialize signal structures
|
||||
::memset((void*)pending_signals, 0, sizeof(pending_signals));
|
||||
@ -2112,10 +2211,6 @@ bool os::pd_release_memory(char* addr, size_t size) {
|
||||
return anon_munmap(addr, size);
|
||||
}
|
||||
|
||||
static address highest_vm_reserved_address() {
|
||||
return _highest_vm_reserved_address;
|
||||
}
|
||||
|
||||
static bool bsd_mprotect(char* addr, size_t size, int prot) {
|
||||
// Bsd wants the mprotect address argument to be page aligned.
|
||||
char* bottom = (char*)align_size_down((intptr_t)addr, os::Bsd::page_size());
|
||||
@ -2159,43 +2254,6 @@ bool os::Bsd::hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the coredump_filter bits to include largepages in core dump (bit 6)
|
||||
*
|
||||
* From the coredump_filter documentation:
|
||||
*
|
||||
* - (bit 0) anonymous private memory
|
||||
* - (bit 1) anonymous shared memory
|
||||
* - (bit 2) file-backed private memory
|
||||
* - (bit 3) file-backed shared memory
|
||||
* - (bit 4) ELF header pages in file-backed private memory areas (it is
|
||||
* effective only if the bit 2 is cleared)
|
||||
* - (bit 5) hugetlb private memory
|
||||
* - (bit 6) hugetlb shared memory
|
||||
*/
|
||||
static void set_coredump_filter(void) {
|
||||
FILE *f;
|
||||
long cdm;
|
||||
|
||||
if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fscanf(f, "%lx", &cdm) != 1) {
|
||||
fclose(f);
|
||||
return;
|
||||
}
|
||||
|
||||
rewind(f);
|
||||
|
||||
if ((cdm & LARGEPAGES_BIT) == 0) {
|
||||
cdm |= LARGEPAGES_BIT;
|
||||
fprintf(f, "%#lx", cdm);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
// Large page support
|
||||
|
||||
static size_t _large_page_size = 0;
|
||||
@ -2659,9 +2717,6 @@ void os::hint_no_preempt() {}
|
||||
static void resume_clear_context(OSThread *osthread) {
|
||||
osthread->set_ucontext(NULL);
|
||||
osthread->set_siginfo(NULL);
|
||||
|
||||
// notify the suspend action is completed, we have now resumed
|
||||
osthread->sr.clear_suspended();
|
||||
}
|
||||
|
||||
static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
|
||||
@ -2681,7 +2736,7 @@ static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontex
|
||||
// its signal handlers run and prevents sigwait()'s use with the
|
||||
// mutex granting granting signal.
|
||||
//
|
||||
// Currently only ever called on the VMThread
|
||||
// Currently only ever called on the VMThread or JavaThread
|
||||
//
|
||||
static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
|
||||
// Save and restore errno to avoid confusing native code with EINTR
|
||||
@ -2690,38 +2745,48 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
|
||||
|
||||
Thread* thread = Thread::current();
|
||||
OSThread* osthread = thread->osthread();
|
||||
assert(thread->is_VM_thread(), "Must be VMThread");
|
||||
// read current suspend action
|
||||
int action = osthread->sr.suspend_action();
|
||||
if (action == os::Bsd::SuspendResume::SR_SUSPEND) {
|
||||
assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
|
||||
|
||||
os::SuspendResume::State current = osthread->sr.state();
|
||||
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
|
||||
suspend_save_context(osthread, siginfo, context);
|
||||
|
||||
// Notify the suspend action is about to be completed. do_suspend()
|
||||
// waits until SR_SUSPENDED is set and then returns. We will wait
|
||||
// here for a resume signal and that completes the suspend-other
|
||||
// action. do_suspend/do_resume is always called as a pair from
|
||||
// the same thread - so there are no races
|
||||
// attempt to switch the state, we assume we had a SUSPEND_REQUEST
|
||||
os::SuspendResume::State state = osthread->sr.suspended();
|
||||
if (state == os::SuspendResume::SR_SUSPENDED) {
|
||||
sigset_t suspend_set; // signals for sigsuspend()
|
||||
|
||||
// notify the caller
|
||||
osthread->sr.set_suspended();
|
||||
// get current set of blocked signals and unblock resume signal
|
||||
pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
|
||||
sigdelset(&suspend_set, SR_signum);
|
||||
|
||||
sigset_t suspend_set; // signals for sigsuspend()
|
||||
sr_semaphore.signal();
|
||||
// wait here until we are resumed
|
||||
while (1) {
|
||||
sigsuspend(&suspend_set);
|
||||
|
||||
// get current set of blocked signals and unblock resume signal
|
||||
pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
|
||||
sigdelset(&suspend_set, SR_signum);
|
||||
os::SuspendResume::State result = osthread->sr.running();
|
||||
if (result == os::SuspendResume::SR_RUNNING) {
|
||||
sr_semaphore.signal();
|
||||
break;
|
||||
} else if (result != os::SuspendResume::SR_SUSPENDED) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
// wait here until we are resumed
|
||||
do {
|
||||
sigsuspend(&suspend_set);
|
||||
// ignore all returns until we get a resume signal
|
||||
} while (osthread->sr.suspend_action() != os::Bsd::SuspendResume::SR_CONTINUE);
|
||||
} else if (state == os::SuspendResume::SR_RUNNING) {
|
||||
// request was cancelled, continue
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
resume_clear_context(osthread);
|
||||
|
||||
} else if (current == os::SuspendResume::SR_RUNNING) {
|
||||
// request was cancelled, continue
|
||||
} else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
|
||||
// ignore
|
||||
} else {
|
||||
assert(action == os::Bsd::SuspendResume::SR_CONTINUE, "unexpected sr action");
|
||||
// nothing special to do - just leave the handler
|
||||
// ignore
|
||||
}
|
||||
|
||||
errno = old_errno;
|
||||
@ -2765,42 +2830,82 @@ static int SR_initialize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sr_notify(OSThread* osthread) {
|
||||
int status = pthread_kill(osthread->pthread_id(), SR_signum);
|
||||
assert_status(status == 0, status, "pthread_kill");
|
||||
return status;
|
||||
}
|
||||
|
||||
// "Randomly" selected value for how long we want to spin
|
||||
// before bailing out on suspending a thread, also how often
|
||||
// we send a signal to a thread we want to resume
|
||||
static const int RANDOMLY_LARGE_INTEGER = 1000000;
|
||||
static const int RANDOMLY_LARGE_INTEGER2 = 100;
|
||||
|
||||
// returns true on success and false on error - really an error is fatal
|
||||
// but this seems the normal response to library errors
|
||||
static bool do_suspend(OSThread* osthread) {
|
||||
// mark as suspended and send signal
|
||||
osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_SUSPEND);
|
||||
int status = pthread_kill(osthread->pthread_id(), SR_signum);
|
||||
assert_status(status == 0, status, "pthread_kill");
|
||||
assert(osthread->sr.is_running(), "thread should be running");
|
||||
assert(!sr_semaphore.trywait(), "semaphore has invalid state");
|
||||
|
||||
// check status and wait until notified of suspension
|
||||
if (status == 0) {
|
||||
for (int i = 0; !osthread->sr.is_suspended(); i++) {
|
||||
os::yield_all(i);
|
||||
}
|
||||
osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
|
||||
// mark as suspended and send signal
|
||||
if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
|
||||
// failed to switch, state wasn't running?
|
||||
ShouldNotReachHere();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sr_notify(osthread) != 0) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
|
||||
while (true) {
|
||||
if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
|
||||
break;
|
||||
} else {
|
||||
// timeout
|
||||
os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
|
||||
if (cancelled == os::SuspendResume::SR_RUNNING) {
|
||||
return false;
|
||||
} else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
|
||||
// make sure that we consume the signal on the semaphore as well
|
||||
sr_semaphore.wait();
|
||||
break;
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
guarantee(osthread->sr.is_suspended(), "Must be suspended");
|
||||
return true;
|
||||
}
|
||||
|
||||
static void do_resume(OSThread* osthread) {
|
||||
assert(osthread->sr.is_suspended(), "thread should be suspended");
|
||||
osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_CONTINUE);
|
||||
assert(!sr_semaphore.trywait(), "invalid semaphore state");
|
||||
|
||||
int status = pthread_kill(osthread->pthread_id(), SR_signum);
|
||||
assert_status(status == 0, status, "pthread_kill");
|
||||
// check status and wait unit notified of resumption
|
||||
if (status == 0) {
|
||||
for (int i = 0; osthread->sr.is_suspended(); i++) {
|
||||
os::yield_all(i);
|
||||
if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
|
||||
// failed to switch to WAKEUP_REQUEST
|
||||
ShouldNotReachHere();
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (sr_notify(osthread) == 0) {
|
||||
if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
|
||||
if (osthread->sr.is_running()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
|
||||
|
||||
guarantee(osthread->sr.is_running(), "Must be running!");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -3030,6 +3135,19 @@ void os::Bsd::set_signal_handler(int sig, bool set_installed) {
|
||||
sigAct.sa_sigaction = signalHandler;
|
||||
sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
|
||||
}
|
||||
#if __APPLE__
|
||||
// Needed for main thread as XNU (Mac OS X kernel) will only deliver SIGSEGV
|
||||
// (which starts as SIGBUS) on main thread with faulting address inside "stack+guard pages"
|
||||
// if the signal handler declares it will handle it on alternate stack.
|
||||
// Notice we only declare we will handle it on alt stack, but we are not
|
||||
// actually going to use real alt stack - this is just a workaround.
|
||||
// Please see ux_exception.c, method catch_mach_exception_raise for details
|
||||
// link http://www.opensource.apple.com/source/xnu/xnu-2050.18.24/bsd/uxkern/ux_exception.c
|
||||
if (sig == SIGSEGV) {
|
||||
sigAct.sa_flags |= SA_ONSTACK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Save flags, which are set by ours
|
||||
assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
|
||||
sigflags[sig] = sigAct.sa_flags;
|
||||
@ -3538,7 +3656,40 @@ bool os::bind_to_processor(uint processor_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void os::SuspendedThreadTask::internal_do_task() {
|
||||
if (do_suspend(_thread->osthread())) {
|
||||
SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
|
||||
do_task(context);
|
||||
do_resume(_thread->osthread());
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
class PcFetcher : public os::SuspendedThreadTask {
|
||||
public:
|
||||
PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
|
||||
ExtendedPC result();
|
||||
protected:
|
||||
void do_task(const os::SuspendedThreadTaskContext& context);
|
||||
private:
|
||||
ExtendedPC _epc;
|
||||
};
|
||||
|
||||
ExtendedPC PcFetcher::result() {
|
||||
guarantee(is_done(), "task is not done yet.");
|
||||
return _epc;
|
||||
}
|
||||
|
||||
void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
|
||||
Thread* thread = context.thread();
|
||||
OSThread* osthread = thread->osthread();
|
||||
if (osthread->ucontext() != NULL) {
|
||||
_epc = os::Bsd::ucontext_get_pc((ucontext_t *) context.ucontext());
|
||||
} else {
|
||||
// NULL context is unexpected, double-check this is the VMThread
|
||||
guarantee(thread->is_VM_thread(), "can only be called for VMThread");
|
||||
}
|
||||
}
|
||||
|
||||
// Suspends the target using the signal mechanism and then grabs the PC before
|
||||
// resuming the target. Used by the flat-profiler only
|
||||
@ -3547,22 +3698,9 @@ ExtendedPC os::get_thread_pc(Thread* thread) {
|
||||
assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
|
||||
assert(thread->is_VM_thread(), "Can only be called for VMThread");
|
||||
|
||||
ExtendedPC epc;
|
||||
|
||||
OSThread* osthread = thread->osthread();
|
||||
if (do_suspend(osthread)) {
|
||||
if (osthread->ucontext() != NULL) {
|
||||
epc = os::Bsd::ucontext_get_pc(osthread->ucontext());
|
||||
} else {
|
||||
// NULL context is unexpected, double-check this is the VMThread
|
||||
guarantee(thread->is_VM_thread(), "can only be called for VMThread");
|
||||
}
|
||||
do_resume(osthread);
|
||||
}
|
||||
// failure means pthread_kill failed for some reason - arguably this is
|
||||
// a fatal problem, but such problems are ignored elsewhere
|
||||
|
||||
return epc;
|
||||
PcFetcher fetcher(thread);
|
||||
fetcher.run();
|
||||
return fetcher.result();
|
||||
}
|
||||
|
||||
int os::Bsd::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime)
|
||||
@ -4547,3 +4685,4 @@ int os::get_core_path(char* buffer, size_t bufferSize) {
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -145,36 +145,6 @@ class Bsd {
|
||||
// BsdThreads work-around for 6292965
|
||||
static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);
|
||||
|
||||
|
||||
// Bsd suspend/resume support - this helper is a shadow of its former
|
||||
// self now that low-level suspension is barely used, and old workarounds
|
||||
// for BsdThreads are no longer needed.
|
||||
class SuspendResume {
|
||||
private:
|
||||
volatile int _suspend_action;
|
||||
volatile jint _state;
|
||||
public:
|
||||
// values for suspend_action:
|
||||
enum {
|
||||
SR_NONE = 0x00,
|
||||
SR_SUSPEND = 0x01, // suspend request
|
||||
SR_CONTINUE = 0x02, // resume request
|
||||
SR_SUSPENDED = 0x20 // values for _state: + SR_NONE
|
||||
};
|
||||
|
||||
SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; }
|
||||
|
||||
int suspend_action() const { return _suspend_action; }
|
||||
void set_suspend_action(int x) { _suspend_action = x; }
|
||||
|
||||
// atomic updates for _state
|
||||
inline void set_suspended();
|
||||
inline void clear_suspended();
|
||||
bool is_suspended() { return _state & SR_SUSPENDED; }
|
||||
|
||||
#undef SR_SUSPENDED
|
||||
};
|
||||
|
||||
private:
|
||||
typedef int (*sched_getcpu_func_t)(void);
|
||||
typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
|
||||
@ -250,7 +220,7 @@ class PlatformEvent : public CHeapObj<mtInternal> {
|
||||
int TryPark () ;
|
||||
int park (jlong millis) ;
|
||||
void SetAssociation (Thread * a) { _Assoc = a ; }
|
||||
} ;
|
||||
};
|
||||
|
||||
class PlatformParker : public CHeapObj<mtInternal> {
|
||||
protected:
|
||||
@ -268,6 +238,6 @@ class PlatformParker : public CHeapObj<mtInternal> {
|
||||
status = pthread_mutex_init (_mutex, NULL);
|
||||
assert_status(status == 0, status, "mutex_init");
|
||||
}
|
||||
} ;
|
||||
};
|
||||
|
||||
#endif // OS_BSD_VM_OS_BSD_HPP
|
||||
|
@ -286,20 +286,4 @@ inline int os::set_sock_opt(int fd, int level, int optname,
|
||||
return ::setsockopt(fd, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
inline void os::Bsd::SuspendResume::set_suspended() {
|
||||
jint temp, temp2;
|
||||
do {
|
||||
temp = _state;
|
||||
temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
|
||||
} while (temp2 != temp);
|
||||
}
|
||||
|
||||
inline void os::Bsd::SuspendResume::clear_suspended() {
|
||||
jint temp, temp2;
|
||||
do {
|
||||
temp = _state;
|
||||
temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
|
||||
} while (temp2 != temp);
|
||||
}
|
||||
|
||||
#endif // OS_BSD_VM_OS_BSD_INLINE_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -77,7 +77,7 @@ public:
|
||||
// flags that support signal based suspend/resume on Linux are in a
|
||||
// separate class to avoid confusion with many flags in OSThread that
|
||||
// are used by VM level suspend/resume.
|
||||
os::Linux::SuspendResume sr;
|
||||
os::SuspendResume sr;
|
||||
|
||||
// _ucontext and _siginfo are used by SR_handler() to save thread context,
|
||||
// and they will later be used to walk the stack or reposition thread PC.
|
||||
|
@ -101,6 +101,12 @@
|
||||
# include <inttypes.h>
|
||||
# include <sys/ioctl.h>
|
||||
|
||||
// if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
|
||||
// getrusage() is prepared to handle the associated failure.
|
||||
#ifndef RUSAGE_THREAD
|
||||
#define RUSAGE_THREAD (1) /* only the calling thread */
|
||||
#endif
|
||||
|
||||
#define MAX_PATH (2 * K)
|
||||
|
||||
// for timer info max values which include all bits
|
||||
@ -145,6 +151,9 @@ sigset_t SR_sigset;
|
||||
/* Used to protect dlsym() calls */
|
||||
static pthread_mutex_t dl_mutex;
|
||||
|
||||
// Declarations
|
||||
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
|
||||
|
||||
#ifdef JAVASE_EMBEDDED
|
||||
class MemNotifyThread: public Thread {
|
||||
friend class VMStructs;
|
||||
@ -1336,15 +1345,19 @@ jlong os::elapsed_frequency() {
|
||||
return (1000 * 1000);
|
||||
}
|
||||
|
||||
// For now, we say that linux does not support vtime. I have no idea
|
||||
// whether it can actually be made to (DLD, 9/13/05).
|
||||
|
||||
bool os::supports_vtime() { return false; }
|
||||
bool os::supports_vtime() { return true; }
|
||||
bool os::enable_vtime() { return false; }
|
||||
bool os::vtime_enabled() { return false; }
|
||||
|
||||
double os::elapsedVTime() {
|
||||
// better than nothing, but not much
|
||||
return elapsedTime();
|
||||
struct rusage usage;
|
||||
int retval = getrusage(RUSAGE_THREAD, &usage);
|
||||
if (retval == 0) {
|
||||
return (double) (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) + (double) (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000 * 1000);
|
||||
} else {
|
||||
// better than nothing, but not much
|
||||
return elapsedTime();
|
||||
}
|
||||
}
|
||||
|
||||
jlong os::javaTimeMillis() {
|
||||
@ -2397,6 +2410,57 @@ void* os::user_handler() {
|
||||
return CAST_FROM_FN_PTR(void*, UserHandler);
|
||||
}
|
||||
|
||||
class Semaphore : public StackObj {
|
||||
public:
|
||||
Semaphore();
|
||||
~Semaphore();
|
||||
void signal();
|
||||
void wait();
|
||||
bool trywait();
|
||||
bool timedwait(unsigned int sec, int nsec);
|
||||
private:
|
||||
sem_t _semaphore;
|
||||
};
|
||||
|
||||
|
||||
Semaphore::Semaphore() {
|
||||
sem_init(&_semaphore, 0, 0);
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore() {
|
||||
sem_destroy(&_semaphore);
|
||||
}
|
||||
|
||||
void Semaphore::signal() {
|
||||
sem_post(&_semaphore);
|
||||
}
|
||||
|
||||
void Semaphore::wait() {
|
||||
sem_wait(&_semaphore);
|
||||
}
|
||||
|
||||
bool Semaphore::trywait() {
|
||||
return sem_trywait(&_semaphore) == 0;
|
||||
}
|
||||
|
||||
bool Semaphore::timedwait(unsigned int sec, int nsec) {
|
||||
struct timespec ts;
|
||||
unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
|
||||
|
||||
while (1) {
|
||||
int result = sem_timedwait(&_semaphore, &ts);
|
||||
if (result == 0) {
|
||||
return true;
|
||||
} else if (errno == EINTR) {
|
||||
continue;
|
||||
} else if (errno == ETIMEDOUT) {
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
typedef void (*sa_handler_t)(int);
|
||||
typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
|
||||
@ -2436,6 +2500,7 @@ static volatile jint pending_signals[NSIG+1] = { 0 };
|
||||
|
||||
// Linux(POSIX) specific hand shaking semaphore.
|
||||
static sem_t sig_sem;
|
||||
static Semaphore sr_semaphore;
|
||||
|
||||
void os::signal_init_pd() {
|
||||
// Initialize signal structures
|
||||
@ -3549,9 +3614,6 @@ void os::hint_no_preempt() {}
|
||||
static void resume_clear_context(OSThread *osthread) {
|
||||
osthread->set_ucontext(NULL);
|
||||
osthread->set_siginfo(NULL);
|
||||
|
||||
// notify the suspend action is completed, we have now resumed
|
||||
osthread->sr.clear_suspended();
|
||||
}
|
||||
|
||||
static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
|
||||
@ -3571,7 +3633,7 @@ static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontex
|
||||
// its signal handlers run and prevents sigwait()'s use with the
|
||||
// mutex granting granting signal.
|
||||
//
|
||||
// Currently only ever called on the VMThread
|
||||
// Currently only ever called on the VMThread and JavaThreads (PC sampling)
|
||||
//
|
||||
static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
|
||||
// Save and restore errno to avoid confusing native code with EINTR
|
||||
@ -3580,38 +3642,46 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
|
||||
|
||||
Thread* thread = Thread::current();
|
||||
OSThread* osthread = thread->osthread();
|
||||
assert(thread->is_VM_thread(), "Must be VMThread");
|
||||
// read current suspend action
|
||||
int action = osthread->sr.suspend_action();
|
||||
if (action == os::Linux::SuspendResume::SR_SUSPEND) {
|
||||
assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
|
||||
|
||||
os::SuspendResume::State current = osthread->sr.state();
|
||||
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
|
||||
suspend_save_context(osthread, siginfo, context);
|
||||
|
||||
// Notify the suspend action is about to be completed. do_suspend()
|
||||
// waits until SR_SUSPENDED is set and then returns. We will wait
|
||||
// here for a resume signal and that completes the suspend-other
|
||||
// action. do_suspend/do_resume is always called as a pair from
|
||||
// the same thread - so there are no races
|
||||
// attempt to switch the state, we assume we had a SUSPEND_REQUEST
|
||||
os::SuspendResume::State state = osthread->sr.suspended();
|
||||
if (state == os::SuspendResume::SR_SUSPENDED) {
|
||||
sigset_t suspend_set; // signals for sigsuspend()
|
||||
|
||||
// notify the caller
|
||||
osthread->sr.set_suspended();
|
||||
// get current set of blocked signals and unblock resume signal
|
||||
pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
|
||||
sigdelset(&suspend_set, SR_signum);
|
||||
|
||||
sigset_t suspend_set; // signals for sigsuspend()
|
||||
sr_semaphore.signal();
|
||||
// wait here until we are resumed
|
||||
while (1) {
|
||||
sigsuspend(&suspend_set);
|
||||
|
||||
// get current set of blocked signals and unblock resume signal
|
||||
pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
|
||||
sigdelset(&suspend_set, SR_signum);
|
||||
os::SuspendResume::State result = osthread->sr.running();
|
||||
if (result == os::SuspendResume::SR_RUNNING) {
|
||||
sr_semaphore.signal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// wait here until we are resumed
|
||||
do {
|
||||
sigsuspend(&suspend_set);
|
||||
// ignore all returns until we get a resume signal
|
||||
} while (osthread->sr.suspend_action() != os::Linux::SuspendResume::SR_CONTINUE);
|
||||
} else if (state == os::SuspendResume::SR_RUNNING) {
|
||||
// request was cancelled, continue
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
resume_clear_context(osthread);
|
||||
|
||||
} else if (current == os::SuspendResume::SR_RUNNING) {
|
||||
// request was cancelled, continue
|
||||
} else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
|
||||
// ignore
|
||||
} else {
|
||||
assert(action == os::Linux::SuspendResume::SR_CONTINUE, "unexpected sr action");
|
||||
// nothing special to do - just leave the handler
|
||||
// ignore
|
||||
}
|
||||
|
||||
errno = old_errno;
|
||||
@ -3655,42 +3725,82 @@ static int SR_initialize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sr_notify(OSThread* osthread) {
|
||||
int status = pthread_kill(osthread->pthread_id(), SR_signum);
|
||||
assert_status(status == 0, status, "pthread_kill");
|
||||
return status;
|
||||
}
|
||||
|
||||
// "Randomly" selected value for how long we want to spin
|
||||
// before bailing out on suspending a thread, also how often
|
||||
// we send a signal to a thread we want to resume
|
||||
static const int RANDOMLY_LARGE_INTEGER = 1000000;
|
||||
static const int RANDOMLY_LARGE_INTEGER2 = 100;
|
||||
|
||||
// returns true on success and false on error - really an error is fatal
|
||||
// but this seems the normal response to library errors
|
||||
static bool do_suspend(OSThread* osthread) {
|
||||
// mark as suspended and send signal
|
||||
osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_SUSPEND);
|
||||
int status = pthread_kill(osthread->pthread_id(), SR_signum);
|
||||
assert_status(status == 0, status, "pthread_kill");
|
||||
assert(osthread->sr.is_running(), "thread should be running");
|
||||
assert(!sr_semaphore.trywait(), "semaphore has invalid state");
|
||||
|
||||
// check status and wait until notified of suspension
|
||||
if (status == 0) {
|
||||
for (int i = 0; !osthread->sr.is_suspended(); i++) {
|
||||
os::yield_all(i);
|
||||
}
|
||||
osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
|
||||
// mark as suspended and send signal
|
||||
if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
|
||||
// failed to switch, state wasn't running?
|
||||
ShouldNotReachHere();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sr_notify(osthread) != 0) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
|
||||
while (true) {
|
||||
if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
|
||||
break;
|
||||
} else {
|
||||
// timeout
|
||||
os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
|
||||
if (cancelled == os::SuspendResume::SR_RUNNING) {
|
||||
return false;
|
||||
} else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
|
||||
// make sure that we consume the signal on the semaphore as well
|
||||
sr_semaphore.wait();
|
||||
break;
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
guarantee(osthread->sr.is_suspended(), "Must be suspended");
|
||||
return true;
|
||||
}
|
||||
|
||||
static void do_resume(OSThread* osthread) {
|
||||
assert(osthread->sr.is_suspended(), "thread should be suspended");
|
||||
osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_CONTINUE);
|
||||
assert(!sr_semaphore.trywait(), "invalid semaphore state");
|
||||
|
||||
int status = pthread_kill(osthread->pthread_id(), SR_signum);
|
||||
assert_status(status == 0, status, "pthread_kill");
|
||||
// check status and wait unit notified of resumption
|
||||
if (status == 0) {
|
||||
for (int i = 0; osthread->sr.is_suspended(); i++) {
|
||||
os::yield_all(i);
|
||||
if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
|
||||
// failed to switch to WAKEUP_REQUEST
|
||||
ShouldNotReachHere();
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (sr_notify(osthread) == 0) {
|
||||
if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
|
||||
if (osthread->sr.is_running()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
|
||||
|
||||
guarantee(osthread->sr.is_running(), "Must be running!");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -4462,6 +4572,40 @@ bool os::bind_to_processor(uint processor_id) {
|
||||
|
||||
///
|
||||
|
||||
void os::SuspendedThreadTask::internal_do_task() {
|
||||
if (do_suspend(_thread->osthread())) {
|
||||
SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
|
||||
do_task(context);
|
||||
do_resume(_thread->osthread());
|
||||
}
|
||||
}
|
||||
|
||||
class PcFetcher : public os::SuspendedThreadTask {
|
||||
public:
|
||||
PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
|
||||
ExtendedPC result();
|
||||
protected:
|
||||
void do_task(const os::SuspendedThreadTaskContext& context);
|
||||
private:
|
||||
ExtendedPC _epc;
|
||||
};
|
||||
|
||||
ExtendedPC PcFetcher::result() {
|
||||
guarantee(is_done(), "task is not done yet.");
|
||||
return _epc;
|
||||
}
|
||||
|
||||
void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
|
||||
Thread* thread = context.thread();
|
||||
OSThread* osthread = thread->osthread();
|
||||
if (osthread->ucontext() != NULL) {
|
||||
_epc = os::Linux::ucontext_get_pc((ucontext_t *) context.ucontext());
|
||||
} else {
|
||||
// NULL context is unexpected, double-check this is the VMThread
|
||||
guarantee(thread->is_VM_thread(), "can only be called for VMThread");
|
||||
}
|
||||
}
|
||||
|
||||
// Suspends the target using the signal mechanism and then grabs the PC before
|
||||
// resuming the target. Used by the flat-profiler only
|
||||
ExtendedPC os::get_thread_pc(Thread* thread) {
|
||||
@ -4469,22 +4613,9 @@ ExtendedPC os::get_thread_pc(Thread* thread) {
|
||||
assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
|
||||
assert(thread->is_VM_thread(), "Can only be called for VMThread");
|
||||
|
||||
ExtendedPC epc;
|
||||
|
||||
OSThread* osthread = thread->osthread();
|
||||
if (do_suspend(osthread)) {
|
||||
if (osthread->ucontext() != NULL) {
|
||||
epc = os::Linux::ucontext_get_pc(osthread->ucontext());
|
||||
} else {
|
||||
// NULL context is unexpected, double-check this is the VMThread
|
||||
guarantee(thread->is_VM_thread(), "can only be called for VMThread");
|
||||
}
|
||||
do_resume(osthread);
|
||||
}
|
||||
// failure means pthread_kill failed for some reason - arguably this is
|
||||
// a fatal problem, but such problems are ignored elsewhere
|
||||
|
||||
return epc;
|
||||
PcFetcher fetcher(thread);
|
||||
fetcher.run();
|
||||
return fetcher.result();
|
||||
}
|
||||
|
||||
int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime)
|
||||
@ -5606,4 +5737,5 @@ void MemNotifyThread::start() {
|
||||
new MemNotifyThread(fd);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // JAVASE_EMBEDDED
|
||||
|
@ -210,35 +210,6 @@ class Linux {
|
||||
// LinuxThreads work-around for 6292965
|
||||
static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);
|
||||
|
||||
|
||||
// Linux suspend/resume support - this helper is a shadow of its former
|
||||
// self now that low-level suspension is barely used, and old workarounds
|
||||
// for LinuxThreads are no longer needed.
|
||||
class SuspendResume {
|
||||
private:
|
||||
volatile int _suspend_action;
|
||||
volatile jint _state;
|
||||
public:
|
||||
// values for suspend_action:
|
||||
enum {
|
||||
SR_NONE = 0x00,
|
||||
SR_SUSPEND = 0x01, // suspend request
|
||||
SR_CONTINUE = 0x02, // resume request
|
||||
SR_SUSPENDED = 0x20 // values for _state: + SR_NONE
|
||||
};
|
||||
|
||||
SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; }
|
||||
|
||||
int suspend_action() const { return _suspend_action; }
|
||||
void set_suspend_action(int x) { _suspend_action = x; }
|
||||
|
||||
// atomic updates for _state
|
||||
inline void set_suspended();
|
||||
inline void clear_suspended();
|
||||
bool is_suspended() { return _state & SR_SUSPENDED; }
|
||||
|
||||
};
|
||||
|
||||
private:
|
||||
typedef int (*sched_getcpu_func_t)(void);
|
||||
typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
|
||||
@ -333,6 +304,6 @@ class PlatformParker : public CHeapObj<mtInternal> {
|
||||
status = pthread_mutex_init (_mutex, NULL);
|
||||
assert_status(status == 0, status, "mutex_init");
|
||||
}
|
||||
} ;
|
||||
};
|
||||
|
||||
#endif // OS_LINUX_VM_OS_LINUX_HPP
|
||||
|
@ -288,20 +288,4 @@ inline int os::set_sock_opt(int fd, int level, int optname,
|
||||
return ::setsockopt(fd, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
inline void os::Linux::SuspendResume::set_suspended() {
|
||||
jint temp, temp2;
|
||||
do {
|
||||
temp = _state;
|
||||
temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
|
||||
} while (temp2 != temp);
|
||||
}
|
||||
|
||||
inline void os::Linux::SuspendResume::clear_suspended() {
|
||||
jint temp, temp2;
|
||||
do {
|
||||
temp = _state;
|
||||
temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
|
||||
} while (temp2 != temp);
|
||||
}
|
||||
|
||||
#endif // OS_LINUX_VM_OS_LINUX_INLINE_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -41,10 +41,6 @@ void OSThread::pd_initialize() {
|
||||
_thread_id = 0;
|
||||
sigemptyset(&_caller_sigmask);
|
||||
|
||||
_current_callback = NULL;
|
||||
_current_callback_lock = VM_Version::supports_compare_and_exchange() ? NULL
|
||||
: new Mutex(Mutex::suspend_resume, "Callback_lock", true);
|
||||
|
||||
_saved_interrupt_thread_state = _thread_new;
|
||||
_vm_created_thread = false;
|
||||
}
|
||||
@ -52,172 +48,6 @@ void OSThread::pd_initialize() {
|
||||
void OSThread::pd_destroy() {
|
||||
}
|
||||
|
||||
// Synchronous interrupt support
|
||||
//
|
||||
// _current_callback == NULL no pending callback
|
||||
// == 1 callback_in_progress
|
||||
// == other value pointer to the pending callback
|
||||
//
|
||||
|
||||
// CAS on v8 is implemented by using a global atomic_memory_operation_lock,
|
||||
// which is shared by other atomic functions. It is OK for normal uses, but
|
||||
// dangerous if used after some thread is suspended or if used in signal
|
||||
// handlers. Instead here we use a special per-thread lock to synchronize
|
||||
// updating _current_callback if we are running on v8. Note in general trying
|
||||
// to grab locks after a thread is suspended is not safe, but it is safe for
|
||||
// updating _current_callback, because synchronous interrupt callbacks are
|
||||
// currently only used in:
|
||||
// 1. GetThreadPC_Callback - used by WatcherThread to profile VM thread
|
||||
// There is no overlap between the callbacks, which means we won't try to
|
||||
// grab a thread's sync lock after the thread has been suspended while holding
|
||||
// the same lock.
|
||||
|
||||
// used after a thread is suspended
|
||||
static intptr_t compare_and_exchange_current_callback (
|
||||
intptr_t callback, intptr_t *addr, intptr_t compare_value, Mutex *sync) {
|
||||
if (VM_Version::supports_compare_and_exchange()) {
|
||||
return Atomic::cmpxchg_ptr(callback, addr, compare_value);
|
||||
} else {
|
||||
MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
|
||||
if (*addr == compare_value) {
|
||||
*addr = callback;
|
||||
return compare_value;
|
||||
} else {
|
||||
return callback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// used in signal handler
|
||||
static intptr_t exchange_current_callback(intptr_t callback, intptr_t *addr, Mutex *sync) {
|
||||
if (VM_Version::supports_compare_and_exchange()) {
|
||||
return Atomic::xchg_ptr(callback, addr);
|
||||
} else {
|
||||
MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
|
||||
intptr_t cb = *addr;
|
||||
*addr = callback;
|
||||
return cb;
|
||||
}
|
||||
}
|
||||
|
||||
// one interrupt at a time. spin if _current_callback != NULL
|
||||
int OSThread::set_interrupt_callback(Sync_Interrupt_Callback * cb) {
|
||||
int count = 0;
|
||||
while (compare_and_exchange_current_callback(
|
||||
(intptr_t)cb, (intptr_t *)&_current_callback, (intptr_t)NULL, _current_callback_lock) != NULL) {
|
||||
while (_current_callback != NULL) {
|
||||
count++;
|
||||
#ifdef ASSERT
|
||||
if ((WarnOnStalledSpinLock > 0) &&
|
||||
(count % WarnOnStalledSpinLock == 0)) {
|
||||
warning("_current_callback seems to be stalled: %p", _current_callback);
|
||||
}
|
||||
#endif
|
||||
os::yield_all(count);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// reset _current_callback, spin if _current_callback is callback_in_progress
|
||||
void OSThread::remove_interrupt_callback(Sync_Interrupt_Callback * cb) {
|
||||
int count = 0;
|
||||
while (compare_and_exchange_current_callback(
|
||||
(intptr_t)NULL, (intptr_t *)&_current_callback, (intptr_t)cb, _current_callback_lock) != (intptr_t)cb) {
|
||||
#ifdef ASSERT
|
||||
intptr_t p = (intptr_t)_current_callback;
|
||||
assert(p == (intptr_t)callback_in_progress ||
|
||||
p == (intptr_t)cb, "wrong _current_callback value");
|
||||
#endif
|
||||
while (_current_callback != cb) {
|
||||
count++;
|
||||
#ifdef ASSERT
|
||||
if ((WarnOnStalledSpinLock > 0) &&
|
||||
(count % WarnOnStalledSpinLock == 0)) {
|
||||
warning("_current_callback seems to be stalled: %p", _current_callback);
|
||||
}
|
||||
#endif
|
||||
os::yield_all(count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OSThread::do_interrupt_callbacks_at_interrupt(InterruptArguments *args) {
|
||||
Sync_Interrupt_Callback * cb;
|
||||
cb = (Sync_Interrupt_Callback *)exchange_current_callback(
|
||||
(intptr_t)callback_in_progress, (intptr_t *)&_current_callback, _current_callback_lock);
|
||||
|
||||
if (cb == NULL) {
|
||||
// signal is delivered too late (thread is masking interrupt signal??).
|
||||
// there is nothing we need to do because requesting thread has given up.
|
||||
} else if ((intptr_t)cb == (intptr_t)callback_in_progress) {
|
||||
fatal("invalid _current_callback state");
|
||||
} else {
|
||||
assert(cb->target()->osthread() == this, "wrong target");
|
||||
cb->execute(args);
|
||||
cb->leave_callback(); // notify the requester
|
||||
}
|
||||
|
||||
// restore original _current_callback value
|
||||
intptr_t p;
|
||||
p = exchange_current_callback((intptr_t)cb, (intptr_t *)&_current_callback, _current_callback_lock);
|
||||
assert(p == (intptr_t)callback_in_progress, "just checking");
|
||||
}
|
||||
|
||||
// Called by the requesting thread to send a signal to target thread and
|
||||
// execute "this" callback from the signal handler.
|
||||
int OSThread::Sync_Interrupt_Callback::interrupt(Thread * target, int timeout) {
|
||||
// Let signals to the vm_thread go even if the Threads_lock is not acquired
|
||||
assert(Threads_lock->owned_by_self() || (target == VMThread::vm_thread()),
|
||||
"must have threads lock to call this");
|
||||
|
||||
OSThread * osthread = target->osthread();
|
||||
|
||||
// may block if target thread already has a pending callback
|
||||
osthread->set_interrupt_callback(this);
|
||||
|
||||
_target = target;
|
||||
|
||||
int rslt = thr_kill(osthread->thread_id(), os::Solaris::SIGasync());
|
||||
assert(rslt == 0, "thr_kill != 0");
|
||||
|
||||
bool status = false;
|
||||
jlong t1 = os::javaTimeMillis();
|
||||
{ // don't use safepoint check because we might be the watcher thread.
|
||||
MutexLockerEx ml(_sync, Mutex::_no_safepoint_check_flag);
|
||||
while (!is_done()) {
|
||||
status = _sync->wait(Mutex::_no_safepoint_check_flag, timeout);
|
||||
|
||||
// status == true if timed out
|
||||
if (status) break;
|
||||
|
||||
// update timeout
|
||||
jlong t2 = os::javaTimeMillis();
|
||||
timeout -= t2 - t1;
|
||||
t1 = t2;
|
||||
}
|
||||
}
|
||||
|
||||
// reset current_callback
|
||||
osthread->remove_interrupt_callback(this);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void OSThread::Sync_Interrupt_Callback::leave_callback() {
|
||||
if (!_sync->owned_by_self()) {
|
||||
// notify requesting thread
|
||||
MutexLockerEx ml(_sync, Mutex::_no_safepoint_check_flag);
|
||||
_is_done = true;
|
||||
_sync->notify_all();
|
||||
} else {
|
||||
// Current thread is interrupted while it is holding the _sync lock, trying
|
||||
// to grab it again will deadlock. The requester will timeout anyway,
|
||||
// so just return.
|
||||
_is_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
// copied from synchronizer.cpp
|
||||
|
||||
void OSThread::handle_spinlock_contention(int tries) {
|
||||
@ -229,3 +59,7 @@ void OSThread::handle_spinlock_contention(int tries) {
|
||||
os::yield(); // Yield to threads of same or higher priority
|
||||
}
|
||||
}
|
||||
|
||||
void OSThread::SR_handler(Thread* thread, ucontext_t* uc) {
|
||||
os::Solaris::SR_handler(thread, uc);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -72,61 +72,15 @@
|
||||
// ***************************************************************
|
||||
|
||||
public:
|
||||
|
||||
class InterruptArguments : StackObj {
|
||||
private:
|
||||
Thread* _thread; // the thread to signal was dispatched to
|
||||
ucontext_t* _ucontext; // the machine context at the time of the signal
|
||||
|
||||
public:
|
||||
InterruptArguments(Thread* thread, ucontext_t* ucontext) {
|
||||
_thread = thread;
|
||||
_ucontext = ucontext;
|
||||
}
|
||||
|
||||
Thread* thread() const { return _thread; }
|
||||
ucontext_t* ucontext() const { return _ucontext; }
|
||||
};
|
||||
|
||||
// There are currently no asynchronous callbacks - and we'd better not
|
||||
// support them in the future either, as they need to be deallocated from
|
||||
// the interrupt handler, which is not safe; they also require locks to
|
||||
// protect the callback queue.
|
||||
|
||||
class Sync_Interrupt_Callback : private StackObj {
|
||||
protected:
|
||||
volatile bool _is_done;
|
||||
Monitor* _sync;
|
||||
Thread* _target;
|
||||
public:
|
||||
Sync_Interrupt_Callback(Monitor * sync) {
|
||||
_is_done = false; _target = NULL; _sync = sync;
|
||||
}
|
||||
|
||||
bool is_done() const { return _is_done; }
|
||||
Thread* target() const { return _target; }
|
||||
|
||||
int interrupt(Thread * target, int timeout);
|
||||
|
||||
// override to implement the callback.
|
||||
virtual void execute(InterruptArguments *args) = 0;
|
||||
|
||||
void leave_callback();
|
||||
};
|
||||
os::SuspendResume sr;
|
||||
|
||||
private:
|
||||
|
||||
Sync_Interrupt_Callback * volatile _current_callback;
|
||||
enum {
|
||||
callback_in_progress = 1
|
||||
};
|
||||
Mutex * _current_callback_lock; // only used on v8
|
||||
ucontext_t* _ucontext;
|
||||
|
||||
public:
|
||||
|
||||
int set_interrupt_callback (Sync_Interrupt_Callback * cb);
|
||||
void remove_interrupt_callback(Sync_Interrupt_Callback * cb);
|
||||
void do_interrupt_callbacks_at_interrupt(InterruptArguments *args);
|
||||
ucontext_t* ucontext() const { return _ucontext; }
|
||||
void set_ucontext(ucontext_t* ptr) { _ucontext = ptr; }
|
||||
static void SR_handler(Thread* thread, ucontext_t* uc);
|
||||
|
||||
// ***************************************************************
|
||||
// java.lang.Thread.interrupt state.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -27,28 +27,6 @@
|
||||
|
||||
// Defines the interfaces to Solaris operating systems that vary across platforms
|
||||
|
||||
|
||||
// This is a simple callback that just fetches a PC for an interrupted thread.
|
||||
// The thread need not be suspended and the fetched PC is just a hint.
|
||||
// Returned PC and nPC are not necessarily consecutive.
|
||||
// This one is currently used for profiling the VMThread ONLY!
|
||||
|
||||
// Must be synchronous
|
||||
class GetThreadPC_Callback : public OSThread::Sync_Interrupt_Callback {
|
||||
private:
|
||||
ExtendedPC _addr;
|
||||
|
||||
public:
|
||||
|
||||
GetThreadPC_Callback(Monitor *sync) :
|
||||
OSThread::Sync_Interrupt_Callback(sync) { }
|
||||
ExtendedPC addr() const { return _addr; }
|
||||
|
||||
void set_addr(ExtendedPC addr) { _addr = addr; }
|
||||
|
||||
void execute(OSThread::InterruptArguments *args);
|
||||
};
|
||||
|
||||
// misc
|
||||
extern "C" {
|
||||
void signalHandler(int, siginfo_t*, void*);
|
||||
|
@ -240,6 +240,8 @@ extern "C" {
|
||||
static int pthread_cond_default_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; }
|
||||
}
|
||||
|
||||
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
|
||||
|
||||
// Thread Local Storage
|
||||
// This is common to all Solaris platforms so it is defined here,
|
||||
// in this common file.
|
||||
@ -2580,6 +2582,57 @@ void* os::user_handler() {
|
||||
return CAST_FROM_FN_PTR(void*, UserHandler);
|
||||
}
|
||||
|
||||
class Semaphore : public StackObj {
|
||||
public:
|
||||
Semaphore();
|
||||
~Semaphore();
|
||||
void signal();
|
||||
void wait();
|
||||
bool trywait();
|
||||
bool timedwait(unsigned int sec, int nsec);
|
||||
private:
|
||||
sema_t _semaphore;
|
||||
};
|
||||
|
||||
|
||||
Semaphore::Semaphore() {
|
||||
sema_init(&_semaphore, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore() {
|
||||
sema_destroy(&_semaphore);
|
||||
}
|
||||
|
||||
void Semaphore::signal() {
|
||||
sema_post(&_semaphore);
|
||||
}
|
||||
|
||||
void Semaphore::wait() {
|
||||
sema_wait(&_semaphore);
|
||||
}
|
||||
|
||||
bool Semaphore::trywait() {
|
||||
return sema_trywait(&_semaphore) == 0;
|
||||
}
|
||||
|
||||
bool Semaphore::timedwait(unsigned int sec, int nsec) {
|
||||
struct timespec ts;
|
||||
unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
|
||||
|
||||
while (1) {
|
||||
int result = sema_timedwait(&_semaphore, &ts);
|
||||
if (result == 0) {
|
||||
return true;
|
||||
} else if (errno == EINTR) {
|
||||
continue;
|
||||
} else if (errno == ETIME) {
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
typedef void (*sa_handler_t)(int);
|
||||
typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
|
||||
@ -4164,6 +4217,68 @@ void os::hint_no_preempt() {
|
||||
schedctl_start(schedctl_init());
|
||||
}
|
||||
|
||||
static void resume_clear_context(OSThread *osthread) {
|
||||
osthread->set_ucontext(NULL);
|
||||
}
|
||||
|
||||
static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
|
||||
osthread->set_ucontext(context);
|
||||
}
|
||||
|
||||
static Semaphore sr_semaphore;
|
||||
|
||||
void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
|
||||
// Save and restore errno to avoid confusing native code with EINTR
|
||||
// after sigsuspend.
|
||||
int old_errno = errno;
|
||||
|
||||
OSThread* osthread = thread->osthread();
|
||||
assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
|
||||
|
||||
os::SuspendResume::State current = osthread->sr.state();
|
||||
if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
|
||||
suspend_save_context(osthread, uc);
|
||||
|
||||
// attempt to switch the state, we assume we had a SUSPEND_REQUEST
|
||||
os::SuspendResume::State state = osthread->sr.suspended();
|
||||
if (state == os::SuspendResume::SR_SUSPENDED) {
|
||||
sigset_t suspend_set; // signals for sigsuspend()
|
||||
|
||||
// get current set of blocked signals and unblock resume signal
|
||||
thr_sigsetmask(SIG_BLOCK, NULL, &suspend_set);
|
||||
sigdelset(&suspend_set, os::Solaris::SIGasync());
|
||||
|
||||
sr_semaphore.signal();
|
||||
// wait here until we are resumed
|
||||
while (1) {
|
||||
sigsuspend(&suspend_set);
|
||||
|
||||
os::SuspendResume::State result = osthread->sr.running();
|
||||
if (result == os::SuspendResume::SR_RUNNING) {
|
||||
sr_semaphore.signal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (state == os::SuspendResume::SR_RUNNING) {
|
||||
// request was cancelled, continue
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
resume_clear_context(osthread);
|
||||
} else if (current == os::SuspendResume::SR_RUNNING) {
|
||||
// request was cancelled, continue
|
||||
} else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
|
||||
// ignore
|
||||
} else {
|
||||
// ignore
|
||||
}
|
||||
|
||||
errno = old_errno;
|
||||
}
|
||||
|
||||
|
||||
void os::interrupt(Thread* thread) {
|
||||
assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
|
||||
|
||||
@ -4247,6 +4362,116 @@ int os::message_box(const char* title, const char* message) {
|
||||
return buf[0] == 'y' || buf[0] == 'Y';
|
||||
}
|
||||
|
||||
static int sr_notify(OSThread* osthread) {
|
||||
int status = thr_kill(osthread->thread_id(), os::Solaris::SIGasync());
|
||||
assert_status(status == 0, status, "thr_kill");
|
||||
return status;
|
||||
}
|
||||
|
||||
// "Randomly" selected value for how long we want to spin
|
||||
// before bailing out on suspending a thread, also how often
|
||||
// we send a signal to a thread we want to resume
|
||||
static const int RANDOMLY_LARGE_INTEGER = 1000000;
|
||||
static const int RANDOMLY_LARGE_INTEGER2 = 100;
|
||||
|
||||
static bool do_suspend(OSThread* osthread) {
|
||||
assert(osthread->sr.is_running(), "thread should be running");
|
||||
assert(!sr_semaphore.trywait(), "semaphore has invalid state");
|
||||
|
||||
// mark as suspended and send signal
|
||||
if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
|
||||
// failed to switch, state wasn't running?
|
||||
ShouldNotReachHere();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sr_notify(osthread) != 0) {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
|
||||
// managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
|
||||
while (true) {
|
||||
if (sr_semaphore.timedwait(0, 2000 * NANOSECS_PER_MILLISEC)) {
|
||||
break;
|
||||
} else {
|
||||
// timeout
|
||||
os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
|
||||
if (cancelled == os::SuspendResume::SR_RUNNING) {
|
||||
return false;
|
||||
} else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
|
||||
// make sure that we consume the signal on the semaphore as well
|
||||
sr_semaphore.wait();
|
||||
break;
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
guarantee(osthread->sr.is_suspended(), "Must be suspended");
|
||||
return true;
|
||||
}
|
||||
|
||||
static void do_resume(OSThread* osthread) {
|
||||
assert(osthread->sr.is_suspended(), "thread should be suspended");
|
||||
assert(!sr_semaphore.trywait(), "invalid semaphore state");
|
||||
|
||||
if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
|
||||
// failed to switch to WAKEUP_REQUEST
|
||||
ShouldNotReachHere();
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (sr_notify(osthread) == 0) {
|
||||
if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
|
||||
if (osthread->sr.is_running()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
guarantee(osthread->sr.is_running(), "Must be running!");
|
||||
}
|
||||
|
||||
void os::SuspendedThreadTask::internal_do_task() {
|
||||
if (do_suspend(_thread->osthread())) {
|
||||
SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
|
||||
do_task(context);
|
||||
do_resume(_thread->osthread());
|
||||
}
|
||||
}
|
||||
|
||||
class PcFetcher : public os::SuspendedThreadTask {
|
||||
public:
|
||||
PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
|
||||
ExtendedPC result();
|
||||
protected:
|
||||
void do_task(const os::SuspendedThreadTaskContext& context);
|
||||
private:
|
||||
ExtendedPC _epc;
|
||||
};
|
||||
|
||||
ExtendedPC PcFetcher::result() {
|
||||
guarantee(is_done(), "task is not done yet.");
|
||||
return _epc;
|
||||
}
|
||||
|
||||
void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
|
||||
Thread* thread = context.thread();
|
||||
OSThread* osthread = thread->osthread();
|
||||
if (osthread->ucontext() != NULL) {
|
||||
_epc = os::Solaris::ucontext_get_pc((ucontext_t *) context.ucontext());
|
||||
} else {
|
||||
// NULL context is unexpected, double-check this is the VMThread
|
||||
guarantee(thread->is_VM_thread(), "can only be called for VMThread");
|
||||
}
|
||||
}
|
||||
|
||||
// A lightweight implementation that does not suspend the target thread and
|
||||
// thus returns only a hint. Used for profiling only!
|
||||
ExtendedPC os::get_thread_pc(Thread* thread) {
|
||||
@ -4254,21 +4479,9 @@ ExtendedPC os::get_thread_pc(Thread* thread) {
|
||||
assert(Thread::current()->is_Watcher_thread(), "Must be watcher and own Threads_lock");
|
||||
// For now, is only used to profile the VM Thread
|
||||
assert(thread->is_VM_thread(), "Can only be called for VMThread");
|
||||
ExtendedPC epc;
|
||||
|
||||
GetThreadPC_Callback cb(ProfileVM_lock);
|
||||
OSThread *osthread = thread->osthread();
|
||||
const int time_to_wait = 400; // 400ms wait for initial response
|
||||
int status = cb.interrupt(thread, time_to_wait);
|
||||
|
||||
if (cb.is_done() ) {
|
||||
epc = cb.addr();
|
||||
} else {
|
||||
DEBUG_ONLY(tty->print_cr("Failed to get pc for thread: %d got %d status",
|
||||
osthread->thread_id(), status););
|
||||
// epc is already NULL
|
||||
}
|
||||
return epc;
|
||||
PcFetcher fetcher(thread);
|
||||
fetcher.run();
|
||||
return fetcher.result();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -127,7 +127,6 @@ class Solaris {
|
||||
static void set_SIGinterrupt(int newsig) { _SIGinterrupt = newsig; }
|
||||
static void set_SIGasync(int newsig) { _SIGasync = newsig; }
|
||||
|
||||
|
||||
public:
|
||||
// Large Page Support--ISM.
|
||||
static bool largepage_range(char* addr, size_t size);
|
||||
@ -145,6 +144,7 @@ class Solaris {
|
||||
static intptr_t* ucontext_get_sp(ucontext_t* uc);
|
||||
// ucontext_get_fp() is only used by Solaris X86 (see note below)
|
||||
static intptr_t* ucontext_get_fp(ucontext_t* uc);
|
||||
static address ucontext_get_pc(ucontext_t* uc);
|
||||
|
||||
// For Analyzer Forte AsyncGetCallTrace profiling support:
|
||||
// Parameter ret_fp is only used by Solaris X86.
|
||||
@ -157,6 +157,8 @@ class Solaris {
|
||||
|
||||
static void hotspot_sigmask(Thread* thread);
|
||||
|
||||
// SR_handler
|
||||
static void SR_handler(Thread* thread, ucontext_t* uc);
|
||||
protected:
|
||||
// Solaris-specific interface goes here
|
||||
static julong available_memory();
|
||||
|
@ -813,15 +813,21 @@ FILETIME java_to_windows_time(jlong l) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// For now, we say that Windows does not support vtime. I have no idea
|
||||
// whether it can actually be made to (DLD, 9/13/05).
|
||||
|
||||
bool os::supports_vtime() { return false; }
|
||||
bool os::supports_vtime() { return true; }
|
||||
bool os::enable_vtime() { return false; }
|
||||
bool os::vtime_enabled() { return false; }
|
||||
|
||||
double os::elapsedVTime() {
|
||||
// better than nothing, but not much
|
||||
return elapsedTime();
|
||||
FILETIME created;
|
||||
FILETIME exited;
|
||||
FILETIME kernel;
|
||||
FILETIME user;
|
||||
if (GetThreadTimes(GetCurrentThread(), &created, &exited, &kernel, &user) != 0) {
|
||||
// the resolution of windows_to_java_time() should be sufficient (ms)
|
||||
return (double) (windows_to_java_time(kernel) + windows_to_java_time(user)) / MILLIUNITS;
|
||||
} else {
|
||||
return elapsedTime();
|
||||
}
|
||||
}
|
||||
|
||||
jlong os::javaTimeMillis() {
|
||||
@ -944,6 +950,8 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
|
||||
MINIDUMP_TYPE dumpType;
|
||||
static const char* cwd;
|
||||
|
||||
// Default is to always create dump for debug builds, on product builds only dump on server versions of Windows.
|
||||
#ifndef ASSERT
|
||||
// If running on a client version of Windows and user has not explicitly enabled dumping
|
||||
if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) {
|
||||
VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false);
|
||||
@ -953,6 +961,12 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
|
||||
VMError::report_coredump_status("Minidump has been disabled from the command line", false);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (!FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) {
|
||||
VMError::report_coredump_status("Minidump has been disabled from the command line", false);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0);
|
||||
|
||||
@ -1004,7 +1018,21 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
|
||||
// the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.
|
||||
if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false &&
|
||||
_MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) {
|
||||
VMError::report_coredump_status("Call to MiniDumpWriteDump() failed", false);
|
||||
DWORD error = GetLastError();
|
||||
LPTSTR msgbuf = NULL;
|
||||
|
||||
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) {
|
||||
|
||||
jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf);
|
||||
LocalFree(msgbuf);
|
||||
} else {
|
||||
// Call to FormatMessage failed, just include the result from GetLastError
|
||||
jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x)", error);
|
||||
}
|
||||
VMError::report_coredump_status(buffer, false);
|
||||
} else {
|
||||
VMError::report_coredump_status(buffer, true);
|
||||
}
|
||||
@ -5020,6 +5048,71 @@ int os::set_sock_opt(int fd, int level, int optname,
|
||||
return ::setsockopt(fd, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
// WINDOWS CONTEXT Flags for THREAD_SAMPLING
|
||||
#if defined(IA32)
|
||||
# define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
|
||||
#elif defined (AMD64)
|
||||
# define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
|
||||
#endif
|
||||
|
||||
// returns true if thread could be suspended,
|
||||
// false otherwise
|
||||
static bool do_suspend(HANDLE* h) {
|
||||
if (h != NULL) {
|
||||
if (SuspendThread(*h) != ~0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// resume the thread
|
||||
// calling resume on an active thread is a no-op
|
||||
static void do_resume(HANDLE* h) {
|
||||
if (h != NULL) {
|
||||
ResumeThread(*h);
|
||||
}
|
||||
}
|
||||
|
||||
// retrieve a suspend/resume context capable handle
|
||||
// from the tid. Caller validates handle return value.
|
||||
void get_thread_handle_for_extended_context(HANDLE* h, OSThread::thread_id_t tid) {
|
||||
if (h != NULL) {
|
||||
*h = OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, tid);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Thread sampling implementation
|
||||
//
|
||||
void os::SuspendedThreadTask::internal_do_task() {
|
||||
CONTEXT ctxt;
|
||||
HANDLE h = NULL;
|
||||
|
||||
// get context capable handle for thread
|
||||
get_thread_handle_for_extended_context(&h, _thread->osthread()->thread_id());
|
||||
|
||||
// sanity
|
||||
if (h == NULL || h == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// suspend the thread
|
||||
if (do_suspend(&h)) {
|
||||
ctxt.ContextFlags = sampling_context_flags;
|
||||
// get thread context
|
||||
GetThreadContext(h, &ctxt);
|
||||
SuspendedThreadTaskContext context(_thread, &ctxt);
|
||||
// pass context to Thread Sampling impl
|
||||
do_task(context);
|
||||
// resume thread
|
||||
do_resume(&h);
|
||||
}
|
||||
|
||||
// close handle
|
||||
CloseHandle(h);
|
||||
}
|
||||
|
||||
|
||||
// Kernel32 API
|
||||
typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -30,10 +30,16 @@
|
||||
// currently interrupted by SIGPROF
|
||||
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
|
||||
void* ucontext, bool isInJava) {
|
||||
|
||||
assert(Thread::current() == this, "caller must be current thread");
|
||||
assert(this->is_Java_thread(), "must be JavaThread");
|
||||
return pd_get_top_frame(fr_addr, ucontext, isInJava);
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
|
||||
return pd_get_top_frame(fr_addr, ucontext, isInJava);
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
|
||||
assert(this->is_Java_thread(), "must be JavaThread");
|
||||
JavaThread* jt = (JavaThread *)this;
|
||||
|
||||
// If we have a last_Java_frame, then we should use it even if
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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
|
||||
@ -61,6 +61,13 @@
|
||||
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
|
||||
bool isInJava);
|
||||
|
||||
bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
|
||||
bool isInJava);
|
||||
|
||||
private:
|
||||
bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
|
||||
public:
|
||||
|
||||
// These routines are only used on cpu architectures that
|
||||
// have separate register stacks (Itanium).
|
||||
static bool register_stack_overflow() { return false; }
|
||||
|
@ -241,7 +241,7 @@ acb_CopyLeft:
|
||||
jbe 2f # <= 32 dwords
|
||||
rep; smovl
|
||||
jmp 4f
|
||||
.=.+8
|
||||
.space 8
|
||||
2: subl %esi,%edi
|
||||
.p2align 4,,15
|
||||
3: movl (%esi),%edx
|
||||
@ -378,7 +378,7 @@ acs_CopyRight:
|
||||
rep; smovl
|
||||
jmp 4f
|
||||
# copy aligned dwords
|
||||
.=.+5
|
||||
.space 5
|
||||
2: subl %esi,%edi
|
||||
.p2align 4,,15
|
||||
3: movl (%esi),%edx
|
||||
@ -454,7 +454,7 @@ ci_CopyRight:
|
||||
popl %edi
|
||||
popl %esi
|
||||
ret
|
||||
.=.+10
|
||||
.space 10
|
||||
2: subl %esi,%edi
|
||||
jmp 4f
|
||||
.p2align 4,,15
|
||||
|
@ -93,6 +93,10 @@ address os::current_stack_pointer() {
|
||||
register void *esp;
|
||||
__asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
|
||||
return (address) ((char*)esp + sizeof(long)*2);
|
||||
#elif defined(__clang__)
|
||||
intptr_t* esp;
|
||||
__asm__ __volatile__ ("mov %%"SPELL_REG_SP", %0":"=r"(esp):);
|
||||
return (address) esp;
|
||||
#else
|
||||
register void *esp __asm__ (SPELL_REG_SP);
|
||||
return (address) esp;
|
||||
@ -175,6 +179,9 @@ intptr_t* _get_previous_fp() {
|
||||
#ifdef SPARC_WORKS
|
||||
register intptr_t **ebp;
|
||||
__asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp));
|
||||
#elif defined(__clang__)
|
||||
intptr_t **ebp;
|
||||
__asm__ __volatile__ ("mov %%"SPELL_REG_FP", %0":"=r"(ebp):);
|
||||
#else
|
||||
register intptr_t **ebp __asm__ (SPELL_REG_FP);
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -32,8 +32,15 @@ bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
|
||||
void* ucontext, bool isInJava) {
|
||||
|
||||
assert(Thread::current() == this, "caller must be current thread");
|
||||
assert(this->is_Java_thread(), "must be JavaThread");
|
||||
return pd_get_top_frame(fr_addr, ucontext, isInJava);
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
|
||||
return pd_get_top_frame(fr_addr, ucontext, isInJava);
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
|
||||
assert(this->is_Java_thread(), "must be JavaThread");
|
||||
JavaThread* jt = (JavaThread *)this;
|
||||
|
||||
// If we have a last_Java_frame, then we should use it even if
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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
|
||||
@ -61,6 +61,11 @@
|
||||
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
|
||||
bool isInJava);
|
||||
|
||||
bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
|
||||
private:
|
||||
bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
|
||||
public:
|
||||
|
||||
// These routines are only used on cpu architectures that
|
||||
// have separate register stacks (Itanium).
|
||||
static bool register_stack_overflow() { return false; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -194,6 +194,11 @@ intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
|
||||
return (address) uc->uc_mcontext.gregs[REG_PC];
|
||||
}
|
||||
|
||||
|
||||
// For Forte Analyzer AsyncGetCallTrace profiling support - thread
|
||||
// is currently interrupted by SIGPROF.
|
||||
//
|
||||
@ -265,22 +270,6 @@ frame os::current_frame() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) {
|
||||
Thread* thread = args->thread();
|
||||
ucontext_t* uc = args->ucontext();
|
||||
intptr_t* sp;
|
||||
|
||||
assert(ProfileVM && thread->is_VM_thread(), "just checking");
|
||||
|
||||
// Skip the mcontext corruption verification. If if occasionally
|
||||
// things get corrupt, it is ok for profiling - we will just get an unresolved
|
||||
// function name
|
||||
ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]);
|
||||
_addr = new_addr;
|
||||
}
|
||||
|
||||
|
||||
static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) {
|
||||
char lwpstatusfile[PROCFILE_LENGTH];
|
||||
int lwpfd, err;
|
||||
@ -358,13 +347,8 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||
guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
|
||||
|
||||
if (sig == os::Solaris::SIGasync()) {
|
||||
if (thread) {
|
||||
OSThread::InterruptArguments args(thread, uc);
|
||||
thread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
|
||||
return true;
|
||||
} else if (vmthread) {
|
||||
OSThread::InterruptArguments args(vmthread, uc);
|
||||
vmthread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
|
||||
if (thread || vmthread) {
|
||||
OSThread::SR_handler(t, uc);
|
||||
return true;
|
||||
} else if (os::Solaris::chained_handler(sig, info, ucVoid)) {
|
||||
return true;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -36,11 +36,21 @@ bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
|
||||
void* ucontext, bool isInJava) {
|
||||
|
||||
assert(Thread::current() == this, "caller must be current thread");
|
||||
return pd_get_top_frame(fr_addr, ucontext, isInJava, true);
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
|
||||
// get ucontext somehow
|
||||
return pd_get_top_frame(fr_addr, ucontext, isInJava, false);
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame(frame* fr_addr,
|
||||
void* ucontext, bool isInJava, bool makeWalkable) {
|
||||
assert(this->is_Java_thread(), "must be JavaThread");
|
||||
|
||||
JavaThread* jt = (JavaThread *)this;
|
||||
|
||||
if (!isInJava) {
|
||||
if (!isInJava && makeWalkable) {
|
||||
// make_walkable flushes register windows and grabs last_Java_pc
|
||||
// which can not be done if the ucontext sp matches last_Java_sp
|
||||
// stack walking utilities assume last_Java_pc set if marked flushed
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -93,6 +93,11 @@ public:
|
||||
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
|
||||
bool isInJava);
|
||||
|
||||
bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
|
||||
private:
|
||||
bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava, bool makeWalkable);
|
||||
public:
|
||||
|
||||
// These routines are only used on cpu architectures that
|
||||
// have separate register stacks (Itanium).
|
||||
static bool register_stack_overflow() { return false; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -183,6 +183,10 @@ intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
|
||||
return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
|
||||
}
|
||||
|
||||
address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
|
||||
return (address) uc->uc_mcontext.gregs[REG_PC];
|
||||
}
|
||||
|
||||
// For Forte Analyzer AsyncGetCallTrace profiling support - thread
|
||||
// is currently interrupted by SIGPROF.
|
||||
//
|
||||
@ -252,22 +256,6 @@ frame os::current_frame() {
|
||||
}
|
||||
}
|
||||
|
||||
// This is a simple callback that just fetches a PC for an interrupted thread.
|
||||
// The thread need not be suspended and the fetched PC is just a hint.
|
||||
// This one is currently used for profiling the VMThread ONLY!
|
||||
|
||||
// Must be synchronous
|
||||
void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) {
|
||||
Thread* thread = args->thread();
|
||||
ucontext_t* uc = args->ucontext();
|
||||
intptr_t* sp;
|
||||
|
||||
assert(ProfileVM && thread->is_VM_thread(), "just checking");
|
||||
|
||||
ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]);
|
||||
_addr = new_addr;
|
||||
}
|
||||
|
||||
static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) {
|
||||
char lwpstatusfile[PROCFILE_LENGTH];
|
||||
int lwpfd, err;
|
||||
@ -419,14 +407,8 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||
guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
|
||||
|
||||
if (sig == os::Solaris::SIGasync()) {
|
||||
if(thread){
|
||||
OSThread::InterruptArguments args(thread, uc);
|
||||
thread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
|
||||
return true;
|
||||
}
|
||||
else if(vmthread){
|
||||
OSThread::InterruptArguments args(vmthread, uc);
|
||||
vmthread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
|
||||
if(thread || vmthread){
|
||||
OSThread::SR_handler(t, uc);
|
||||
return true;
|
||||
} else if (os::Solaris::chained_handler(sig, info, ucVoid)) {
|
||||
return true;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -30,8 +30,17 @@
|
||||
// currently interrupted by SIGPROF
|
||||
bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
|
||||
void* ucontext, bool isInJava) {
|
||||
|
||||
assert(Thread::current() == this, "caller must be current thread");
|
||||
return pd_get_top_frame(fr_addr, ucontext, isInJava);
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr,
|
||||
void* ucontext, bool isInJava) {
|
||||
return pd_get_top_frame(fr_addr, ucontext, isInJava);
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame(frame* fr_addr,
|
||||
void* ucontext, bool isInJava) {
|
||||
assert(this->is_Java_thread(), "must be JavaThread");
|
||||
JavaThread* jt = (JavaThread *)this;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -54,6 +54,12 @@
|
||||
|
||||
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
|
||||
bool isInJava);
|
||||
bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
|
||||
bool isInJava);
|
||||
private:
|
||||
bool pd_get_top_frame(frame* fr_addr, void* ucontext,
|
||||
bool isInJava);
|
||||
public:
|
||||
|
||||
// These routines are only used on cpu architectures that
|
||||
// have separate register stacks (Itanium).
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -32,6 +32,15 @@ bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
|
||||
void* ucontext, bool isInJava) {
|
||||
|
||||
assert(Thread::current() == this, "caller must be current thread");
|
||||
return pd_get_top_frame(fr_addr, ucontext, isInJava);
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
|
||||
return pd_get_top_frame(fr_addr, ucontext, isInJava);
|
||||
}
|
||||
|
||||
bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
|
||||
|
||||
assert(this->is_Java_thread(), "must be JavaThread");
|
||||
|
||||
JavaThread* jt = (JavaThread *)this;
|
||||
@ -87,4 +96,3 @@ bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
|
||||
}
|
||||
|
||||
void JavaThread::cache_global_variables() { }
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -58,6 +58,12 @@
|
||||
bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
|
||||
bool isInJava);
|
||||
|
||||
bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
|
||||
|
||||
private:
|
||||
bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
|
||||
|
||||
public:
|
||||
// These routines are only used on cpu architectures that
|
||||
// have separate register stacks (Itanium).
|
||||
static bool register_stack_overflow() { return false; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -152,7 +152,7 @@ class BuildConfig {
|
||||
sysDefines.add("_WINDOWS");
|
||||
sysDefines.add("HOTSPOT_BUILD_USER=\\\""+System.getProperty("user.name")+"\\\"");
|
||||
sysDefines.add("HOTSPOT_BUILD_TARGET=\\\""+get("Build")+"\\\"");
|
||||
sysDefines.add("INCLUDE_TRACE");
|
||||
sysDefines.add("INCLUDE_TRACE=1");
|
||||
sysDefines.add("_JNI_IMPLEMENTATION_");
|
||||
if (vars.get("PlatformName").equals("Win32")) {
|
||||
sysDefines.add("HOTSPOT_LIB_ARCH=\\\"i386\\\"");
|
||||
|
@ -29,8 +29,8 @@
|
||||
static FILE *errfile = stderr;
|
||||
|
||||
//--------------------------- utility functions -----------------------------
|
||||
inline char toUpper(char lower) {
|
||||
return (('a' <= lower && lower <= 'z') ? (lower + ('A'-'a')) : lower);
|
||||
inline char toUpper(char lower) {
|
||||
return (('a' <= lower && lower <= 'z') ? ((char) (lower + ('A'-'a'))) : lower);
|
||||
}
|
||||
char *toUpper(const char *str) {
|
||||
char *upper = new char[strlen(str)+1];
|
||||
|
@ -64,18 +64,18 @@ void Dict::init() {
|
||||
int i;
|
||||
|
||||
// Precompute table of null character hashes
|
||||
if( !initflag ) { // Not initializated yet?
|
||||
xsum[0] = (1<<shft[0])+1; // Initialize
|
||||
if (!initflag) { // Not initializated yet?
|
||||
xsum[0] = (short) ((1 << shft[0]) + 1); // Initialize
|
||||
for( i = 1; i < MAXID; i++) {
|
||||
xsum[i] = (1<<shft[i])+1+xsum[i-1];
|
||||
xsum[i] = (short) ((1 << shft[i]) + 1 + xsum[i-1]);
|
||||
}
|
||||
initflag = 1; // Never again
|
||||
}
|
||||
|
||||
_size = 16; // Size is a power of 2
|
||||
_cnt = 0; // Dictionary is empty
|
||||
_bin = (bucket*)_arena->Amalloc_4(sizeof(bucket)*_size);
|
||||
memset(_bin,0,sizeof(bucket)*_size);
|
||||
_bin = (bucket*)_arena->Amalloc_4(sizeof(bucket) * _size);
|
||||
memset(_bin, 0, sizeof(bucket) * _size);
|
||||
}
|
||||
|
||||
//------------------------------~Dict------------------------------------------
|
||||
@ -287,11 +287,11 @@ int hashstr(const void *t) {
|
||||
register int sum = 0;
|
||||
register const char *s = (const char *)t;
|
||||
|
||||
while( ((c = s[k]) != '\0') && (k < MAXID-1) ) { // Get characters till nul
|
||||
c = (c<<1)+1; // Characters are always odd!
|
||||
sum += c + (c<<shft[k++]); // Universal hash function
|
||||
while (((c = s[k]) != '\0') && (k < MAXID-1)) { // Get characters till nul
|
||||
c = (char) ((c << 1) + 1); // Characters are always odd!
|
||||
sum += c + (c << shft[k++]); // Universal hash function
|
||||
}
|
||||
assert( k < (MAXID), "Exceeded maximum name length");
|
||||
assert(k < (MAXID), "Exceeded maximum name length");
|
||||
return (int)((sum+xsum[k]) >> 1); // Hash key, un-modulo'd table size
|
||||
}
|
||||
|
||||
|
@ -796,11 +796,11 @@ uint InstructForm::num_opnds() {
|
||||
return num_opnds;
|
||||
}
|
||||
|
||||
const char *InstructForm::opnd_ident(int idx) {
|
||||
const char* InstructForm::opnd_ident(int idx) {
|
||||
return _components.at(idx)->_name;
|
||||
}
|
||||
|
||||
const char *InstructForm::unique_opnd_ident(int idx) {
|
||||
const char* InstructForm::unique_opnd_ident(uint idx) {
|
||||
uint i;
|
||||
for (i = 1; i < num_opnds(); ++i) {
|
||||
if (unique_opnds_idx(i) == idx) {
|
||||
@ -1315,36 +1315,36 @@ void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {
|
||||
// Seach through operands to determine parameters unique positions.
|
||||
void InstructForm::set_unique_opnds() {
|
||||
uint* uniq_idx = NULL;
|
||||
int nopnds = num_opnds();
|
||||
uint nopnds = num_opnds();
|
||||
uint num_uniq = nopnds;
|
||||
int i;
|
||||
uint i;
|
||||
_uniq_idx_length = 0;
|
||||
if ( nopnds > 0 ) {
|
||||
if (nopnds > 0) {
|
||||
// Allocate index array. Worst case we're mapping from each
|
||||
// component back to an index and any DEF always goes at 0 so the
|
||||
// length of the array has to be the number of components + 1.
|
||||
_uniq_idx_length = _components.count() + 1;
|
||||
uniq_idx = (uint*) malloc(sizeof(uint)*(_uniq_idx_length));
|
||||
for( i = 0; i < _uniq_idx_length; i++ ) {
|
||||
uniq_idx = (uint*) malloc(sizeof(uint) * _uniq_idx_length);
|
||||
for (i = 0; i < _uniq_idx_length; i++) {
|
||||
uniq_idx[i] = i;
|
||||
}
|
||||
}
|
||||
// Do it only if there is a match rule and no expand rule. With an
|
||||
// expand rule it is done by creating new mach node in Expand()
|
||||
// method.
|
||||
if ( nopnds > 0 && _matrule != NULL && _exprule == NULL ) {
|
||||
if (nopnds > 0 && _matrule != NULL && _exprule == NULL) {
|
||||
const char *name;
|
||||
uint count;
|
||||
bool has_dupl_use = false;
|
||||
|
||||
_parameters.reset();
|
||||
while( (name = _parameters.iter()) != NULL ) {
|
||||
while ((name = _parameters.iter()) != NULL) {
|
||||
count = 0;
|
||||
int position = 0;
|
||||
int uniq_position = 0;
|
||||
uint position = 0;
|
||||
uint uniq_position = 0;
|
||||
_components.reset();
|
||||
Component *comp = NULL;
|
||||
if( sets_result() ) {
|
||||
if (sets_result()) {
|
||||
comp = _components.iter();
|
||||
position++;
|
||||
}
|
||||
@ -1352,11 +1352,11 @@ void InstructForm::set_unique_opnds() {
|
||||
for (; (comp = _components.iter()) != NULL; ++position) {
|
||||
// When the first component is not a DEF,
|
||||
// leave space for the result operand!
|
||||
if ( position==0 && (! comp->isa(Component::DEF)) ) {
|
||||
if (position==0 && (!comp->isa(Component::DEF))) {
|
||||
++position;
|
||||
}
|
||||
if( strcmp(name, comp->_name)==0 ) {
|
||||
if( ++count > 1 ) {
|
||||
if (strcmp(name, comp->_name) == 0) {
|
||||
if (++count > 1) {
|
||||
assert(position < _uniq_idx_length, "out of bounds");
|
||||
uniq_idx[position] = uniq_position;
|
||||
has_dupl_use = true;
|
||||
@ -1364,22 +1364,25 @@ void InstructForm::set_unique_opnds() {
|
||||
uniq_position = position;
|
||||
}
|
||||
}
|
||||
if( comp->isa(Component::DEF)
|
||||
&& comp->isa(Component::USE) ) {
|
||||
if (comp->isa(Component::DEF) && comp->isa(Component::USE)) {
|
||||
++position;
|
||||
if( position != 1 )
|
||||
if (position != 1)
|
||||
--position; // only use two slots for the 1st USE_DEF
|
||||
}
|
||||
}
|
||||
}
|
||||
if( has_dupl_use ) {
|
||||
for( i = 1; i < nopnds; i++ )
|
||||
if( i != uniq_idx[i] )
|
||||
if (has_dupl_use) {
|
||||
for (i = 1; i < nopnds; i++) {
|
||||
if (i != uniq_idx[i]) {
|
||||
break;
|
||||
int j = i;
|
||||
for( ; i < nopnds; i++ )
|
||||
if( i == uniq_idx[i] )
|
||||
}
|
||||
}
|
||||
uint j = i;
|
||||
for (; i < nopnds; i++) {
|
||||
if (i == uniq_idx[i]) {
|
||||
uniq_idx[i] = j++;
|
||||
}
|
||||
}
|
||||
num_uniq = j;
|
||||
}
|
||||
}
|
||||
@ -2216,21 +2219,27 @@ RegClass* OperandForm::get_RegClass() const {
|
||||
|
||||
|
||||
bool OperandForm::is_bound_register() const {
|
||||
RegClass *reg_class = get_RegClass();
|
||||
if (reg_class == NULL) return false;
|
||||
RegClass* reg_class = get_RegClass();
|
||||
if (reg_class == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char * name = ideal_type(globalAD->globalNames());
|
||||
if (name == NULL) return false;
|
||||
const char* name = ideal_type(globalAD->globalNames());
|
||||
if (name == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int size = 0;
|
||||
if (strcmp(name,"RegFlags")==0) size = 1;
|
||||
if (strcmp(name,"RegI")==0) size = 1;
|
||||
if (strcmp(name,"RegF")==0) size = 1;
|
||||
if (strcmp(name,"RegD")==0) size = 2;
|
||||
if (strcmp(name,"RegL")==0) size = 2;
|
||||
if (strcmp(name,"RegN")==0) size = 1;
|
||||
if (strcmp(name,"RegP")==0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
|
||||
if (size == 0) return false;
|
||||
uint size = 0;
|
||||
if (strcmp(name, "RegFlags") == 0) size = 1;
|
||||
if (strcmp(name, "RegI") == 0) size = 1;
|
||||
if (strcmp(name, "RegF") == 0) size = 1;
|
||||
if (strcmp(name, "RegD") == 0) size = 2;
|
||||
if (strcmp(name, "RegL") == 0) size = 2;
|
||||
if (strcmp(name, "RegN") == 0) size = 1;
|
||||
if (strcmp(name, "RegP") == 0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
|
||||
if (size == 0) {
|
||||
return false;
|
||||
}
|
||||
return size == reg_class->size();
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ public:
|
||||
const char *_ins_pipe; // Instruction Scheduling description class
|
||||
|
||||
uint *_uniq_idx; // Indexes of unique operands
|
||||
int _uniq_idx_length; // Length of _uniq_idx array
|
||||
uint _uniq_idx_length; // Length of _uniq_idx array
|
||||
uint _num_uniq; // Number of unique operands
|
||||
ComponentList _components; // List of Components matches MachNode's
|
||||
// operand structure
|
||||
@ -272,14 +272,14 @@ public:
|
||||
void set_unique_opnds();
|
||||
uint num_unique_opnds() { return _num_uniq; }
|
||||
uint unique_opnds_idx(int idx) {
|
||||
if( _uniq_idx != NULL && idx > 0 ) {
|
||||
assert(idx < _uniq_idx_length, "out of bounds");
|
||||
return _uniq_idx[idx];
|
||||
} else {
|
||||
return idx;
|
||||
}
|
||||
if (_uniq_idx != NULL && idx > 0) {
|
||||
assert((uint)idx < _uniq_idx_length, "out of bounds");
|
||||
return _uniq_idx[idx];
|
||||
} else {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
const char *unique_opnd_ident(int idx); // Name of operand at unique idx.
|
||||
const char *unique_opnd_ident(uint idx); // Name of operand at unique idx.
|
||||
|
||||
// Operands which are only KILLs aren't part of the input array and
|
||||
// require special handling in some cases. Their position in this
|
||||
|
@ -463,8 +463,9 @@ static int pipeline_res_mask_initializer(
|
||||
uint resources_used_exclusively = 0;
|
||||
|
||||
for (pipeclass->_resUsage.reset();
|
||||
(piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; )
|
||||
(piperesource = (const PipeClassResourceForm*)pipeclass->_resUsage.iter()) != NULL; ) {
|
||||
element_count++;
|
||||
}
|
||||
|
||||
// Pre-compute the string length
|
||||
int templen;
|
||||
@ -482,8 +483,8 @@ static int pipeline_res_mask_initializer(
|
||||
for (i = rescount; i > 0; i /= 10)
|
||||
maskdigit++;
|
||||
|
||||
static const char * pipeline_use_cycle_mask = "Pipeline_Use_Cycle_Mask";
|
||||
static const char * pipeline_use_element = "Pipeline_Use_Element";
|
||||
static const char* pipeline_use_cycle_mask = "Pipeline_Use_Cycle_Mask";
|
||||
static const char* pipeline_use_element = "Pipeline_Use_Element";
|
||||
|
||||
templen = 1 +
|
||||
(int)(strlen(pipeline_use_cycle_mask) + (int)strlen(pipeline_use_element) +
|
||||
@ -496,11 +497,12 @@ static int pipeline_res_mask_initializer(
|
||||
templen = 0;
|
||||
|
||||
for (pipeclass->_resUsage.reset();
|
||||
(piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
|
||||
(piperesource = (const PipeClassResourceForm*)pipeclass->_resUsage.iter()) != NULL; ) {
|
||||
int used_mask = pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
|
||||
|
||||
if (!used_mask)
|
||||
if (!used_mask) {
|
||||
fprintf(stderr, "*** used_mask is 0 ***\n");
|
||||
}
|
||||
|
||||
resources_used |= used_mask;
|
||||
|
||||
@ -509,8 +511,9 @@ static int pipeline_res_mask_initializer(
|
||||
for (lb = 0; (used_mask & (1 << lb)) == 0; lb++);
|
||||
for (ub = 31; (used_mask & (1 << ub)) == 0; ub--);
|
||||
|
||||
if (lb == ub)
|
||||
if (lb == ub) {
|
||||
resources_used_exclusively |= used_mask;
|
||||
}
|
||||
|
||||
int formatlen =
|
||||
sprintf(&resource_mask[templen], " %s(0x%0*x, %*d, %*d, %s %s(",
|
||||
@ -526,7 +529,7 @@ static int pipeline_res_mask_initializer(
|
||||
|
||||
int cycles = piperesource->_cycles;
|
||||
uint stage = pipeline->_stages.index(piperesource->_stage);
|
||||
if (NameList::Not_in_list == stage) {
|
||||
if ((uint)NameList::Not_in_list == stage) {
|
||||
fprintf(stderr,
|
||||
"pipeline_res_mask_initializer: "
|
||||
"semantic error: "
|
||||
@ -534,8 +537,8 @@ static int pipeline_res_mask_initializer(
|
||||
piperesource->_stage);
|
||||
exit(1);
|
||||
}
|
||||
uint upper_limit = stage+cycles-1;
|
||||
uint lower_limit = stage-1;
|
||||
uint upper_limit = stage + cycles - 1;
|
||||
uint lower_limit = stage - 1;
|
||||
uint upper_idx = upper_limit >> 5;
|
||||
uint lower_idx = lower_limit >> 5;
|
||||
uint upper_position = upper_limit & 0x1f;
|
||||
@ -543,7 +546,7 @@ static int pipeline_res_mask_initializer(
|
||||
|
||||
uint mask = (((uint)1) << upper_position) - 1;
|
||||
|
||||
while ( upper_idx > lower_idx ) {
|
||||
while (upper_idx > lower_idx) {
|
||||
res_mask[upper_idx--] |= mask;
|
||||
mask = (uint)-1;
|
||||
}
|
||||
@ -565,8 +568,9 @@ static int pipeline_res_mask_initializer(
|
||||
}
|
||||
|
||||
resource_mask[templen] = 0;
|
||||
if (last_comma)
|
||||
if (last_comma) {
|
||||
last_comma[0] = ' ';
|
||||
}
|
||||
|
||||
// See if the same string is in the table
|
||||
int ndx = pipeline_res_mask.index(resource_mask);
|
||||
@ -580,7 +584,7 @@ static int pipeline_res_mask_initializer(
|
||||
fprintf(fp_cpp, "static const Pipeline_Use_Element pipeline_res_mask_%03d[%d] = {\n%s};\n\n",
|
||||
ndx+1, element_count, resource_mask);
|
||||
|
||||
char * args = new char [9 + 2*masklen + maskdigit];
|
||||
char* args = new char [9 + 2*masklen + maskdigit];
|
||||
|
||||
sprintf(args, "0x%0*x, 0x%0*x, %*d",
|
||||
masklen, resources_used,
|
||||
@ -589,8 +593,9 @@ static int pipeline_res_mask_initializer(
|
||||
|
||||
pipeline_res_args.addName(args);
|
||||
}
|
||||
else
|
||||
else {
|
||||
delete [] resource_mask;
|
||||
}
|
||||
|
||||
delete [] res_mask;
|
||||
//delete [] res_masks;
|
||||
@ -1787,7 +1792,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
||||
// Skip first unique operands.
|
||||
for( i = 1; i < cur_num_opnds; i++ ) {
|
||||
comp = node->_components.iter();
|
||||
if( (int)i != node->unique_opnds_idx(i) ) {
|
||||
if (i != node->unique_opnds_idx(i)) {
|
||||
break;
|
||||
}
|
||||
new_num_opnds++;
|
||||
@ -1795,7 +1800,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
||||
// Replace not unique operands with next unique operands.
|
||||
for( ; i < cur_num_opnds; i++ ) {
|
||||
comp = node->_components.iter();
|
||||
int j = node->unique_opnds_idx(i);
|
||||
uint j = node->unique_opnds_idx(i);
|
||||
// unique_opnds_idx(i) is unique if unique_opnds_idx(j) is not unique.
|
||||
if( j != node->unique_opnds_idx(j) ) {
|
||||
fprintf(fp," set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n",
|
||||
|
@ -2232,6 +2232,7 @@ void LIRGenerator::do_UnsafeGetObject(UnsafeGetObject* x) {
|
||||
// We still need to continue with the checks.
|
||||
if (src.is_constant()) {
|
||||
ciObject* src_con = src.get_jobject_constant();
|
||||
guarantee(src_con != NULL, "no source constant");
|
||||
|
||||
if (src_con->is_null_object()) {
|
||||
// The constant src object is null - We can skip
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "memory/gcLocker.hpp"
|
||||
#include "memory/metadataFactory.hpp"
|
||||
#include "memory/oopFactory.hpp"
|
||||
#include "memory/referenceType.hpp"
|
||||
#include "memory/universe.inline.hpp"
|
||||
#include "oops/constantPool.hpp"
|
||||
#include "oops/fieldStreams.hpp"
|
||||
@ -444,8 +445,8 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
|
||||
break;
|
||||
case JVM_REF_invokeStatic:
|
||||
case JVM_REF_invokeSpecial:
|
||||
check_property(
|
||||
tag.is_method() || tag.is_interface_method(),
|
||||
check_property(tag.is_method() ||
|
||||
((_major_version >= JAVA_8_VERSION) && tag.is_interface_method()),
|
||||
"Invalid constant pool index %u in class file %s (not a method)",
|
||||
ref_index, CHECK_(nullHandle));
|
||||
break;
|
||||
@ -3152,7 +3153,6 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
||||
}
|
||||
}
|
||||
}
|
||||
int contended_count = nonstatic_contended_count;
|
||||
|
||||
|
||||
// Calculate the starting byte offsets
|
||||
@ -3177,35 +3177,52 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
||||
|
||||
next_nonstatic_field_offset = nonstatic_fields_start;
|
||||
|
||||
bool is_contended_class = parsed_annotations->is_contended();
|
||||
|
||||
// Class is contended, pad before all the fields
|
||||
if (parsed_annotations->is_contended()) {
|
||||
if (is_contended_class) {
|
||||
next_nonstatic_field_offset += ContendedPaddingWidth;
|
||||
}
|
||||
|
||||
// Compute the non-contended fields count
|
||||
// Compute the non-contended fields count.
|
||||
// The packing code below relies on these counts to determine if some field
|
||||
// can be squeezed into the alignment gap. Contended fields are obviously
|
||||
// exempt from that.
|
||||
unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
|
||||
unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD];
|
||||
unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT];
|
||||
unsigned int nonstatic_byte_count = fac->count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE];
|
||||
unsigned int nonstatic_oop_count = fac->count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP];
|
||||
|
||||
// Total non-static fields count, including every contended field
|
||||
unsigned int nonstatic_fields_count = fac->count[NONSTATIC_DOUBLE] + fac->count[NONSTATIC_WORD] +
|
||||
fac->count[NONSTATIC_SHORT] + fac->count[NONSTATIC_BYTE] +
|
||||
fac->count[NONSTATIC_OOP];
|
||||
|
||||
bool super_has_nonstatic_fields =
|
||||
(_super_klass() != NULL && _super_klass->has_nonstatic_fields());
|
||||
bool has_nonstatic_fields = super_has_nonstatic_fields ||
|
||||
((nonstatic_double_count + nonstatic_word_count +
|
||||
nonstatic_short_count + nonstatic_byte_count +
|
||||
nonstatic_oop_count) != 0);
|
||||
bool has_nonstatic_fields = super_has_nonstatic_fields || (nonstatic_fields_count != 0);
|
||||
|
||||
|
||||
// Prepare list of oops for oop map generation.
|
||||
//
|
||||
// "offset" and "count" lists are describing the set of contiguous oop
|
||||
// regions. offset[i] is the start of the i-th region, which then has
|
||||
// count[i] oops following. Before we know how many regions are required,
|
||||
// we pessimistically allocate the maps to fit all the oops into the
|
||||
// distinct regions.
|
||||
//
|
||||
// TODO: We add +1 to always allocate non-zero resource arrays; we need
|
||||
// to figure out if we still need to do this.
|
||||
int* nonstatic_oop_offsets;
|
||||
unsigned int* nonstatic_oop_counts;
|
||||
unsigned int nonstatic_oop_map_count = 0;
|
||||
unsigned int max_nonstatic_oop_maps = fac->count[NONSTATIC_OOP] + 1;
|
||||
|
||||
nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD(
|
||||
THREAD, int, nonstatic_oop_count + 1);
|
||||
THREAD, int, max_nonstatic_oop_maps);
|
||||
nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD(
|
||||
THREAD, unsigned int, nonstatic_oop_count + 1);
|
||||
THREAD, unsigned int, max_nonstatic_oop_maps);
|
||||
|
||||
first_nonstatic_oop_offset = 0; // will be set for first oop field
|
||||
|
||||
@ -3392,9 +3409,11 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
||||
int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
|
||||
heapOopSize ) {
|
||||
// Extend current oop map
|
||||
assert(nonstatic_oop_map_count - 1 < max_nonstatic_oop_maps, "range check");
|
||||
nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
|
||||
} else {
|
||||
// Create new oop map
|
||||
assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
|
||||
nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
|
||||
nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
|
||||
nonstatic_oop_map_count += 1;
|
||||
@ -3452,12 +3471,10 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
||||
//
|
||||
// Additionally, this should not break alignment for the fields, so we round the alignment up
|
||||
// for each field.
|
||||
if (contended_count > 0) {
|
||||
if (nonstatic_contended_count > 0) {
|
||||
|
||||
// if there is at least one contended field, we need to have pre-padding for them
|
||||
if (nonstatic_contended_count > 0) {
|
||||
next_nonstatic_padded_offset += ContendedPaddingWidth;
|
||||
}
|
||||
next_nonstatic_padded_offset += ContendedPaddingWidth;
|
||||
|
||||
// collect all contended groups
|
||||
BitMap bm(_cp->size());
|
||||
@ -3518,6 +3535,7 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
||||
next_nonstatic_padded_offset += heapOopSize;
|
||||
|
||||
// Create new oop map
|
||||
assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
|
||||
nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
|
||||
nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
|
||||
nonstatic_oop_map_count += 1;
|
||||
@ -3554,18 +3572,17 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
||||
// handle static fields
|
||||
}
|
||||
|
||||
// Size of instances
|
||||
int notaligned_offset = next_nonstatic_padded_offset;
|
||||
|
||||
// Entire class is contended, pad in the back.
|
||||
// This helps to alleviate memory contention effects for subclass fields
|
||||
// and/or adjacent object.
|
||||
if (parsed_annotations->is_contended()) {
|
||||
notaligned_offset += ContendedPaddingWidth;
|
||||
if (is_contended_class) {
|
||||
next_nonstatic_padded_offset += ContendedPaddingWidth;
|
||||
}
|
||||
|
||||
int nonstatic_fields_end = align_size_up(notaligned_offset, heapOopSize);
|
||||
int instance_end = align_size_up(notaligned_offset, wordSize);
|
||||
int notaligned_nonstatic_fields_end = next_nonstatic_padded_offset;
|
||||
|
||||
int nonstatic_fields_end = align_size_up(notaligned_nonstatic_fields_end, heapOopSize);
|
||||
int instance_end = align_size_up(notaligned_nonstatic_fields_end, wordSize);
|
||||
int static_fields_end = align_size_up(next_static_byte_offset, wordSize);
|
||||
|
||||
int static_field_size = (static_fields_end -
|
||||
@ -3579,6 +3596,14 @@ void ClassFileParser::layout_fields(Handle class_loader,
|
||||
(instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize),
|
||||
wordSize) / wordSize), "consistent layout helper value");
|
||||
|
||||
// Invariant: nonstatic_field end/start should only change if there are
|
||||
// nonstatic fields in the class, or if the class is contended. We compare
|
||||
// against the non-aligned value, so that end alignment will not fail the
|
||||
// assert without actually having the fields.
|
||||
assert((notaligned_nonstatic_fields_end == nonstatic_fields_start) ||
|
||||
is_contended_class ||
|
||||
(nonstatic_fields_count > 0), "double-check nonstatic start/end");
|
||||
|
||||
// Number of non-static oop map blocks allocated at end of klass.
|
||||
const unsigned int total_oop_map_count =
|
||||
compute_oop_map_count(_super_klass, nonstatic_oop_map_count,
|
||||
@ -4040,6 +4065,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate mirror and initialize static fields
|
||||
java_lang_Class::create_mirror(this_klass, protection_domain, CHECK_(nullHandle));
|
||||
|
||||
|
||||
#ifdef ASSERT
|
||||
if (ParseAllGenericSignatures) {
|
||||
@ -4055,17 +4083,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||
this_klass(), &all_mirandas, CHECK_(nullHandle));
|
||||
}
|
||||
|
||||
// Allocate mirror and initialize static fields
|
||||
java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
|
||||
|
||||
// Allocate a simple java object for locking during class initialization.
|
||||
// This needs to be a java object because it can be held across a java call.
|
||||
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
|
||||
this_klass->set_init_lock(r);
|
||||
|
||||
// TODO: Move these oops to the mirror
|
||||
this_klass->set_protection_domain(protection_domain());
|
||||
|
||||
// Update the loader_data graph.
|
||||
record_defined_class_dependencies(this_klass, CHECK_NULL);
|
||||
|
||||
|
@ -64,6 +64,11 @@
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
#if INCLUDE_TRACE
|
||||
#include "trace/tracing.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL;
|
||||
|
||||
ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) :
|
||||
@ -120,6 +125,12 @@ void ClassLoaderData::classes_do(KlassClosure* klass_closure) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderData::classes_do(void f(Klass * const)) {
|
||||
for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
|
||||
f(k);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
|
||||
for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
|
||||
if (k->oop_is_instance()) {
|
||||
@ -583,6 +594,19 @@ void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::classes_do(void f(Klass* const)) {
|
||||
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
|
||||
cld->classes_do(f);
|
||||
}
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
|
||||
for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) {
|
||||
cld->classes_do(f);
|
||||
}
|
||||
}
|
||||
|
||||
GrowableArray<ClassLoaderData*>* ClassLoaderDataGraph::new_clds() {
|
||||
assert(_head == NULL || _saved_head != NULL, "remember_new_clds(true) not called?");
|
||||
|
||||
@ -687,6 +711,11 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure) {
|
||||
dead->set_next(_unloading);
|
||||
_unloading = dead;
|
||||
}
|
||||
|
||||
if (seen_dead_loader) {
|
||||
post_class_unload_events();
|
||||
}
|
||||
|
||||
return seen_dead_loader;
|
||||
}
|
||||
|
||||
@ -702,6 +731,20 @@ void ClassLoaderDataGraph::purge() {
|
||||
Metaspace::purge();
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::post_class_unload_events(void) {
|
||||
#if INCLUDE_TRACE
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!");
|
||||
if (Tracing::enabled()) {
|
||||
if (Tracing::is_event_enabled(TraceClassUnloadEvent)) {
|
||||
assert(_unloading != NULL, "need class loader data unload list!");
|
||||
_class_unload_time = Tracing::time();
|
||||
classes_unloading_do(&class_unload_event);
|
||||
}
|
||||
Tracing::on_unloading_classes();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// CDS support
|
||||
|
||||
// Global metaspaces for writing information to the shared archive. When
|
||||
@ -769,3 +812,21 @@ void ClassLoaderData::print_value_on(outputStream* out) const {
|
||||
class_loader()->print_value_on(out);
|
||||
}
|
||||
}
|
||||
|
||||
#if INCLUDE_TRACE
|
||||
|
||||
TracingTime ClassLoaderDataGraph::_class_unload_time;
|
||||
|
||||
void ClassLoaderDataGraph::class_unload_event(Klass* const k) {
|
||||
|
||||
// post class unload event
|
||||
EventClassUnload event(UNTIMED);
|
||||
event.set_endtime(_class_unload_time);
|
||||
event.set_unloadedClass(k);
|
||||
oop defining_class_loader = k->class_loader();
|
||||
event.set_definingClassLoader(defining_class_loader != NULL ?
|
||||
defining_class_loader->klass() : (Klass*)NULL);
|
||||
event.commit();
|
||||
}
|
||||
|
||||
#endif /* INCLUDE_TRACE */
|
||||
|
@ -32,6 +32,10 @@
|
||||
#include "runtime/mutex.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
|
||||
#if INCLUDE_TRACE
|
||||
# include "trace/traceTime.hpp"
|
||||
#endif
|
||||
|
||||
//
|
||||
// A class loader represents a linkset. Conceptually, a linkset identifies
|
||||
// the complete transitive closure of resolved links that a dynamic linker can
|
||||
@ -49,6 +53,7 @@ class ClassLoaderData;
|
||||
class JNIMethodBlock;
|
||||
class JNIHandleBlock;
|
||||
class Metadebug;
|
||||
|
||||
// GC root for walking class loader data created
|
||||
|
||||
class ClassLoaderDataGraph : public AllStatic {
|
||||
@ -63,6 +68,7 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
static ClassLoaderData* _saved_head;
|
||||
|
||||
static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS);
|
||||
static void post_class_unload_events(void);
|
||||
public:
|
||||
static ClassLoaderData* find_or_create(Handle class_loader, TRAPS);
|
||||
static void purge();
|
||||
@ -71,6 +77,8 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
static void always_strong_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
|
||||
static void keep_alive_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
|
||||
static void classes_do(KlassClosure* klass_closure);
|
||||
static void classes_do(void f(Klass* const));
|
||||
static void classes_unloading_do(void f(Klass* const));
|
||||
static bool do_unloading(BoolObjectClosure* is_alive);
|
||||
|
||||
// CMS support.
|
||||
@ -86,6 +94,12 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
static bool contains(address x);
|
||||
static bool contains_loader_data(ClassLoaderData* loader_data);
|
||||
#endif
|
||||
|
||||
#if INCLUDE_TRACE
|
||||
private:
|
||||
static TracingTime _class_unload_time;
|
||||
static void class_unload_event(Klass* const k);
|
||||
#endif
|
||||
};
|
||||
|
||||
// ClassLoaderData class
|
||||
@ -171,7 +185,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||||
void unload();
|
||||
bool keep_alive() const { return _keep_alive; }
|
||||
bool is_alive(BoolObjectClosure* is_alive_closure) const;
|
||||
|
||||
void classes_do(void f(Klass*));
|
||||
void classes_do(void f(InstanceKlass*));
|
||||
|
||||
// Deallocate free list during class unloading.
|
||||
|
@ -1349,6 +1349,7 @@ static void merge_in_new_methods(InstanceKlass* klass,
|
||||
|
||||
// Replace klass methods with new merged lists
|
||||
klass->set_methods(merged_methods);
|
||||
klass->set_initial_method_idnum(new_size);
|
||||
|
||||
ClassLoaderData* cld = klass->class_loader_data();
|
||||
MetadataFactory::free_array(cld, original_methods);
|
||||
|
@ -512,22 +512,22 @@ void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
|
||||
|
||||
// If the offset was read from the shared archive, it was fixed up already
|
||||
if (!k->is_shared()) {
|
||||
if (k->oop_is_instance()) {
|
||||
// During bootstrap, java.lang.Class wasn't loaded so static field
|
||||
// offsets were computed without the size added it. Go back and
|
||||
// update all the static field offsets to included the size.
|
||||
for (JavaFieldStream fs(InstanceKlass::cast(k())); !fs.done(); fs.next()) {
|
||||
if (fs.access_flags().is_static()) {
|
||||
int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
|
||||
fs.set_offset(real_offset);
|
||||
if (k->oop_is_instance()) {
|
||||
// During bootstrap, java.lang.Class wasn't loaded so static field
|
||||
// offsets were computed without the size added it. Go back and
|
||||
// update all the static field offsets to included the size.
|
||||
for (JavaFieldStream fs(InstanceKlass::cast(k())); !fs.done(); fs.next()) {
|
||||
if (fs.access_flags().is_static()) {
|
||||
int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
|
||||
fs.set_offset(real_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
create_mirror(k, CHECK);
|
||||
create_mirror(k, Handle(NULL), CHECK);
|
||||
}
|
||||
|
||||
oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
|
||||
oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
|
||||
assert(k->java_mirror() == NULL, "should only assign mirror once");
|
||||
// Use this moment of initialization to cache modifier_flags also,
|
||||
// to support Class.getModifiers(). Instance classes recalculate
|
||||
@ -563,6 +563,16 @@ oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
|
||||
set_array_klass(comp_mirror(), k());
|
||||
} else {
|
||||
assert(k->oop_is_instance(), "Must be");
|
||||
|
||||
// Allocate a simple java object for a lock.
|
||||
// This needs to be a java object because during class initialization
|
||||
// it can be held across a java call.
|
||||
typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
|
||||
set_init_lock(mirror(), r);
|
||||
|
||||
// Set protection domain also
|
||||
set_protection_domain(mirror(), protection_domain());
|
||||
|
||||
// Initialize static fields
|
||||
InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
|
||||
}
|
||||
@ -597,6 +607,34 @@ void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
|
||||
java_class->int_field_put(_static_oop_field_count_offset, size);
|
||||
}
|
||||
|
||||
oop java_lang_Class::protection_domain(oop java_class) {
|
||||
assert(_protection_domain_offset != 0, "must be set");
|
||||
return java_class->obj_field(_protection_domain_offset);
|
||||
}
|
||||
void java_lang_Class::set_protection_domain(oop java_class, oop pd) {
|
||||
assert(_protection_domain_offset != 0, "must be set");
|
||||
java_class->obj_field_put(_protection_domain_offset, pd);
|
||||
}
|
||||
|
||||
oop java_lang_Class::init_lock(oop java_class) {
|
||||
assert(_init_lock_offset != 0, "must be set");
|
||||
return java_class->obj_field(_init_lock_offset);
|
||||
}
|
||||
void java_lang_Class::set_init_lock(oop java_class, oop init_lock) {
|
||||
assert(_init_lock_offset != 0, "must be set");
|
||||
java_class->obj_field_put(_init_lock_offset, init_lock);
|
||||
}
|
||||
|
||||
objArrayOop java_lang_Class::signers(oop java_class) {
|
||||
assert(_signers_offset != 0, "must be set");
|
||||
return (objArrayOop)java_class->obj_field(_signers_offset);
|
||||
}
|
||||
void java_lang_Class::set_signers(oop java_class, objArrayOop signers) {
|
||||
assert(_signers_offset != 0, "must be set");
|
||||
java_class->obj_field_put(_signers_offset, (oop)signers);
|
||||
}
|
||||
|
||||
|
||||
oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
|
||||
// This should be improved by adding a field at the Java level or by
|
||||
// introducing a new VM klass (see comment in ClassFileParser)
|
||||
@ -923,7 +961,7 @@ void java_lang_Thread::set_thread_status(oop java_thread,
|
||||
|
||||
// Read thread status value from threadStatus field in java.lang.Thread java class.
|
||||
java_lang_Thread::ThreadStatus java_lang_Thread::get_thread_status(oop java_thread) {
|
||||
assert(Thread::current()->is_VM_thread() ||
|
||||
assert(Thread::current()->is_Watcher_thread() || Thread::current()->is_VM_thread() ||
|
||||
JavaThread::current()->thread_state() == _thread_in_vm,
|
||||
"Java Thread is not running in vm");
|
||||
// The threadStatus is only present starting in 1.5
|
||||
@ -2934,6 +2972,9 @@ int java_lang_Class::_klass_offset;
|
||||
int java_lang_Class::_array_klass_offset;
|
||||
int java_lang_Class::_oop_size_offset;
|
||||
int java_lang_Class::_static_oop_field_count_offset;
|
||||
int java_lang_Class::_protection_domain_offset;
|
||||
int java_lang_Class::_init_lock_offset;
|
||||
int java_lang_Class::_signers_offset;
|
||||
GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL;
|
||||
int java_lang_Throwable::backtrace_offset;
|
||||
int java_lang_Throwable::detailMessage_offset;
|
||||
|
@ -208,7 +208,10 @@ class java_lang_String : AllStatic {
|
||||
macro(java_lang_Class, klass, intptr_signature, false) \
|
||||
macro(java_lang_Class, array_klass, intptr_signature, false) \
|
||||
macro(java_lang_Class, oop_size, int_signature, false) \
|
||||
macro(java_lang_Class, static_oop_field_count, int_signature, false)
|
||||
macro(java_lang_Class, static_oop_field_count, int_signature, false) \
|
||||
macro(java_lang_Class, protection_domain, object_signature, false) \
|
||||
macro(java_lang_Class, init_lock, object_signature, false) \
|
||||
macro(java_lang_Class, signers, object_signature, false)
|
||||
|
||||
class java_lang_Class : AllStatic {
|
||||
friend class VMStructs;
|
||||
@ -222,15 +225,20 @@ class java_lang_Class : AllStatic {
|
||||
static int _oop_size_offset;
|
||||
static int _static_oop_field_count_offset;
|
||||
|
||||
static int _protection_domain_offset;
|
||||
static int _init_lock_offset;
|
||||
static int _signers_offset;
|
||||
|
||||
static bool offsets_computed;
|
||||
static int classRedefinedCount_offset;
|
||||
static GrowableArray<Klass*>* _fixup_mirror_list;
|
||||
|
||||
static void set_init_lock(oop java_class, oop init_lock);
|
||||
public:
|
||||
static void compute_offsets();
|
||||
|
||||
// Instance creation
|
||||
static oop create_mirror(KlassHandle k, TRAPS);
|
||||
static oop create_mirror(KlassHandle k, Handle protection_domain, TRAPS);
|
||||
static void fixup_mirror(KlassHandle k, TRAPS);
|
||||
static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
|
||||
// Conversion
|
||||
@ -262,6 +270,13 @@ class java_lang_Class : AllStatic {
|
||||
static int classRedefinedCount(oop the_class_mirror);
|
||||
static void set_classRedefinedCount(oop the_class_mirror, int value);
|
||||
|
||||
// Support for embedded per-class oops
|
||||
static oop protection_domain(oop java_class);
|
||||
static void set_protection_domain(oop java_class, oop protection_domain);
|
||||
static oop init_lock(oop java_class);
|
||||
static objArrayOop signers(oop java_class);
|
||||
static void set_signers(oop java_class, objArrayOop signers);
|
||||
|
||||
static int oop_size(oop java_class);
|
||||
static void set_oop_size(oop java_class, int size);
|
||||
static int static_oop_field_count(oop java_class);
|
||||
|
@ -737,7 +737,7 @@ oop StringTable::intern(const char* utf8_string, TRAPS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void StringTable::unlink(BoolObjectClosure* is_alive) {
|
||||
void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
|
||||
// Readers of the table are unlocked, so we should only be removing
|
||||
// entries at a safepoint.
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
|
||||
@ -745,41 +745,31 @@ void StringTable::unlink(BoolObjectClosure* is_alive) {
|
||||
HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
|
||||
HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
|
||||
while (entry != NULL) {
|
||||
// Shared entries are normally at the end of the bucket and if we run into
|
||||
// a shared entry, then there is nothing more to remove. However, if we
|
||||
// have rehashed the table, then the shared entries are no longer at the
|
||||
// end of the bucket.
|
||||
if (entry->is_shared() && !use_alternate_hashcode()) {
|
||||
break;
|
||||
}
|
||||
assert(entry->literal() != NULL, "just checking");
|
||||
if (entry->is_shared() || is_alive->do_object_b(entry->literal())) {
|
||||
assert(!entry->is_shared(), "CDS not used for the StringTable");
|
||||
|
||||
if (is_alive->do_object_b(entry->literal())) {
|
||||
if (f != NULL) {
|
||||
f->do_oop((oop*)entry->literal_addr());
|
||||
}
|
||||
p = entry->next_addr();
|
||||
} else {
|
||||
*p = entry->next();
|
||||
the_table()->free_entry(entry);
|
||||
}
|
||||
entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
|
||||
entry = *p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StringTable::oops_do(OopClosure* f) {
|
||||
for (int i = 0; i < the_table()->table_size(); ++i) {
|
||||
HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
|
||||
HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
|
||||
while (entry != NULL) {
|
||||
assert(!entry->is_shared(), "CDS not used for the StringTable");
|
||||
|
||||
f->do_oop((oop*)entry->literal_addr());
|
||||
|
||||
// Did the closure remove the literal from the table?
|
||||
if (entry->literal() == NULL) {
|
||||
assert(!entry->is_shared(), "immutable hashtable entry?");
|
||||
*p = entry->next();
|
||||
the_table()->free_entry(entry);
|
||||
} else {
|
||||
p = entry->next_addr();
|
||||
}
|
||||
entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
|
||||
entry = entry->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -272,7 +272,10 @@ public:
|
||||
|
||||
// GC support
|
||||
// Delete pointers to otherwise-unreachable objects.
|
||||
static void unlink(BoolObjectClosure* cl);
|
||||
static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f);
|
||||
static void unlink(BoolObjectClosure* cl) {
|
||||
unlink_or_oops_do(cl, NULL);
|
||||
}
|
||||
|
||||
// Invoke "f->do_oop" on the locations of all oops in the table.
|
||||
static void oops_do(OopClosure* f);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user