mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-10 18:38:27 +00:00
Merge
This commit is contained in:
commit
9fc2b0affb
1
.hgtags
1
.hgtags
@ -249,3 +249,4 @@ b32e2219736e42baaf45daf0ad67ed34f6033799 jdk9-b02
|
||||
099891b1d86f3719e116ac717ffdafc90d037fb7 jdk9-b04
|
||||
dd311791ad6895a3989020dd6c6c46db87972ab8 jdk9-b05
|
||||
85dbdc227c5e11429b4fc4a8ba763f50107edd6e jdk9-b06
|
||||
c826d05f1fb0773f6a28caa763307dd30d90d36e jdk9-b07
|
||||
|
||||
@ -249,3 +249,4 @@ fd8d51bdf9aadf7ae83e65e8655c53581017c363 jdk9-b03
|
||||
cb4c3440bc2748101923e2488506e61009ab1bf5 jdk9-b04
|
||||
8c63f0b6ada282f27e3a80125e53c3be603f9af7 jdk9-b05
|
||||
d0b525cd31b87abeb6d5b7e3516953eeb13b323c jdk9-b06
|
||||
0ea015c298b201c07fa33990f2445b6d0ef3566d jdk9-b07
|
||||
|
||||
@ -46,10 +46,24 @@ AC_DEFUN([ADD_JVM_ARG_IF_OK],
|
||||
# Appends a string to a path variable, only adding the : when needed.
|
||||
AC_DEFUN([BASIC_APPEND_TO_PATH],
|
||||
[
|
||||
if test "x[$]$1" = x; then
|
||||
$1="$2"
|
||||
else
|
||||
$1="[$]$1:$2"
|
||||
if test "x$2" != x; then
|
||||
if test "x[$]$1" = x; then
|
||||
$1="$2"
|
||||
else
|
||||
$1="[$]$1:$2"
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
# Prepends a string to a path variable, only adding the : when needed.
|
||||
AC_DEFUN([BASIC_PREPEND_TO_PATH],
|
||||
[
|
||||
if test "x$2" != x; then
|
||||
if test "x[$]$1" = x; then
|
||||
$1="$2"
|
||||
else
|
||||
$1="$2:[$]$1"
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
@ -442,43 +456,95 @@ AC_DEFUN_ONCE([BASIC_SETUP_PATHS],
|
||||
|
||||
# Locate the directory of this script.
|
||||
AUTOCONF_DIR=$TOPDIR/common/autoconf
|
||||
])
|
||||
|
||||
AC_DEFUN_ONCE([BASIC_SETUP_DEVKIT],
|
||||
[
|
||||
AC_ARG_WITH([devkit], [AS_HELP_STRING([--with-devkit],
|
||||
[use this devkit for compilers, tools and resources])],
|
||||
[
|
||||
BASIC_FIXUP_PATH([with_devkit])
|
||||
DEVKIT_ROOT="$with_devkit"
|
||||
# Check for a meta data info file in the root of the devkit
|
||||
if test -f "$DEVKIT_ROOT/devkit.info"; then
|
||||
# This potentially sets the following:
|
||||
# DEVKIT_NAME: A descriptive name of the devkit
|
||||
# DEVKIT_TOOLCHAIN_PATH: Corresponds to --with-toolchain-path
|
||||
# DEVKIT_EXTRA_PATH: Corresponds to --with-extra-path
|
||||
# DEVKIT_SYSROOT: Corresponds to --with-sysroot
|
||||
. $DEVKIT_ROOT/devkit.info
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for devkit])
|
||||
if test "x$DEVKIT_NAME" != x; then
|
||||
AC_MSG_RESULT([$DEVKIT_NAME in $DEVKIT_ROOT])
|
||||
else
|
||||
AC_MSG_RESULT([$DEVKIT_ROOT])
|
||||
fi
|
||||
|
||||
if test "x$DEVKIT_EXTRA_PATH" != x; then
|
||||
BASIC_PREPEND_TO_PATH([EXTRA_PATH],$DEVKIT_EXTRA_PATH)
|
||||
fi
|
||||
|
||||
# Fallback default of just /bin if DEVKIT_PATH is not defined
|
||||
if test "x$DEVKIT_TOOLCHAIN_PATH" = x; then
|
||||
DEVKIT_TOOLCHAIN_PATH="$DEVKIT_ROOT/bin"
|
||||
fi
|
||||
BASIC_PREPEND_TO_PATH([TOOLCHAIN_PATH],$DEVKIT_TOOLCHAIN_PATH)
|
||||
|
||||
# If DEVKIT_SYSROOT is set, use that, otherwise try a couple of known
|
||||
# places for backwards compatiblity.
|
||||
if test "x$DEVKIT_SYSROOT" != x; then
|
||||
SYSROOT="$DEVKIT_SYSROOT"
|
||||
elif test -d "$DEVKIT_ROOT/$host_alias/libc"; then
|
||||
SYSROOT="$DEVKIT_ROOT/$host_alias/libc"
|
||||
elif test -d "$DEVKIT_ROOT/$host/sys-root"; then
|
||||
SYSROOT="$DEVKIT_ROOT/$host/sys-root"
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
# You can force the sysroot if the sysroot encoded into the compiler tools
|
||||
# is not correct.
|
||||
AC_ARG_WITH(sys-root, [AS_HELP_STRING([--with-sys-root],
|
||||
[alias for --with-sysroot for backwards compatability])],
|
||||
[SYSROOT=$with_sys_root]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(sysroot, [AS_HELP_STRING([--with-sysroot],
|
||||
[use this directory as sysroot)])],
|
||||
[SYSROOT=$with_sysroot]
|
||||
)
|
||||
|
||||
AC_ARG_WITH([tools-dir], [AS_HELP_STRING([--with-tools-dir],
|
||||
[alias for --with-toolchain-path for backwards compatibility])],
|
||||
[BASIC_PREPEND_TO_PATH([TOOLCHAIN_PATH],$with_tools_dir)]
|
||||
)
|
||||
|
||||
AC_ARG_WITH([toolchain-path], [AS_HELP_STRING([--with-toolchain-path],
|
||||
[prepend these directories when searching for toolchain binaries (compilers etc)])],
|
||||
[BASIC_PREPEND_TO_PATH([TOOLCHAIN_PATH],$with_toolchain_path)]
|
||||
)
|
||||
|
||||
AC_ARG_WITH([extra-path], [AS_HELP_STRING([--with-extra-path],
|
||||
[prepend these directories to the default path])],
|
||||
[BASIC_PREPEND_TO_PATH([EXTRA_PATH],$with_extra_path)]
|
||||
)
|
||||
|
||||
# Prepend the extra path to the global path
|
||||
BASIC_PREPEND_TO_PATH([PATH],$EXTRA_PATH)
|
||||
|
||||
if test "x$OPENJDK_BUILD_OS" = "xsolaris"; then
|
||||
# Add extra search paths on solaris for utilities like ar and as etc...
|
||||
PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin"
|
||||
fi
|
||||
|
||||
# You can force the sys-root if the sys-root encoded into the cross compiler tools
|
||||
# is not correct.
|
||||
AC_ARG_WITH(sys-root, [AS_HELP_STRING([--with-sys-root],
|
||||
[pass this sys-root to the compilers and tools (for cross-compiling)])])
|
||||
|
||||
if test "x$with_sys_root" != x; then
|
||||
SYS_ROOT=$with_sys_root
|
||||
else
|
||||
SYS_ROOT=/
|
||||
fi
|
||||
AC_SUBST(SYS_ROOT)
|
||||
|
||||
AC_ARG_WITH([tools-dir], [AS_HELP_STRING([--with-tools-dir],
|
||||
[search this directory for compilers and tools (for cross-compiling)])],
|
||||
[TOOLS_DIR=$with_tools_dir]
|
||||
)
|
||||
|
||||
AC_ARG_WITH([devkit], [AS_HELP_STRING([--with-devkit],
|
||||
[use this directory as base for tools-dir and sys-root (for cross-compiling)])],
|
||||
[
|
||||
if test "x$with_sys_root" != x; then
|
||||
AC_MSG_ERROR([Cannot specify both --with-devkit and --with-sys-root at the same time])
|
||||
fi
|
||||
BASIC_FIXUP_PATH([with_devkit])
|
||||
BASIC_APPEND_TO_PATH([TOOLS_DIR],$with_devkit/bin)
|
||||
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
|
||||
])
|
||||
AC_MSG_CHECKING([for sysroot])
|
||||
AC_MSG_RESULT([$SYSROOT])
|
||||
AC_MSG_CHECKING([for toolchain path])
|
||||
AC_MSG_RESULT([$TOOLCHAIN_PATH])
|
||||
AC_MSG_CHECKING([for extra path])
|
||||
AC_MSG_RESULT([$EXTRA_PATH])
|
||||
])
|
||||
|
||||
AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
|
||||
@ -648,10 +714,10 @@ AC_DEFUN([BASIC_CHECK_GNU_MAKE],
|
||||
fi
|
||||
|
||||
if test "x$FOUND_MAKE" = x; then
|
||||
if test "x$TOOLS_DIR" != x; then
|
||||
# We have a tools-dir, check that as well before giving up.
|
||||
if test "x$TOOLCHAIN_PATH" != x; then
|
||||
# We have a toolchain path, check that as well before giving up.
|
||||
OLD_PATH=$PATH
|
||||
PATH=$TOOLS_DIR:$PATH
|
||||
PATH=$TOOLCHAIN_PATH:$PATH
|
||||
AC_PATH_PROGS(CHECK_TOOLSDIR_GMAKE, gmake)
|
||||
BASIC_CHECK_MAKE_VERSION("$CHECK_TOOLSDIR_GMAKE", [gmake in tools-dir])
|
||||
if test "x$FOUND_MAKE" = x; then
|
||||
|
||||
10
common/autoconf/build-aux/config.guess
vendored
10
common/autoconf/build-aux/config.guess
vendored
@ -76,4 +76,14 @@ if test $? = 0; then
|
||||
OUT=powerpc$KERNEL_BITMODE`echo $OUT | sed -e 's/[^-]*//'`
|
||||
fi
|
||||
|
||||
# Test and fix little endian PowerPC64.
|
||||
# TODO: should be handled by autoconf-config.guess.
|
||||
if [ "x$OUT" = x ]; then
|
||||
if [ `uname -m` = ppc64le ]; then
|
||||
if [ `uname -s` = Linux ]; then
|
||||
OUT=powerpc64le-unknown-linux-gnu
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo $OUT
|
||||
|
||||
@ -169,8 +169,8 @@ AC_DEFUN([BPERF_SETUP_CCACHE],
|
||||
if test "x$enable_ccache" = xyes; then
|
||||
AC_MSG_RESULT([yes])
|
||||
OLD_PATH="$PATH"
|
||||
if test "x$TOOLS_DIR" != x; then
|
||||
PATH=$TOOLS_DIR:$PATH
|
||||
if test "x$TOOLCHAIN_PATH" != x; then
|
||||
PATH=$TOOLCHAIN_PATH:$PATH
|
||||
fi
|
||||
BASIC_REQUIRE_PROGS(CCACHE, ccache)
|
||||
CCACHE_STATUS="enabled"
|
||||
|
||||
@ -100,6 +100,9 @@ JDKOPT_SETUP_DEBUG_LEVEL
|
||||
# With basic setup done, call the custom early hook.
|
||||
CUSTOM_EARLY_HOOK
|
||||
|
||||
# Check if we have devkits, extra paths or sysroot set.
|
||||
BASIC_SETUP_DEVKIT
|
||||
|
||||
# To properly create a configuration name, we need to have the OpenJDK target
|
||||
# and options (variants and debug level) parsed.
|
||||
BASIC_SETUP_OUTPUT_DIR
|
||||
|
||||
@ -119,6 +119,32 @@ AC_DEFUN_ONCE([FLAGS_SETUP_INIT_FLAGS],
|
||||
# FIXME: likely bug, should be CCXXFLAGS_JDK? or one for C or CXX.
|
||||
CCXXFLAGS="$CCXXFLAGS -nologo"
|
||||
fi
|
||||
|
||||
if test "x$SYSROOT" != "x"; then
|
||||
if test "x$TOOLCHAIN_TYPE" = xsolstudio; then
|
||||
if test "x$OPENJDK_TARGET_OS" = xsolaris; then
|
||||
# Solaris Studio does not have a concept of sysroot. Instead we must
|
||||
# make sure the default include and lib dirs are appended to each
|
||||
# compile and link command line.
|
||||
SYSROOT_CFLAGS="-I$SYSROOT/usr/include"
|
||||
SYSROOT_LDFLAGS="-L$SYSROOT/usr/lib$OPENJDK_TARGET_CPU_ISADIR \
|
||||
-L$SYSROOT/lib$OPENJDK_TARGET_CPU_ISADIR \
|
||||
-L$SYSROOT/usr/ccs/lib$OPENJDK_TARGET_CPU_ISADIR"
|
||||
fi
|
||||
elif test "x$TOOLCHAIN_TYPE" = xgcc; then
|
||||
SYSROOT_CFLAGS="--sysroot=\"$SYSROOT\""
|
||||
SYSROOT_LDFLAGS="--sysroot=\"$SYSROOT\""
|
||||
elif test "x$TOOLCHAIN_TYPE" = xclang; then
|
||||
SYSROOT_CFLAGS="-isysroot \"$SYSROOT\""
|
||||
SYSROOT_LDFLAGS="-isysroot \"$SYSROOT\""
|
||||
fi
|
||||
# Propagate the sysroot args to hotspot
|
||||
LEGACY_EXTRA_CFLAGS="$LEGACY_EXTRA_CFLAGS $SYSROOT_CFLAGS"
|
||||
LEGACY_EXTRA_CXXFLAGS="$LEGACY_EXTRA_CXXFLAGS $SYSROOT_CFLAGS"
|
||||
LEGACY_EXTRA_LDFLAGS="$LEGACY_EXTRA_LDFLAGS $SYSROOT_LDFLAGS"
|
||||
fi
|
||||
AC_SUBST(SYSROOT_CFLAGS)
|
||||
AC_SUBST(SYSROOT_LDFLAGS)
|
||||
])
|
||||
|
||||
AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_LIBS],
|
||||
@ -421,9 +447,9 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
|
||||
LDFLAGS_JDK="${LDFLAGS_JDK} $with_extra_ldflags"
|
||||
|
||||
# Hotspot needs these set in their legacy form
|
||||
LEGACY_EXTRA_CFLAGS=$with_extra_cflags
|
||||
LEGACY_EXTRA_CXXFLAGS=$with_extra_cxxflags
|
||||
LEGACY_EXTRA_LDFLAGS=$with_extra_ldflags
|
||||
LEGACY_EXTRA_CFLAGS="$LEGACY_EXTRA_CFLAGS $with_extra_cflags"
|
||||
LEGACY_EXTRA_CXXFLAGS="$LEGACY_EXTRA_CXXFLAGS $with_extra_cxxflags"
|
||||
LEGACY_EXTRA_LDFLAGS="$LEGACY_EXTRA_LDFLAGS $with_extra_ldflags"
|
||||
|
||||
AC_SUBST(LEGACY_EXTRA_CFLAGS)
|
||||
AC_SUBST(LEGACY_EXTRA_CXXFLAGS)
|
||||
@ -521,7 +547,13 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK],
|
||||
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -D_LITTLE_ENDIAN"
|
||||
fi
|
||||
else
|
||||
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -D_BIG_ENDIAN"
|
||||
# Same goes for _BIG_ENDIAN. Do we really need to set *ENDIAN on Solaris if they
|
||||
# are defined in the system?
|
||||
if test "x$OPENJDK_TARGET_OS" = xsolaris; then
|
||||
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -D_BIG_ENDIAN="
|
||||
else
|
||||
CCXXFLAGS_JDK="$CCXXFLAGS_JDK -D_BIG_ENDIAN"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Setup target OS define. Use OS target name but in upper case.
|
||||
@ -735,4 +767,20 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_MISC],
|
||||
[COMPILER_SUPPORTS_TARGET_BITS_FLAG=true],
|
||||
[COMPILER_SUPPORTS_TARGET_BITS_FLAG=false])
|
||||
AC_SUBST(COMPILER_SUPPORTS_TARGET_BITS_FLAG)
|
||||
|
||||
case "${TOOLCHAIN_TYPE}" in
|
||||
microsoft)
|
||||
CFLAGS_WARNINGS_ARE_ERRORS="/WX"
|
||||
;;
|
||||
solstudio)
|
||||
CFLAGS_WARNINGS_ARE_ERRORS="-errtags -errwarn=%all"
|
||||
;;
|
||||
gcc)
|
||||
CFLAGS_WARNINGS_ARE_ERRORS="-Werror"
|
||||
;;
|
||||
clang)
|
||||
CFLAGS_WARNINGS_ARE_ERRORS="-Werror"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(CFLAGS_WARNINGS_ARE_ERRORS)
|
||||
])
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -200,6 +200,7 @@ AC_DEFUN_ONCE([HELP_PRINT_SUMMARY_AND_WARNINGS],
|
||||
printf "\n"
|
||||
printf "Configuration summary:\n"
|
||||
printf "* Debug level: $DEBUG_LEVEL\n"
|
||||
printf "* HS debug level: $HOTSPOT_DEBUG_LEVEL\n"
|
||||
printf "* JDK variant: $JDK_VARIANT\n"
|
||||
printf "* JVM variants: $with_jvm_variants\n"
|
||||
printf "* OpenJDK target: OS: $OPENJDK_TARGET_OS, CPU architecture: $OPENJDK_TARGET_CPU_ARCH, address length: $OPENJDK_TARGET_CPU_BITS\n"
|
||||
|
||||
@ -176,6 +176,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_DEBUG_LEVEL],
|
||||
#
|
||||
# Set the debug level
|
||||
# release: no debug information, all optimizations, no asserts.
|
||||
# optimized: no debug information, all optimizations, no asserts, HotSpot target is 'optimized'.
|
||||
# fastdebug: debug information (-g), all optimizations, all asserts
|
||||
# slowdebug: debug information (-g), no optimizations, all asserts
|
||||
#
|
||||
@ -189,7 +190,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_DEBUG_LEVEL],
|
||||
], [ENABLE_DEBUG="no"])
|
||||
|
||||
AC_ARG_WITH([debug-level], [AS_HELP_STRING([--with-debug-level],
|
||||
[set the debug level (release, fastdebug, slowdebug) @<:@release@:>@])],
|
||||
[set the debug level (release, fastdebug, slowdebug, optimized (HotSpot build only)) @<:@release@:>@])],
|
||||
[
|
||||
DEBUG_LEVEL="${withval}"
|
||||
if test "x$ENABLE_DEBUG" = xyes; then
|
||||
@ -199,6 +200,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_DEBUG_LEVEL],
|
||||
AC_MSG_RESULT([$DEBUG_LEVEL])
|
||||
|
||||
if test "x$DEBUG_LEVEL" != xrelease && \
|
||||
test "x$DEBUG_LEVEL" != xoptimized && \
|
||||
test "x$DEBUG_LEVEL" != xfastdebug && \
|
||||
test "x$DEBUG_LEVEL" != xslowdebug; then
|
||||
AC_MSG_ERROR([Allowed debug levels are: release, fastdebug and slowdebug])
|
||||
@ -235,8 +237,30 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_DEBUG_LEVEL],
|
||||
HOTSPOT_DEBUG_LEVEL="jvmg"
|
||||
HOTSPOT_EXPORT="debug"
|
||||
;;
|
||||
optimized )
|
||||
VARIANT="OPT"
|
||||
FASTDEBUG="false"
|
||||
DEBUG_CLASSFILES="false"
|
||||
BUILD_VARIANT_RELEASE="-optimized"
|
||||
HOTSPOT_DEBUG_LEVEL="optimized"
|
||||
HOTSPOT_EXPORT="optimized"
|
||||
;;
|
||||
esac
|
||||
|
||||
# The debug level 'optimized' is a little special because it is currently only
|
||||
# applicable to the HotSpot build where it means to build a completely
|
||||
# optimized version of the VM without any debugging code (like for the
|
||||
# 'release' debug level which is called 'product' in the HotSpot build) but
|
||||
# with the exception that it can contain additional code which is otherwise
|
||||
# protected by '#ifndef PRODUCT' macros. These 'optimized' builds are used to
|
||||
# test new and/or experimental features which are not intended for customer
|
||||
# shipment. Because these new features need to be tested and benchmarked in
|
||||
# real world scenarios, we want to build the containing JDK at the 'release'
|
||||
# debug level.
|
||||
if test "x$DEBUG_LEVEL" = xoptimized; then
|
||||
DEBUG_LEVEL="release"
|
||||
fi
|
||||
|
||||
#####
|
||||
# Generate the legacy makefile targets for hotspot.
|
||||
# The hotspot api for selecting the build artifacts, really, needs to be improved.
|
||||
|
||||
@ -110,21 +110,23 @@ AC_DEFUN_ONCE([LIB_SETUP_X11],
|
||||
# Check if the user has specified sysroot, but not --x-includes or --x-libraries.
|
||||
# Make a simple check for the libraries at the sysroot, and setup --x-includes and
|
||||
# --x-libraries for the sysroot, if that seems to be correct.
|
||||
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"
|
||||
if test "x$OPENJDK_TARGET_OS" = "xlinux"; then
|
||||
if test "x$SYSROOT" != "x"; then
|
||||
if test "x$x_includes" = xNONE; then
|
||||
if test -f "$SYSROOT/usr/X11R6/include/X11/Xlib.h"; then
|
||||
x_includes="$SYSROOT/usr/X11R6/include"
|
||||
elif test -f "$SYSROOT/usr/include/X11/Xlib.h"; then
|
||||
x_includes="$SYSROOT/usr/include"
|
||||
fi
|
||||
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"
|
||||
if test "x$x_libraries" = xNONE; then
|
||||
if test -f "$SYSROOT/usr/X11R6/lib/libX11.so"; then
|
||||
x_libraries="$SYSROOT/usr/X11R6/lib"
|
||||
elif test "$SYSROOT/usr/lib64/libX11.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
|
||||
x_libraries="$SYSROOT/usr/lib64"
|
||||
elif test -f "$SYSROOT/usr/lib/libX11.so"; then
|
||||
x_libraries="$SYSROOT/usr/lib"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@ -146,9 +148,12 @@ AC_DEFUN_ONCE([LIB_SETUP_X11],
|
||||
|
||||
if test "x$OPENJDK_TARGET_OS" = xsolaris; then
|
||||
OPENWIN_HOME="/usr/openwin"
|
||||
X_CFLAGS="-I$SYSROOT$OPENWIN_HOME/include -I$SYSROOT$OPENWIN_HOME/include/X11/extensions"
|
||||
X_LIBS="-L$SYSROOT$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \
|
||||
-L$SYSROOT$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR \
|
||||
-R$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \
|
||||
-R$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR"
|
||||
fi
|
||||
AC_SUBST(OPENWIN_HOME)
|
||||
|
||||
|
||||
#
|
||||
# Weird Sol10 something check...TODO change to try compile
|
||||
@ -237,14 +242,14 @@ AC_DEFUN_ONCE([LIB_SETUP_CUPS],
|
||||
# Getting nervous now? Lets poke around for standard Solaris third-party
|
||||
# package installation locations.
|
||||
AC_MSG_CHECKING([for cups headers])
|
||||
if test -s /opt/sfw/cups/include/cups/cups.h; then
|
||||
if test -s $SYSROOT/opt/sfw/cups/include/cups/cups.h; then
|
||||
# An SFW package seems to be installed!
|
||||
CUPS_FOUND=yes
|
||||
CUPS_CFLAGS="-I/opt/sfw/cups/include"
|
||||
elif test -s /opt/csw/include/cups/cups.h; then
|
||||
CUPS_CFLAGS="-I$SYSROOT/opt/sfw/cups/include"
|
||||
elif test -s $SYSROOT/opt/csw/include/cups/cups.h; then
|
||||
# A CSW package seems to be installed!
|
||||
CUPS_FOUND=yes
|
||||
CUPS_CFLAGS="-I/opt/csw/include"
|
||||
CUPS_CFLAGS="-I$SYSROOT/opt/csw/include"
|
||||
fi
|
||||
AC_MSG_RESULT([$CUPS_FOUND])
|
||||
fi
|
||||
@ -398,24 +403,27 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$FOUND_FREETYPE" != xyes; then
|
||||
# Check modules using pkg-config, but only if we have it (ugly output results otherwise)
|
||||
if test "x$PKG_CONFIG" != x; then
|
||||
PKG_CHECK_MODULES(FREETYPE, freetype2, [FOUND_FREETYPE=yes], [FOUND_FREETYPE=no])
|
||||
if test "x$FOUND_FREETYPE" = xyes; then
|
||||
# On solaris, pkg_check adds -lz to freetype libs, which isn't necessary for us.
|
||||
FREETYPE_LIBS=`$ECHO $FREETYPE_LIBS | $SED 's/-lz//g'`
|
||||
# 64-bit libs for Solaris x86 are installed in the amd64 subdirectory, change lib to lib/amd64
|
||||
if test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
|
||||
FREETYPE_LIBS=`$ECHO $FREETYPE_LIBS | $SED 's?/lib?/lib/amd64?g'`
|
||||
fi
|
||||
# BDEPS_CHECK_MODULE will set FREETYPE_CFLAGS and _LIBS, but we don't get a lib path for bundling.
|
||||
if test "x$BUNDLE_FREETYPE" = xyes; then
|
||||
AC_MSG_NOTICE([Found freetype using pkg-config, but ignoring since we can not bundle that])
|
||||
FOUND_FREETYPE=no
|
||||
else
|
||||
AC_MSG_CHECKING([for freetype])
|
||||
AC_MSG_RESULT([yes (using pkg-config)])
|
||||
# If we have a sysroot, assume that's where we are supposed to look and skip pkg-config.
|
||||
if test "x$SYSROOT" = x; then
|
||||
if test "x$FOUND_FREETYPE" != xyes; then
|
||||
# Check modules using pkg-config, but only if we have it (ugly output results otherwise)
|
||||
if test "x$PKG_CONFIG" != x; then
|
||||
PKG_CHECK_MODULES(FREETYPE, freetype2, [FOUND_FREETYPE=yes], [FOUND_FREETYPE=no])
|
||||
if test "x$FOUND_FREETYPE" = xyes; then
|
||||
# On solaris, pkg_check adds -lz to freetype libs, which isn't necessary for us.
|
||||
FREETYPE_LIBS=`$ECHO $FREETYPE_LIBS | $SED 's/-lz//g'`
|
||||
# 64-bit libs for Solaris x86 are installed in the amd64 subdirectory, change lib to lib/amd64
|
||||
if test "x$OPENJDK_TARGET_OS" = xsolaris && test "x$OPENJDK_TARGET_CPU" = xx86_64; then
|
||||
FREETYPE_LIBS=`$ECHO $FREETYPE_LIBS | $SED 's?/lib?/lib/amd64?g'`
|
||||
fi
|
||||
# BDEPS_CHECK_MODULE will set FREETYPE_CFLAGS and _LIBS, but we don't get a lib path for bundling.
|
||||
if test "x$BUNDLE_FREETYPE" = xyes; then
|
||||
AC_MSG_NOTICE([Found freetype using pkg-config, but ignoring since we can not bundle that])
|
||||
FOUND_FREETYPE=no
|
||||
else
|
||||
AC_MSG_CHECKING([for freetype])
|
||||
AC_MSG_RESULT([yes (using pkg-config)])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@ -433,21 +441,21 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib], [well-known location])
|
||||
fi
|
||||
else
|
||||
if test "x$SYS_ROOT" = "x/"; then
|
||||
FREETYPE_ROOT=
|
||||
else
|
||||
FREETYPE_ROOT="$SYS_ROOT"
|
||||
fi
|
||||
FREETYPE_BASE_DIR="$FREETYPE_ROOT/usr"
|
||||
FREETYPE_BASE_DIR="$SYSROOT/usr"
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib], [well-known location])
|
||||
|
||||
if test "x$FOUND_FREETYPE" != xyes; then
|
||||
FREETYPE_BASE_DIR="$FREETYPE_ROOT/usr/X11"
|
||||
FREETYPE_BASE_DIR="$SYSROOT/usr/X11"
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib], [well-known location])
|
||||
fi
|
||||
|
||||
if test "x$FOUND_FREETYPE" != xyes; then
|
||||
FREETYPE_BASE_DIR="$FREETYPE_ROOT/usr"
|
||||
FREETYPE_BASE_DIR="$SYSROOT/usr/sfw"
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib], [well-known location])
|
||||
fi
|
||||
|
||||
if test "x$FOUND_FREETYPE" != xyes; then
|
||||
FREETYPE_BASE_DIR="$SYSROOT/usr"
|
||||
if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then
|
||||
LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib/x86_64-linux-gnu], [well-known location])
|
||||
else
|
||||
@ -577,8 +585,11 @@ AC_DEFUN_ONCE([LIB_SETUP_ALSA],
|
||||
if test "x$ALSA_FOUND" = xno; then
|
||||
BDEPS_CHECK_MODULE(ALSA, alsa, xxx, [ALSA_FOUND=yes], [ALSA_FOUND=no])
|
||||
fi
|
||||
if test "x$ALSA_FOUND" = xno; then
|
||||
PKG_CHECK_MODULES(ALSA, alsa, [ALSA_FOUND=yes], [ALSA_FOUND=no])
|
||||
# Do not try pkg-config if we have a sysroot set.
|
||||
if test "x$SYSROOT" = x; then
|
||||
if test "x$ALSA_FOUND" = xno; then
|
||||
PKG_CHECK_MODULES(ALSA, alsa, [ALSA_FOUND=yes], [ALSA_FOUND=no])
|
||||
fi
|
||||
fi
|
||||
if test "x$ALSA_FOUND" = xno; then
|
||||
AC_CHECK_HEADERS([alsa/asoundlib.h],
|
||||
@ -917,7 +928,7 @@ AC_DEFUN_ONCE([LIB_SETUP_STATIC_LINK_LIBSTDCPP],
|
||||
|
||||
# libCrun is the c++ runtime-library with SunStudio (roughly the equivalent of gcc's libstdc++.so)
|
||||
if test "x$TOOLCHAIN_TYPE" = xsolstudio && test "x$LIBCXX" = x; then
|
||||
LIBCXX="/usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libCrun.so.1"
|
||||
LIBCXX="${SYSROOT}/usr/lib${OPENJDK_TARGET_CPU_ISADIR}/libCrun.so.1"
|
||||
fi
|
||||
|
||||
# TODO better (platform agnostic) test
|
||||
|
||||
@ -60,6 +60,12 @@ AC_DEFUN([PLATFORM_EXTRACT_VARS_FROM_CPU],
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=big
|
||||
;;
|
||||
powerpc64le)
|
||||
VAR_CPU=ppc64
|
||||
VAR_CPU_ARCH=ppc
|
||||
VAR_CPU_BITS=64
|
||||
VAR_CPU_ENDIAN=little
|
||||
;;
|
||||
s390)
|
||||
VAR_CPU=s390
|
||||
VAR_CPU_ARCH=s390
|
||||
|
||||
@ -130,10 +130,8 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
|
||||
export LIB:=@VS_LIB@
|
||||
endif
|
||||
|
||||
# The sys root where standard headers and libraries are found.
|
||||
# Usually not needed since the configure script should have
|
||||
# taken it into account already when setting CFLAGS et al.
|
||||
SYS_ROOT:=@SYS_ROOT@
|
||||
SYSROOT_CFLAGS := @SYSROOT_CFLAGS@
|
||||
SYSROOT_LDFLAGS := @SYSROOT_LDFLAGS@
|
||||
|
||||
# Paths to the source code
|
||||
ADD_SRC_ROOT:=@ADD_SRC_ROOT@
|
||||
@ -294,7 +292,6 @@ RMICONNECTOR_IIOP=@RMICONNECTOR_IIOP@
|
||||
# Necessary additional compiler flags to compile X11
|
||||
X_CFLAGS:=@X_CFLAGS@
|
||||
X_LIBS:=@X_LIBS@
|
||||
OPENWIN_HOME:=@OPENWIN_HOME@
|
||||
|
||||
# The lowest required version of macosx to enforce compatiblity for
|
||||
MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@
|
||||
@ -324,6 +321,8 @@ CXX_O_FLAG_NONE:=@CXX_O_FLAG_NONE@
|
||||
C_FLAG_DEPS:=@C_FLAG_DEPS@
|
||||
CXX_FLAG_DEPS:=@CXX_FLAG_DEPS@
|
||||
|
||||
CFLAGS_WARNINGS_ARE_ERRORS:=@CFLAGS_WARNINGS_ARE_ERRORS@
|
||||
|
||||
# Tools that potentially need to be cross compilation aware.
|
||||
CC:=@FIXPATH@ @CCACHE@ @CC@
|
||||
|
||||
|
||||
@ -189,6 +189,12 @@ AC_DEFUN_ONCE([TOOLCHAIN_PRE_DETECTION],
|
||||
# it for DLL resolution in runtime.
|
||||
if test "x$OPENJDK_BUILD_OS" = "xwindows" && test "x$TOOLCHAIN_TYPE" = "xmicrosoft"; then
|
||||
TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV
|
||||
# Reset path to VS_PATH. It will include everything that was on PATH at the time we
|
||||
# ran TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV.
|
||||
PATH="$VS_PATH"
|
||||
# The microsoft toolchain also requires INCLUDE and LIB to be set.
|
||||
export INCLUDE="$VS_INCLUDE"
|
||||
export LIB="$VS_LIB"
|
||||
fi
|
||||
|
||||
# autoconf magic only relies on PATH, so update it if tools dir is specified
|
||||
@ -202,29 +208,11 @@ AC_DEFUN_ONCE([TOOLCHAIN_PRE_DETECTION],
|
||||
PATH="/usr/ccs/bin:$PATH"
|
||||
fi
|
||||
|
||||
# Finally add TOOLS_DIR at the beginning, to allow --with-tools-dir to
|
||||
# Finally add TOOLCHAIN_PATH at the beginning, to allow --with-tools-dir to
|
||||
# override all other locations.
|
||||
if test "x$TOOLS_DIR" != x; then
|
||||
PATH=$TOOLS_DIR:$PATH
|
||||
if test "x$TOOLCHAIN_PATH" != x; then
|
||||
PATH=$TOOLCHAIN_PATH:$PATH
|
||||
fi
|
||||
|
||||
# If a devkit is found on the builddeps server, then prepend its path to the
|
||||
# PATH variable. If there are cross compilers available in the devkit, these
|
||||
# will be found by AC_PROG_CC et al.
|
||||
DEVKIT=
|
||||
BDEPS_CHECK_MODULE(DEVKIT, devkit, xxx,
|
||||
[
|
||||
# Found devkit
|
||||
PATH="$DEVKIT/bin:$PATH"
|
||||
SYS_ROOT="$DEVKIT/${rewritten_target}/sys-root"
|
||||
if test "x$x_includes" = "xNONE"; then
|
||||
x_includes="$SYS_ROOT/usr/include/X11"
|
||||
fi
|
||||
if test "x$x_libraries" = "xNONE"; then
|
||||
x_libraries="$SYS_ROOT/usr/lib"
|
||||
fi
|
||||
],
|
||||
[])
|
||||
])
|
||||
|
||||
# Restore path, etc
|
||||
@ -396,15 +384,15 @@ AC_DEFUN([TOOLCHAIN_FIND_COMPILER],
|
||||
# used.
|
||||
|
||||
$1=
|
||||
# If TOOLS_DIR is set, check for all compiler names in there first
|
||||
# If TOOLCHAIN_PATH is set, check for all compiler names in there first
|
||||
# before checking the rest of the PATH.
|
||||
# FIXME: Now that we prefix the TOOLS_DIR to the PATH in the PRE_DETECTION
|
||||
# step, this should not be necessary.
|
||||
if test -n "$TOOLS_DIR"; then
|
||||
if test -n "$TOOLCHAIN_PATH"; then
|
||||
PATH_save="$PATH"
|
||||
PATH="$TOOLS_DIR"
|
||||
AC_PATH_PROGS(TOOLS_DIR_$1, $SEARCH_LIST)
|
||||
$1=$TOOLS_DIR_$1
|
||||
PATH="$TOOLCHAIN_PATH"
|
||||
AC_PATH_PROGS(TOOLCHAIN_PATH_$1, $SEARCH_LIST)
|
||||
$1=$TOOLCHAIN_PATH_$1
|
||||
PATH="$PATH_save"
|
||||
fi
|
||||
|
||||
|
||||
@ -141,46 +141,44 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV],
|
||||
|
||||
# Lets extract the variables that are set by vcvarsall.bat/vsvars32.bat/vsvars64.bat
|
||||
AC_MSG_NOTICE([Trying to extract Visual Studio environment variables])
|
||||
cd $OUTPUT_ROOT
|
||||
# FIXME: The code betweeen ---- was inlined from a separate script and is not properly adapted
|
||||
# to autoconf standards.
|
||||
|
||||
#----
|
||||
# We need to create a couple of temporary files.
|
||||
VS_ENV_TMP_DIR="$OUTPUT_ROOT/vs-env"
|
||||
$MKDIR -p $VS_ENV_TMP_DIR
|
||||
|
||||
# Cannot use the VS10 setup script directly (since it only updates the DOS subshell environment)
|
||||
# but calculate the difference in Cygwin environment before/after running it and then
|
||||
# apply the diff.
|
||||
# Cannot use the VS10 setup script directly (since it only updates the DOS subshell environment).
|
||||
# Instead create a shell script which will set the relevant variables when run.
|
||||
WINPATH_VS_ENV_CMD="$VS_ENV_CMD"
|
||||
BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([WINPATH_VS_ENV_CMD])
|
||||
WINPATH_BASH="$BASH"
|
||||
BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([WINPATH_BASH])
|
||||
|
||||
if test "x$OPENJDK_BUILD_OS_ENV" = xwindows.cygwin; then
|
||||
_vs10varsall=`cygpath -a -m -s "$VS_ENV_CMD"`
|
||||
_dosvs10varsall=`cygpath -a -w -s $_vs10varsall`
|
||||
_dosbash=`cygpath -a -w -s \`which bash\`.*`
|
||||
else
|
||||
_dosvs10varsall=`cmd //c echo $VS_ENV_CMD`
|
||||
_dosbash=`cmd //c echo \`which bash\``
|
||||
fi
|
||||
|
||||
# generate the set of exported vars before/after the vs10 setup
|
||||
$ECHO "@echo off" > localdevenvtmp.bat
|
||||
$ECHO "$_dosbash -c \"export -p\" > localdevenvtmp.export0" >> localdevenvtmp.bat
|
||||
$ECHO "call $_dosvs10varsall $VS_ENV_ARGS" >> localdevenvtmp.bat
|
||||
$ECHO "$_dosbash -c \"export -p\" > localdevenvtmp.export1" >> localdevenvtmp.bat
|
||||
# Generate a DOS batch file which runs $VS_ENV_CMD, and then creates a shell
|
||||
# script (executable by bash) that will setup the important variables.
|
||||
EXTRACT_VC_ENV_BAT_FILE="$VS_ENV_TMP_DIR/extract-vs-env.bat"
|
||||
$ECHO "@echo off" > $EXTRACT_VC_ENV_BAT_FILE
|
||||
# This will end up something like:
|
||||
# call C:/progra~2/micros~2.0/vc/bin/amd64/vcvars64.bat
|
||||
$ECHO "call $WINPATH_VS_ENV_CMD $VS_ENV_ARGS" >> $EXTRACT_VC_ENV_BAT_FILE
|
||||
# These will end up something like:
|
||||
# C:/CygWin/bin/bash -c 'echo VS_PATH=\"$PATH\" > localdevenv.sh
|
||||
# The trailing space for everyone except PATH is no typo, but is needed due
|
||||
# to trailing \ in the Windows paths. These will be stripped later.
|
||||
$ECHO "$WINPATH_BASH -c 'echo VS_PATH="'\"$PATH\" > set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||
$ECHO "$WINPATH_BASH -c 'echo VS_INCLUDE="'\"$INCLUDE \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||
$ECHO "$WINPATH_BASH -c 'echo VS_LIB="'\"$LIB \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||
$ECHO "$WINPATH_BASH -c 'echo VCINSTALLDIR="'\"$VCINSTALLDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||
$ECHO "$WINPATH_BASH -c 'echo WindowsSdkDir="'\"$WindowsSdkDir \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||
$ECHO "$WINPATH_BASH -c 'echo WINDOWSSDKDIR="'\"$WINDOWSSDKDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
|
||||
|
||||
# Now execute the newly created bat file.
|
||||
# The | cat is to stop SetEnv.Cmd to mess with system colors on msys
|
||||
cmd /c localdevenvtmp.bat | cat
|
||||
|
||||
# apply the diff (less some non-vs10 vars named by "!")
|
||||
$SORT localdevenvtmp.export0 | $GREP -v "!" > localdevenvtmp.export0.sort
|
||||
$SORT localdevenvtmp.export1 | $GREP -v "!" > localdevenvtmp.export1.sort
|
||||
$COMM -1 -3 localdevenvtmp.export0.sort localdevenvtmp.export1.sort > localdevenv.sh
|
||||
|
||||
# cleanup
|
||||
$RM localdevenvtmp*
|
||||
#----
|
||||
# The | cat is to stop SetEnv.Cmd to mess with system colors on msys.
|
||||
# Change directory so we don't need to mess with Windows paths in redirects.
|
||||
cd $VS_ENV_TMP_DIR
|
||||
cmd /c extract-vs-env.bat | $CAT
|
||||
cd $CURDIR
|
||||
if test ! -s $OUTPUT_ROOT/localdevenv.sh; then
|
||||
AC_MSG_RESULT([no])
|
||||
|
||||
if test ! -s $VS_ENV_TMP_DIR/set-vs-env.sh; then
|
||||
AC_MSG_NOTICE([Could not succesfully extract the envionment variables needed for the VS setup.])
|
||||
AC_MSG_NOTICE([Try setting --with-tools-dir to the VC/bin directory within the VS installation])
|
||||
AC_MSG_NOTICE([or run "bash.exe -l" from a VS command prompt and then run configure from there.])
|
||||
@ -190,30 +188,36 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV],
|
||||
# Now set all paths and other env variables. This will allow the rest of
|
||||
# the configure script to find and run the compiler in the proper way.
|
||||
AC_MSG_NOTICE([Setting extracted environment variables])
|
||||
. $OUTPUT_ROOT/localdevenv.sh
|
||||
. $VS_ENV_TMP_DIR/set-vs-env.sh
|
||||
# Now we have VS_PATH, VS_INCLUDE, VS_LIB. For further checking, we
|
||||
# also define VCINSTALLDIR, WindowsSdkDir and WINDOWSSDKDIR.
|
||||
else
|
||||
# We did not find a vsvars bat file, let's hope we are run from a VS command prompt.
|
||||
AC_MSG_NOTICE([Cannot locate a valid Visual Studio installation, checking current environment])
|
||||
fi
|
||||
|
||||
# At this point, we should have corrent variables in the environment, or we can't continue.
|
||||
# At this point, we should have correct variables in the environment, or we can't continue.
|
||||
AC_MSG_CHECKING([for Visual Studio variables])
|
||||
|
||||
if test "x$VCINSTALLDIR" != x || test "x$WindowsSDKDir" != x || test "x$WINDOWSSDKDIR" != x; then
|
||||
if test "x$INCLUDE" = x || test "x$LIB" = x; then
|
||||
if test "x$VS_INCLUDE" = x || test "x$VS_LIB" = x; then
|
||||
AC_MSG_RESULT([present but broken])
|
||||
AC_MSG_ERROR([Your VC command prompt seems broken, INCLUDE and/or LIB is missing.])
|
||||
else
|
||||
AC_MSG_RESULT([ok])
|
||||
# Remove any trailing \ from INCLUDE and LIB to avoid trouble in spec.gmk.
|
||||
VS_INCLUDE=`$ECHO "$INCLUDE" | $SED 's/\\\\$//'`
|
||||
VS_LIB=`$ECHO "$LIB" | $SED 's/\\\\$//'`
|
||||
# Remove any paths containing # (typically F#) as that messes up make
|
||||
PATH=`$ECHO "$PATH" | $SED 's/[[^:#]]*#[^:]*://g'`
|
||||
VS_PATH="$PATH"
|
||||
# Remove any trailing "\" and " " from the variables.
|
||||
VS_INCLUDE=`$ECHO "$VS_INCLUDE" | $SED 's/\\\\* *$//'`
|
||||
VS_LIB=`$ECHO "$VS_LIB" | $SED 's/\\\\* *$//'`
|
||||
VCINSTALLDIR=`$ECHO "$VCINSTALLDIR" | $SED 's/\\\\* *$//'`
|
||||
WindowsSDKDir=`$ECHO "$WindowsSDKDir" | $SED 's/\\\\* *$//'`
|
||||
WINDOWSSDKDIR=`$ECHO "$WINDOWSSDKDIR" | $SED 's/\\\\* *$//'`
|
||||
# Remove any paths containing # (typically F#) as that messes up make. This
|
||||
# is needed if visual studio was installed with F# support.
|
||||
VS_PATH=`$ECHO "$VS_PATH" | $SED 's/[[^:#]]*#[^:]*://g'`
|
||||
|
||||
AC_SUBST(VS_PATH)
|
||||
AC_SUBST(VS_INCLUDE)
|
||||
AC_SUBST(VS_LIB)
|
||||
AC_SUBST(VS_PATH)
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([not found])
|
||||
|
||||
@ -114,7 +114,7 @@ diff_text() {
|
||||
fi
|
||||
if test "x$SUFFIX" = "xproperties"; then
|
||||
# Run through nawk to add possibly missing newline at end of file.
|
||||
$CAT $OTHER_FILE | $NAWK '{ print }' > $OTHER_FILE.cleaned
|
||||
$CAT $OTHER_FILE | $NAWK '{ print }' | LC_ALL=C $SORT > $OTHER_FILE.cleaned
|
||||
# Disable this exception since we aren't changing the properties cleaning method yet.
|
||||
# $CAT $OTHER_FILE | $SED -e 's/\([^\\]\):/\1\\:/g' -e 's/\([^\\]\)=/\1\\=/g' -e 's/#.*/#/g' \
|
||||
# | $SED -f "$SRC_ROOT/common/makefiles/support/unicode2x.sed" \
|
||||
|
||||
@ -24,12 +24,58 @@
|
||||
#
|
||||
|
||||
# Shell script for a fast parallel forest command
|
||||
command="$1"
|
||||
pull_extra_base="$2"
|
||||
|
||||
if [ "" = "$command" ] ; then
|
||||
echo No command to hg supplied!
|
||||
exit 1
|
||||
global_opts=""
|
||||
status_output="/dev/stdout"
|
||||
qflag="false"
|
||||
vflag="false"
|
||||
sflag="false"
|
||||
while [ $# -gt 0 ]
|
||||
do
|
||||
case $1 in
|
||||
-q | --quiet )
|
||||
qflag="true"
|
||||
global_opts="${global_opts} -q"
|
||||
status_output="/dev/null"
|
||||
;;
|
||||
|
||||
-v | --verbose )
|
||||
vflag="true"
|
||||
global_opts="${global_opts} -v"
|
||||
;;
|
||||
|
||||
-s | --sequential )
|
||||
sflag="true"
|
||||
;;
|
||||
|
||||
'--' ) # no more options
|
||||
shift; break
|
||||
;;
|
||||
|
||||
-*) # bad option
|
||||
usage
|
||||
;;
|
||||
|
||||
* ) # non option
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
|
||||
command="$1"; shift
|
||||
command_args="$@"
|
||||
|
||||
usage() {
|
||||
echo "usage: $0 [-q|--quiet] [-v|--verbose] [-s|--sequential] [--] <command> [commands...]" > ${status_output}
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
if [ "x" = "x$command" ] ; then
|
||||
echo "ERROR: No command to hg supplied!"
|
||||
usage
|
||||
fi
|
||||
|
||||
# Clean out the temporary directory that stores the pid files.
|
||||
@ -40,17 +86,17 @@ mkdir -p ${tmp}
|
||||
safe_interrupt () {
|
||||
if [ -d ${tmp} ]; then
|
||||
if [ "`ls ${tmp}/*.pid`" != "" ]; then
|
||||
echo "Waiting for processes ( `cat ${tmp}/*.pid | tr '\n' ' '`) to terminate nicely!"
|
||||
echo "Waiting for processes ( `cat ${tmp}/*.pid | tr '\n' ' '`) to terminate nicely!" > ${status_output}
|
||||
sleep 1
|
||||
# Pipe stderr to dev/null to silence kill, that complains when trying to kill
|
||||
# a subprocess that has already exited.
|
||||
kill -TERM `cat ${tmp}/*.pid | tr '\n' ' '` 2> /dev/null
|
||||
wait
|
||||
echo Interrupt complete!
|
||||
echo "Interrupt complete!" > ${status_output}
|
||||
fi
|
||||
rm -f -r ${tmp}
|
||||
fi
|
||||
rm -f -r ${tmp}
|
||||
exit 1
|
||||
exit 130
|
||||
}
|
||||
|
||||
nice_exit () {
|
||||
@ -58,39 +104,44 @@ nice_exit () {
|
||||
if [ "`ls ${tmp}`" != "" ]; then
|
||||
wait
|
||||
fi
|
||||
rm -f -r ${tmp}
|
||||
fi
|
||||
rm -f -r ${tmp}
|
||||
}
|
||||
|
||||
trap 'safe_interrupt' INT QUIT
|
||||
trap 'nice_exit' EXIT
|
||||
|
||||
subrepos="corba jaxp jaxws langtools jdk hotspot nashorn"
|
||||
subrepos_extra="closed jdk/src/closed jdk/make/closed jdk/test/closed hotspot/make/closed hotspot/src/closed hotspot/test/closed deploy install sponsors pubs"
|
||||
|
||||
# Only look in specific locations for possible forests (avoids long searches)
|
||||
pull_default=""
|
||||
repos=""
|
||||
repos_extra=""
|
||||
if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
|
||||
subrepos="corba jaxp jaxws langtools jdk hotspot nashorn"
|
||||
if [ -f .hg/hgrc ] ; then
|
||||
pull_default=`hg paths default`
|
||||
if [ "${pull_default}" = "" ] ; then
|
||||
echo "ERROR: Need initial clone with 'hg paths default' defined"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ "${pull_default}" = "" ] ; then
|
||||
echo "ERROR: Need initial repository to use this script"
|
||||
if [ "${command}" = "clone" -o "${command}" = "fclone" -o "${command}" = "tclone" ] ; then
|
||||
if [ ! -f .hg/hgrc ] ; then
|
||||
echo "ERROR: Need initial repository to use this script" > ${status_output}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pull_default=`hg paths default`
|
||||
if [ "${pull_default}" = "" ] ; then
|
||||
echo "ERROR: Need initial clone with 'hg paths default' defined" > ${status_output}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for i in ${subrepos} ; do
|
||||
if [ ! -f ${i}/.hg/hgrc ] ; then
|
||||
repos="${repos} ${i}"
|
||||
fi
|
||||
done
|
||||
if [ "${pull_extra_base}" != "" ] ; then
|
||||
subrepos_extra="closed jdk/src/closed jdk/make/closed jdk/test/closed hotspot/make/closed hotspot/src/closed hotspot/test/closed deploy install sponsors pubs"
|
||||
if [ "${command_args}" != "" ] ; then
|
||||
pull_default_tail=`echo ${pull_default} | sed -e 's@^.*://[^/]*/\(.*\)@\1@'`
|
||||
pull_extra="${pull_extra_base}/${pull_default_tail}"
|
||||
if [ "x${pull_default}" = "x${pull_default_tail}" ] ; then
|
||||
echo "ERROR: Need initial clone from non-local source" > ${status_output}
|
||||
exit 1
|
||||
fi
|
||||
pull_extra="${command_args}/${pull_default_tail}"
|
||||
for i in ${subrepos_extra} ; do
|
||||
if [ ! -f ${i}/.hg/hgrc ] ; then
|
||||
repos_extra="${repos_extra} ${i}"
|
||||
@ -100,78 +151,115 @@ if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
|
||||
at_a_time=2
|
||||
# Any repos to deal with?
|
||||
if [ "${repos}" = "" -a "${repos_extra}" = "" ] ; then
|
||||
echo "No repositories to process." > ${status_output}
|
||||
exit
|
||||
fi
|
||||
else
|
||||
hgdirs=`ls -d ./.hg ./*/.hg ./*/*/.hg ./*/*/*/.hg ./*/*/*/*/.hg 2>/dev/null`
|
||||
# Derive repository names from the .hg directory locations
|
||||
for i in ${hgdirs} ; do
|
||||
repos="${repos} `echo ${i} | sed -e 's@/.hg$@@'`"
|
||||
for i in . ${subrepos} ${subrepos_extra} ; do
|
||||
if [ -d ${i}/.hg ] ; then
|
||||
repos="${repos} ${i}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Any repos to deal with?
|
||||
if [ "${repos}" = "" ] ; then
|
||||
echo "No repositories to process." > ${status_output}
|
||||
exit
|
||||
fi
|
||||
|
||||
# any of the repos locked?
|
||||
for i in ${repos} ; do
|
||||
if [ -h ${i}/.hg/store/lock -o -f ${i}/.hg/store/lock ] ; then
|
||||
locked="${i} ${locked}"
|
||||
fi
|
||||
done
|
||||
at_a_time=8
|
||||
# Any repos to deal with?
|
||||
if [ "${repos}" = "" ] ; then
|
||||
echo "No repositories to process."
|
||||
exit
|
||||
fi
|
||||
if [ "${locked}" != "" ] ; then
|
||||
echo "These repositories are locked: ${locked}"
|
||||
exit
|
||||
echo "ERROR: These repositories are locked: ${locked}" > ${status_output}
|
||||
exit 1
|
||||
fi
|
||||
at_a_time=8
|
||||
fi
|
||||
|
||||
# Echo out what repositories we do a command on.
|
||||
echo "# Repositories: ${repos} ${repos_extra}"
|
||||
echo
|
||||
echo "# Repositories: ${repos} ${repos_extra}" > ${status_output}
|
||||
|
||||
# Run the supplied command on all repos in parallel.
|
||||
n=0
|
||||
for i in ${repos} ${repos_extra} ; do
|
||||
n=`expr ${n} '+' 1`
|
||||
repopidfile=`echo ${i} | sed -e 's@./@@' -e 's@/@_@g'`
|
||||
reponame=`echo ${i} | sed -e :a -e 's/^.\{1,20\}$/ &/;ta'`
|
||||
pull_base="${pull_default}"
|
||||
for j in $repos_extra ; do
|
||||
if [ "${command}" = "serve" ] ; then
|
||||
# "serve" is run for all the repos.
|
||||
(
|
||||
(
|
||||
(
|
||||
echo "[web]"
|
||||
echo "description = $(basename $(pwd))"
|
||||
echo "allow_push = *"
|
||||
echo "push_ssl = False"
|
||||
|
||||
echo "[paths]"
|
||||
for i in ${repos} ${repos_extra} ; do
|
||||
if [ "${i}" != "." ] ; then
|
||||
echo "/$(basename $(pwd))/${i} = ${i}"
|
||||
else
|
||||
echo "/$(basename $(pwd)) = $(pwd)"
|
||||
fi
|
||||
done
|
||||
) > ${tmp}/serve.web-conf
|
||||
|
||||
echo "serving root repo $(basename $(pwd))"
|
||||
|
||||
(PYTHONUNBUFFERED=true hg${global_opts} serve -A ${status_output} -E ${status_output} --pid-file ${tmp}/serve.pid --web-conf ${tmp}/serve.web-conf; echo "$?" > ${tmp}/serve.pid.rc ) 2>&1 &
|
||||
) 2>&1 | sed -e "s@^@serve: @" > ${status_output}
|
||||
) &
|
||||
else
|
||||
# Run the supplied command on all repos in parallel.
|
||||
n=0
|
||||
for i in ${repos} ${repos_extra} ; do
|
||||
n=`expr ${n} '+' 1`
|
||||
repopidfile=`echo ${i} | sed -e 's@./@@' -e 's@/@_@g'`
|
||||
reponame=`echo ${i} | sed -e :a -e 's/^.\{1,20\}$/ &/;ta'`
|
||||
pull_base="${pull_default}"
|
||||
for j in $repos_extra ; do
|
||||
if [ "$i" = "$j" ] ; then
|
||||
pull_base="${pull_extra}"
|
||||
fi
|
||||
done
|
||||
(
|
||||
done
|
||||
(
|
||||
if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
|
||||
pull_newrepo="`echo ${pull_base}/${i} | sed -e 's@\([^:]/\)//*@\1@g'`"
|
||||
echo hg clone ${pull_newrepo} ${i}
|
||||
path="`dirname ${i}`"
|
||||
if [ "${path}" != "." ] ; then
|
||||
times=0
|
||||
while [ ! -d "${path}" ] ## nested repo, ensure containing dir exists
|
||||
do
|
||||
times=`expr ${times} '+' 1`
|
||||
if [ `expr ${times} '%' 10` -eq 0 ] ; then
|
||||
echo ${path} still not created, waiting...
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
(
|
||||
if [ "${command}" = "clone" -o "${command}" = "fclone" -o "${command}" = "tclone" ] ; then
|
||||
pull_newrepo="`echo ${pull_base}/${i} | sed -e 's@\([^:]/\)//*@\1@g'`"
|
||||
path="`dirname ${i}`"
|
||||
if [ "${path}" != "." ] ; then
|
||||
times=0
|
||||
while [ ! -d "${path}" ] ## nested repo, ensure containing dir exists
|
||||
do
|
||||
times=`expr ${times} '+' 1`
|
||||
if [ `expr ${times} '%' 10` -eq 0 ] ; then
|
||||
echo "${path} still not created, waiting..." > ${status_output}
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
fi
|
||||
echo "hg clone ${pull_newrepo} ${i}" > ${status_output}
|
||||
(PYTHONUNBUFFERED=true hg${global_opts} clone ${pull_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc ) 2>&1 &
|
||||
else
|
||||
echo "cd ${i} && hg${global_opts} ${command} ${command_args}" > ${status_output}
|
||||
cd ${i} && (PYTHONUNBUFFERED=true hg${global_opts} ${command} ${command_args}; echo "$?" > ${tmp}/${repopidfile}.pid.rc ) 2>&1 &
|
||||
fi
|
||||
(PYTHONUNBUFFERED=true hg clone ${pull_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc )&
|
||||
else
|
||||
echo "cd ${i} && hg $*"
|
||||
cd ${i} && (PYTHONUNBUFFERED=true hg "$@"; echo "$?" > ${tmp}/${repopidfile}.pid.rc )&
|
||||
fi
|
||||
echo $! > ${tmp}/${repopidfile}.pid
|
||||
) 2>&1 | sed -e "s@^@${reponame}: @") &
|
||||
|
||||
if [ `expr ${n} '%' ${at_a_time}` -eq 0 ] ; then
|
||||
sleep 2
|
||||
echo Waiting 5 secs before spawning next background command.
|
||||
sleep 3
|
||||
fi
|
||||
done
|
||||
echo $! > ${tmp}/${repopidfile}.pid
|
||||
) 2>&1 | sed -e "s@^@${reponame}: @" > ${status_output}
|
||||
) &
|
||||
|
||||
if [ `expr ${n} '%' ${at_a_time}` -eq 0 -a "${sflag}" = "false" ] ; then
|
||||
sleep 2
|
||||
echo "Waiting 5 secs before spawning next background command." > ${status_output}
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
if [ "${sflag}" = "true" ] ; then
|
||||
wait
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Wait for all hg commands to complete
|
||||
wait
|
||||
|
||||
@ -181,7 +269,8 @@ if [ -d ${tmp} ]; then
|
||||
for rc in ${tmp}/*.pid.rc ; do
|
||||
exit_code=`cat ${rc} | tr -d ' \n\r'`
|
||||
if [ "${exit_code}" != "0" ] ; then
|
||||
echo "WARNING: ${rc} exited abnormally."
|
||||
repo="`echo ${rc} | sed -e s@^${tmp}@@ -e 's@/*\([^/]*\)\.pid\.rc$@\1@' -e 's@_@/@g'`"
|
||||
echo "WARNING: ${repo} exited abnormally." > ${status_output}
|
||||
ec=1
|
||||
fi
|
||||
done
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2014, 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
|
||||
@ -29,7 +29,7 @@
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
void report_error()
|
||||
void report_error(char const * msg)
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
DWORD dw = GetLastError();
|
||||
@ -46,8 +46,8 @@ void report_error()
|
||||
NULL);
|
||||
|
||||
fprintf(stderr,
|
||||
"Could not start process! Failed with error %d: %s\n",
|
||||
dw, lpMsgBuf);
|
||||
"%s Failed with error %d: %s\n",
|
||||
msg, dw, lpMsgBuf);
|
||||
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
@ -56,7 +56,7 @@ void report_error()
|
||||
* Test if pos points to /cygdrive/_/ where _ can
|
||||
* be any character.
|
||||
*/
|
||||
int is_cygdrive_here(int pos, char *in, int len)
|
||||
int is_cygdrive_here(int pos, char const *in, int len)
|
||||
{
|
||||
// Length of /cygdrive/c/ is 12
|
||||
if (pos+12 > len) return 0;
|
||||
@ -81,16 +81,17 @@ int is_cygdrive_here(int pos, char *in, int len)
|
||||
* Works in place since drive letter is always
|
||||
* shorter than /cygdrive/
|
||||
*/
|
||||
char *replace_cygdrive_cygwin(char *in)
|
||||
char *replace_cygdrive_cygwin(char const *in)
|
||||
{
|
||||
int len = strlen(in);
|
||||
char *out = malloc(len+1);
|
||||
size_t len = strlen(in);
|
||||
char *out = (char*) malloc(len+1);
|
||||
int i,j;
|
||||
|
||||
if (len < 12) {
|
||||
strcpy(out, in);
|
||||
memmove(out, in, len + 1);
|
||||
return out;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i<len;) {
|
||||
if (is_cygdrive_here(i, in, len)) {
|
||||
out[j++] = in[i+10];
|
||||
@ -102,7 +103,7 @@ char *replace_cygdrive_cygwin(char *in)
|
||||
j++;
|
||||
}
|
||||
}
|
||||
out[j] = 0;
|
||||
out[j] = '\0';
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -110,7 +111,7 @@ void append(char **b, size_t *bl, size_t *u, char *add, size_t addlen)
|
||||
{
|
||||
while ( (addlen+*u+1) > *bl) {
|
||||
*bl *= 2;
|
||||
*b = realloc(*b, *bl);
|
||||
*b = (char*) realloc(*b, *bl);
|
||||
}
|
||||
memcpy(*b+*u, add, addlen);
|
||||
*u += addlen;
|
||||
@ -125,7 +126,7 @@ char *replace_substring(char *in, char *sub, char *rep)
|
||||
int in_len = strlen(in);
|
||||
int sub_len = strlen(sub);
|
||||
int rep_len = strlen(rep);
|
||||
char *out = malloc(in_len - sub_len + rep_len + 1);
|
||||
char *out = (char *) malloc(in_len - sub_len + rep_len + 1);
|
||||
char *p;
|
||||
|
||||
if (!(p = strstr(in, sub))) {
|
||||
@ -145,7 +146,7 @@ char *replace_substring(char *in, char *sub, char *rep)
|
||||
char* msys_path_list; // @-separated list of paths prefix to look for
|
||||
char* msys_path_list_end; // Points to last \0 in msys_path_list.
|
||||
|
||||
void setup_msys_path_list(char* argument)
|
||||
void setup_msys_path_list(char const * argument)
|
||||
{
|
||||
char* p;
|
||||
char* drive_letter_pos;
|
||||
@ -173,7 +174,7 @@ void setup_msys_path_list(char* argument)
|
||||
} while (p != NULL);
|
||||
}
|
||||
|
||||
char *replace_cygdrive_msys(char *in)
|
||||
char *replace_cygdrive_msys(char const *in)
|
||||
{
|
||||
char* str;
|
||||
char* prefix;
|
||||
@ -195,12 +196,12 @@ char *replace_cygdrive_msys(char *in)
|
||||
return str;
|
||||
}
|
||||
|
||||
char*(*replace_cygdrive)(char *in) = NULL;
|
||||
char*(*replace_cygdrive)(char const *in) = NULL;
|
||||
|
||||
char *files_to_delete[1024];
|
||||
int num_files_to_delete = 0;
|
||||
|
||||
char *fix_at_file(char *in)
|
||||
char *fix_at_file(char const *in)
|
||||
{
|
||||
char *tmpdir;
|
||||
char name[2048];
|
||||
@ -222,9 +223,13 @@ char *fix_at_file(char *in)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
tmpdir = getenv("TMP");
|
||||
tmpdir = getenv("TEMP");
|
||||
if (tmpdir == NULL) {
|
||||
#if _WIN64
|
||||
tmpdir = "c:/cygwin64/tmp";
|
||||
#else
|
||||
tmpdir = "c:/cygwin/tmp";
|
||||
#endif
|
||||
}
|
||||
_snprintf(name, sizeof(name), "%s\\atfile_XXXXXX", tmpdir);
|
||||
|
||||
@ -240,7 +245,7 @@ char *fix_at_file(char *in)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
buffer = malloc(buflen);
|
||||
buffer = (char*) malloc(buflen);
|
||||
while((blocklen = fread(block,1,sizeof(block),atin)) > 0) {
|
||||
append(&buffer, &buflen, &used, block, blocklen);
|
||||
}
|
||||
@ -257,84 +262,229 @@ char *fix_at_file(char *in)
|
||||
fclose(atout);
|
||||
free(fixed);
|
||||
free(buffer);
|
||||
files_to_delete[num_files_to_delete] = malloc(strlen(name)+1);
|
||||
files_to_delete[num_files_to_delete] = (char*) malloc(strlen(name)+1);
|
||||
strcpy(files_to_delete[num_files_to_delete], name);
|
||||
num_files_to_delete++;
|
||||
atname = malloc(strlen(name)+2);
|
||||
atname = (char*) malloc(strlen(name)+2);
|
||||
atname[0] = '@';
|
||||
strcpy(atname+1, name);
|
||||
return atname;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
// given an argument, convert it to the windows command line safe quoted version
|
||||
// using rules from:
|
||||
// http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
|
||||
// caller is responsible for freeing both input and output.
|
||||
char * quote_arg(char const * in_arg) {
|
||||
char *quoted = NULL;
|
||||
char *current = quoted;
|
||||
int pass;
|
||||
|
||||
if(strpbrk(in_arg, " \t\n\v\r\\\"") == NULL) {
|
||||
return _strdup(in_arg);
|
||||
}
|
||||
|
||||
// process the arg twice. Once to calculate the size and then to copy it.
|
||||
for(pass=1; pass<=2; pass++) {
|
||||
char const *arg = in_arg;
|
||||
|
||||
// initial "
|
||||
if(pass == 2) {
|
||||
*current = '\"';
|
||||
}
|
||||
current++;
|
||||
|
||||
// process string to be quoted until NUL
|
||||
do {
|
||||
int escapes = 0;
|
||||
|
||||
while (*arg == '\\') {
|
||||
// count escapes.
|
||||
escapes++;
|
||||
arg++;
|
||||
}
|
||||
|
||||
if (*arg == '\0') {
|
||||
// escape the escapes before final "
|
||||
escapes *= 2;
|
||||
} else if (*arg == '"') {
|
||||
// escape the escapes and the "
|
||||
escapes = escapes * 2 + 1;
|
||||
} else {
|
||||
// escapes aren't special, just echo them.
|
||||
}
|
||||
|
||||
// emit some escapes
|
||||
while (escapes > 0) {
|
||||
if (pass == 2) {
|
||||
*current = '\\';
|
||||
}
|
||||
current++;
|
||||
escapes--;
|
||||
}
|
||||
|
||||
// and the current char
|
||||
if (pass == 2) {
|
||||
*current = *arg;
|
||||
}
|
||||
current++;
|
||||
} while( *arg++ != '\0');
|
||||
|
||||
// allocate the buffer
|
||||
if (pass == 1) {
|
||||
size_t alloc = (size_t) (current - quoted + (ptrdiff_t) 2);
|
||||
current = quoted = (char*) calloc(alloc, sizeof(char));
|
||||
}
|
||||
}
|
||||
|
||||
// final " and \0
|
||||
*(current - 1) = '"';
|
||||
*current = '\0';
|
||||
|
||||
return quoted;
|
||||
}
|
||||
|
||||
int main(int argc, char const ** argv)
|
||||
{
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
unsigned short rc;
|
||||
|
||||
char *new_at_file;
|
||||
char *old_at_file;
|
||||
char *line;
|
||||
int i;
|
||||
char *current;
|
||||
int i, cmd;
|
||||
DWORD exitCode;
|
||||
|
||||
if (argc<3 || argv[1][0] != '-' || (argv[1][1] != 'c' && argv[1][1] != 'm')) {
|
||||
fprintf(stderr, "Usage: fixpath -c|m<path@path@...> /cygdrive/c/WINDOWS/notepad.exe /cygdrive/c/x/test.txt\n");
|
||||
if (argc<2 || argv[1][0] != '-' || (argv[1][1] != 'c' && argv[1][1] != 'm')) {
|
||||
fprintf(stderr, "Usage: fixpath -c|m<path@path@...> /cygdrive/c/WINDOWS/notepad.exe [/cygdrive/c/x/test.txt|@/cygdrive/c/x/atfile]\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (getenv("DEBUG_FIXPATH") != NULL) {
|
||||
fprintf(stderr, "fixpath input line >%s<\n", strstr(GetCommandLine(), argv[1]));
|
||||
char const * cmdline = GetCommandLine();
|
||||
fprintf(stderr, "fixpath input line >%s<\n", strstr( cmdline , argv[1]));
|
||||
}
|
||||
|
||||
if (argv[1][1] == 'c' && argv[1][2] == '\0') {
|
||||
if (getenv("DEBUG_FIXPATH") != NULL) {
|
||||
fprintf(stderr, "using cygwin mode\n");
|
||||
fprintf(stderr, "fixpath using cygwin mode\n");
|
||||
}
|
||||
replace_cygdrive = replace_cygdrive_cygwin;
|
||||
} else if (argv[1][1] == 'm') {
|
||||
if (getenv("DEBUG_FIXPATH") != NULL) {
|
||||
fprintf(stderr, "using msys mode, with path list: %s\n", &argv[1][2]);
|
||||
fprintf(stderr, "fixpath using msys mode, with path list: %s\n", &argv[1][2]);
|
||||
}
|
||||
setup_msys_path_list(argv[1]);
|
||||
replace_cygdrive = replace_cygdrive_msys;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown mode: %s\n", argv[1]);
|
||||
fprintf(stderr, "fixpath Unknown mode: %s\n", argv[1]);
|
||||
exit(-1);
|
||||
}
|
||||
line = replace_cygdrive(strstr(GetCommandLine(), argv[2]));
|
||||
|
||||
for (i=1; i<argc; ++i) {
|
||||
if (argv[i][0] == '@') {
|
||||
// Found at-file! Fix it!
|
||||
old_at_file = replace_cygdrive(argv[i]);
|
||||
new_at_file = fix_at_file(old_at_file);
|
||||
line = replace_substring(line, old_at_file, new_at_file);
|
||||
}
|
||||
i = 2;
|
||||
|
||||
// handle assignments
|
||||
while (i < argc) {
|
||||
char const * assignment = strchr(argv[i], '=');
|
||||
if (assignment != NULL && assignment != argv[i]) {
|
||||
size_t var_len = (size_t) (assignment - argv[i] + (ptrdiff_t) 1);
|
||||
char *var = (char *) calloc(var_len, sizeof(char));
|
||||
char *val = replace_cygdrive(assignment + 1);
|
||||
memmove(var, argv[i], var_len);
|
||||
var[var_len - 1] = '\0';
|
||||
strupr(var);
|
||||
|
||||
if (getenv("DEBUG_FIXPATH") != NULL) {
|
||||
fprintf(stderr, "fixpath setting var >%s< to >%s<\n", var, val);
|
||||
}
|
||||
|
||||
rc = SetEnvironmentVariable(var, val);
|
||||
if(!rc) {
|
||||
// Could not set var for some reason. Try to report why.
|
||||
const int msg_len = 80 + var_len + strlen(val);
|
||||
char * msg = (char *) alloca(msg_len);
|
||||
_snprintf_s(msg, msg_len, _TRUNCATE, "Could not set environment variable [%s=%s]", var, val);
|
||||
report_error(msg);
|
||||
exit(1);
|
||||
}
|
||||
free(var);
|
||||
free(val);
|
||||
} else {
|
||||
// no more assignments;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
// remember index of the command
|
||||
cmd = i;
|
||||
|
||||
// handle command and it's args.
|
||||
while (i < argc) {
|
||||
char const *replaced = replace_cygdrive(argv[i]);
|
||||
if(replaced[0] == '@') {
|
||||
// Found at-file! Fix it!
|
||||
replaced = fix_at_file(replaced);
|
||||
}
|
||||
argv[i] = quote_arg(replaced);
|
||||
i++;
|
||||
}
|
||||
|
||||
// determine the length of the line
|
||||
line = NULL;
|
||||
// args
|
||||
for(i = cmd; i < argc; i++) {
|
||||
line += (ptrdiff_t) strlen(argv[i]);
|
||||
}
|
||||
// spaces and null
|
||||
line += (ptrdiff_t) (argc - cmd + 1);
|
||||
// allocate
|
||||
line = (char*) calloc(line - (char*) NULL, sizeof(char));
|
||||
|
||||
// copy in args.
|
||||
current = line;
|
||||
for(i = cmd; i < argc; i++) {
|
||||
ptrdiff_t len = strlen(argv[i]);
|
||||
if (i != cmd) {
|
||||
*current++ = ' ';
|
||||
}
|
||||
memmove(current, argv[i], len);
|
||||
current += len;
|
||||
}
|
||||
*current = '\0';
|
||||
|
||||
if (getenv("DEBUG_FIXPATH") != NULL) {
|
||||
fprintf(stderr, "fixpath converted line >%s<\n", line);
|
||||
}
|
||||
|
||||
if(cmd == argc) {
|
||||
if (getenv("DEBUG_FIXPATH") != NULL) {
|
||||
fprintf(stderr, "fixpath no command provided!\n");
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
ZeroMemory(&si,sizeof(si));
|
||||
si.cb=sizeof(si);
|
||||
ZeroMemory(&pi,sizeof(pi));
|
||||
|
||||
fflush(stderr);
|
||||
fflush(stdout);
|
||||
|
||||
rc = CreateProcess(NULL,
|
||||
line,
|
||||
0,
|
||||
0,
|
||||
TRUE,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&si,
|
||||
&pi);
|
||||
if(!rc) {
|
||||
// Could not start process for some reason. Try to report why:
|
||||
report_error();
|
||||
exit(rc);
|
||||
report_error("Could not start process!");
|
||||
exit(126);
|
||||
}
|
||||
|
||||
WaitForSingleObject(pi.hProcess,INFINITE);
|
||||
@ -342,15 +492,21 @@ int main(int argc, char **argv)
|
||||
|
||||
if (getenv("DEBUG_FIXPATH") != NULL) {
|
||||
for (i=0; i<num_files_to_delete; ++i) {
|
||||
fprintf(stderr, "Not deleting temporary fixpath file %s\n",
|
||||
fprintf(stderr, "fixpath Not deleting temporary file %s\n",
|
||||
files_to_delete[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
for (i=0; i<num_files_to_delete; ++i) {
|
||||
remove(files_to_delete[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (exitCode != 0) {
|
||||
if (getenv("DEBUG_FIXPATH") != NULL) {
|
||||
fprintf(stderr, "fixpath exit code %d\n",
|
||||
exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
exit(exitCode);
|
||||
}
|
||||
|
||||
@ -249,3 +249,4 @@ d338b892a13db19b093f85cf5f949a4504e4d31f jdk9-b03
|
||||
1ed19de263e1e0772da0269118cdd9deeb9fff04 jdk9-b04
|
||||
167c39eb44731a5d66770d0f00e231164653a2ff jdk9-b05
|
||||
a4bf701ac316946c2e5e83138ad8e687da6a4b30 jdk9-b06
|
||||
6c8563600a71394c949405189ddd66267a88d8cd jdk9-b07
|
||||
|
||||
@ -253,6 +253,13 @@ public class SocketOrChannelAcceptorImpl
|
||||
// registered with the selector. Otherwise if the bytes
|
||||
// are read on the connection it will attempt a time stamp
|
||||
// but the cache will be null, resulting in NPE.
|
||||
|
||||
// A connection needs to be timestamped before putting to the cache.
|
||||
// Otherwise the newly created connection (with 0 timestamp) could be
|
||||
// incorrectly reclaimed by concurrent reclaim() call OR if there
|
||||
// will be no events on this connection then it could be reclaimed
|
||||
// by upcoming reclaim() call.
|
||||
getConnectionCache().stampTime(connection);
|
||||
getConnectionCache().put(this, connection);
|
||||
|
||||
if (connection.shouldRegisterServerReadEvent()) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
package com.sun.corba.se.spi.orb;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map ;
|
||||
import java.util.HashMap ;
|
||||
import java.util.Properties ;
|
||||
@ -97,8 +99,7 @@ import com.sun.corba.se.impl.logging.OMGSystemException ;
|
||||
|
||||
import com.sun.corba.se.impl.presentation.rmi.PresentationManagerImpl ;
|
||||
|
||||
import sun.awt.AppContext;
|
||||
import sun.corba.SharedSecrets;
|
||||
import sun.misc.JavaAWTAccess;
|
||||
|
||||
public abstract class ORB extends com.sun.corba.se.org.omg.CORBA.ORB
|
||||
implements Broker, TypeCodeFactory
|
||||
@ -170,6 +171,13 @@ public abstract class ORB extends com.sun.corba.se.org.omg.CORBA.ORB
|
||||
// representing LogDomain and ExceptionGroup.
|
||||
private Map wrapperMap ;
|
||||
|
||||
static class Holder {
|
||||
static final PresentationManager defaultPresentationManager =
|
||||
setupPresentationManager();
|
||||
}
|
||||
|
||||
private static final Map<Object, PresentationManager> pmContexts = new HashMap<>();
|
||||
|
||||
private static Map staticWrapperMap = new ConcurrentHashMap();
|
||||
|
||||
protected MonitoringManager monitoringManager;
|
||||
@ -201,8 +209,9 @@ public abstract class ORB extends com.sun.corba.se.org.omg.CORBA.ORB
|
||||
|
||||
try {
|
||||
// First try the configured class name, if any
|
||||
Class<?> cls = SharedSecrets.getJavaCorbaAccess().loadClass( className ) ;
|
||||
sff = (PresentationManager.StubFactoryFactory)cls.newInstance() ;
|
||||
Class<?> cls =
|
||||
sun.corba.SharedSecrets.getJavaCorbaAccess().loadClass(className);
|
||||
sff = (PresentationManager.StubFactoryFactory)cls.newInstance();
|
||||
} catch (Exception exc) {
|
||||
// Use the default. Log the error as a warning.
|
||||
staticWrapper.errorInSettingDynamicStubFactoryFactory(
|
||||
@ -235,13 +244,34 @@ public abstract class ORB extends com.sun.corba.se.org.omg.CORBA.ORB
|
||||
*/
|
||||
public static PresentationManager getPresentationManager()
|
||||
{
|
||||
AppContext ac = AppContext.getAppContext();
|
||||
PresentationManager pm = (PresentationManager) ac.get(PresentationManager.class);
|
||||
if (pm == null) {
|
||||
pm = setupPresentationManager();
|
||||
ac.put(PresentationManager.class, pm);
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
JavaAWTAccess javaAwtAccess = sun.misc.SharedSecrets.getJavaAWTAccess();
|
||||
if (sm != null && javaAwtAccess != null) {
|
||||
Object appletContext;
|
||||
try {
|
||||
Class<?> clazz = JavaAWTAccess.class;
|
||||
Method method = clazz.getMethod("getAppletContext");
|
||||
appletContext = method.invoke(javaAwtAccess);
|
||||
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
||||
InternalError err = new InternalError();
|
||||
err.initCause(e);
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (appletContext != null) {
|
||||
synchronized (pmContexts) {
|
||||
PresentationManager pm = pmContexts.get(appletContext);
|
||||
if (pm == null) {
|
||||
pm = setupPresentationManager();
|
||||
pmContexts.put(appletContext, pm);
|
||||
}
|
||||
return pm;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pm;
|
||||
|
||||
// No security manager or AppletAppContext
|
||||
return Holder.defaultPresentationManager;
|
||||
}
|
||||
|
||||
/** Get the appropriate StubFactoryFactory. This
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -44,11 +44,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -38,11 +38,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -48,11 +48,11 @@ package org.omg.CORBA;
|
||||
* OMG specifications :
|
||||
* <ul>
|
||||
* <li> ORB core as defined by CORBA 2.3.1
|
||||
* (<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* (<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)
|
||||
* </li>
|
||||
*
|
||||
* <li> IDL/Java Language Mapping as defined in
|
||||
* <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
@ -18,26 +18,26 @@ href="http://www.omg.org/">www.omg.org</a> to search for the correct specificati
|
||||
<ul>
|
||||
<li>
|
||||
CORBA 2.3.1 (<a
|
||||
href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)</li>
|
||||
href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">formal/99-10-07</a>)</li>
|
||||
|
||||
<li>
|
||||
IDL to Java language mapping (<a
|
||||
href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>)</li>
|
||||
href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">ptc/00-01-08</a>)</li>
|
||||
|
||||
<li>Revised IDL to Java language mapping (<a
|
||||
href="http://cgi.omg.org/cgi-bin/doc?ptc/00-11-03">ptc/00-11-03</a>)</li>
|
||||
href="http://www.omg.org/cgi-bin/doc?ptc/00-11-03">ptc/00-11-03</a>)</li>
|
||||
|
||||
<li>
|
||||
Java to IDL language mapping (<a
|
||||
href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-06">ptc/00-01-06</a>)</li>
|
||||
href="http://www.omg.org/cgi-bin/doc?ptc/00-01-06">ptc/00-01-06</a>)</li>
|
||||
|
||||
<li>
|
||||
Interoperable Naming Service (<a
|
||||
href="http://cgi.omg.org/cgi-bin/doc?ptc/00-08-07">ptc/00-08-07</a>)</li>
|
||||
href="http://www.omg.org/cgi-bin/doc?ptc/00-08-07">ptc/00-08-07</a>)</li>
|
||||
|
||||
<li>
|
||||
Portable Interceptors (<a
|
||||
href="http://cgi.omg.org/cgi-bin/doc?ptc/2001-03-04">ptc/2001-03-04</a>)</li>
|
||||
href="http://www.omg.org/cgi-bin/doc?ptc/2001-03-04">ptc/2001-03-04</a>)</li>
|
||||
</ul>
|
||||
These are the only specifications referenced by this document.
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
<H1>IDL-to-Java Generated Files</H1>
|
||||
|
||||
<P>The files that are generated by the IDL-to-Java compiler, in accordance with the <em><a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">IDL-to-Java Language Mapping Specification</a></em>, which is implemented in Java<sup><font size="-2">TM</font></sup> SE 6 according the <a href="compliance.html">compliance</a> document.
|
||||
<P>The files that are generated by the IDL-to-Java compiler, in accordance with the <em><a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">IDL-to-Java Language Mapping Specification</a></em>, which is implemented in Java<sup><font size="-2">TM</font></sup> SE 6 according the <a href="compliance.html">compliance</a> document.
|
||||
|
||||
|
||||
<P>In general IDL names and identifiers are mapped to Java names and identifiers with no change. Because of the nature of the Java language, a single IDL construct may be mapped to several (differently named) Java constructs. The additional names are constructed by appending a descriptive suffix. For example, the IDL interface <tt>foo</tt> is mapped to the Java interfaces <tt>foo</tt> and <tt>fooOperations</tt>, and additional Java classes <tt>fooHelper</tt>, <tt>fooHolder</tt>, <tt>fooPOA</tt>, and optionally <tt>fooPOATie</tt>.
|
||||
|
||||
@ -344,7 +344,7 @@ public final class AccountHolder implements
|
||||
</PRE>
|
||||
|
||||
<P>For more information on Holder classes, see Chapter 1.4, <em>Mapping for
|
||||
Basic Types</em> in the <a href="http://cgi.omg.org/cgi-bin/doc?ptc/00-01-08">
|
||||
Basic Types</em> in the <a href="http://www.omg.org/cgi-bin/doc?ptc/00-01-08">
|
||||
<em>OMG IDL to Java Language Mapping</em></a>. The Holder classes defined
|
||||
in the package <TT>org.omg.CORBA</TT> are:
|
||||
<PRE>
|
||||
|
||||
@ -331,7 +331,7 @@ Context.
|
||||
|
||||
<ul>
|
||||
<li>Interoperable Naming Service (<a
|
||||
href="http://cgi.omg.org/cgi-bin/doc?ptc/00-08-07">ptc/00-08-07</a>)
|
||||
href="http://www.omg.org/cgi-bin/doc?ptc/00-08-07">ptc/00-08-07</a>)
|
||||
</ul>
|
||||
|
||||
<h2>Related Documentation</h2>
|
||||
|
||||
@ -33,8 +33,8 @@
|
||||
<body bgcolor="white">
|
||||
<P>This package contains the <tt>Dynamic</tt> module specified in the OMG Portable
|
||||
Interceptor specification,
|
||||
<a href="http://cgi.omg.org/cgi-bin/doc?ptc/2000-08-06">
|
||||
http://cgi.omg.org/cgi-bin/doc?ptc/2000-08-06</a>, section 21.9. Please
|
||||
<a href="http://www.omg.org/cgi-bin/doc?ptc/2000-08-06">
|
||||
ptc/2000-08-06</a>, section 21.9. Please
|
||||
refer to that OMG specification for further details.
|
||||
|
||||
|
||||
|
||||
@ -38,8 +38,8 @@ interface of the
|
||||
<tt>DynamicAny</tt> module
|
||||
specified in the OMG <em>The Common Object Request Broker: Architecture and
|
||||
Specification</em>,
|
||||
<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">
|
||||
http://cgi.omg.org/cgi-bin/doc?formal/99-10-07</a>, section 9.2.2. Please
|
||||
<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">
|
||||
formal/99-10-07</a>, section 9.2.2. Please
|
||||
refer to that OMG specification for further details.
|
||||
|
||||
<H3>Package Specification</H3>
|
||||
|
||||
@ -34,8 +34,8 @@
|
||||
interface of the <tt>DynamicAny</tt> module
|
||||
specified in the OMG <em>The Common Object Request Broker: Architecture and
|
||||
Specification</em>,
|
||||
<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">
|
||||
http://cgi.omg.org/cgi-bin/doc?formal/99-10-07</a>, section 9.2. Please
|
||||
<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">
|
||||
formal/99-10-07</a>, section 9.2. Please
|
||||
refer to that OMG specification for further details.
|
||||
|
||||
|
||||
|
||||
@ -33,8 +33,8 @@ questions.
|
||||
<P>This package contains the <TT>IOP</tt> module specified in the OMG document
|
||||
<em>The Common
|
||||
Object Request Broker: Architecture and Specification</em>,
|
||||
<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">
|
||||
http://cgi.omg.org/cgi-bin/doc?formal/99-10-07</a>, section 13.6. Please
|
||||
<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">
|
||||
formal/99-10-07</a>, section 13.6. Please
|
||||
refer to that OMG specification for further details.
|
||||
|
||||
<P>Please note that we do not provide all parts of the <tt>IOP</tt> module from
|
||||
|
||||
@ -32,8 +32,8 @@ questions.
|
||||
<body bgcolor="white">
|
||||
<P>This package contains the <tt>Messaging</tt> module specified in the OMG CORBA
|
||||
Messaging specification,
|
||||
<a href="http://cgi.omg.org/cgi-bin/doc?formal/99-10-07">
|
||||
http://cgi.omg.org/cgi-bin/doc?formal/99-10-07</a>. Please refer to that OMG
|
||||
<a href="http://www.omg.org/cgi-bin/doc?formal/99-10-07">
|
||||
formal/99-10-07</a>. Please refer to that OMG
|
||||
specification for further details.
|
||||
|
||||
<P>Please note that we do not provide all parts of the <tt>Messaging</tt> module from
|
||||
|
||||
@ -33,8 +33,8 @@ questions.
|
||||
<P>This package contains the exceptions and typedefs from the <tt>ORBInitInfo</tt>
|
||||
local interface of the <tt>PortableInterceptor</tt> module specified in the OMG
|
||||
Portable Interceptor specification,
|
||||
<a href="http://cgi.omg.org/cgi-bin/doc?ptc/2000-08-06">
|
||||
http://cgi.omg.org/cgi-bin/doc?ptc/2000-08-06</a>, section 21.7.2. Please
|
||||
<a href="http://www.omg.org/cgi-bin/doc?ptc/2000-08-06">
|
||||
ptc/2000-08-06</a>, section 21.7.2. Please
|
||||
refer to that OMG specification for further details.
|
||||
|
||||
|
||||
|
||||
@ -409,3 +409,4 @@ b2fee789d23f3cdabb3db4e51af43038e5692d3a jdk9-b03
|
||||
3812c088b9456ee22c933e88aee1ece71f4e783a jdk9-b04
|
||||
bdc5311e1db7598589b77015119b821bf8c828bd jdk9-b05
|
||||
52377a30a3f87b62d6135706997b8c7a47366e37 jdk9-b06
|
||||
52f7edf2589d9f9d35db3008bc5377f279de9c18 jdk9-b07
|
||||
|
||||
@ -958,7 +958,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
|
||||
// reset handle block
|
||||
__ ld_ptr(G2_thread, in_bytes(JavaThread::active_handles_offset()), G3_scratch);
|
||||
__ st_ptr(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes());
|
||||
__ st(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes());
|
||||
|
||||
|
||||
// handle exceptions (exception handling will handle unlocking!)
|
||||
|
||||
@ -2687,7 +2687,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
if (!is_critical_native) {
|
||||
// reset handle block
|
||||
__ ld_ptr(G2_thread, in_bytes(JavaThread::active_handles_offset()), L5);
|
||||
__ st_ptr(G0, L5, JNIHandleBlock::top_offset_in_bytes());
|
||||
__ st(G0, L5, JNIHandleBlock::top_offset_in_bytes());
|
||||
|
||||
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), G3_scratch);
|
||||
check_forward_pending_exception(masm, G3_scratch);
|
||||
|
||||
@ -1147,7 +1147,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
|
||||
// reset handle block
|
||||
__ ld_ptr(G2_thread, JavaThread::active_handles_offset(), G3_scratch);
|
||||
__ st_ptr(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes());
|
||||
__ st(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes());
|
||||
|
||||
// If we have an oop result store it where it will be safe for any further gc
|
||||
// until we return now that we've released the handle it might be protected by
|
||||
|
||||
@ -1358,7 +1358,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
|
||||
// reset handle block
|
||||
__ movptr(t, Address(thread, JavaThread::active_handles_offset()));
|
||||
__ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
|
||||
__ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
|
||||
|
||||
// If result was an oop then unbox and save it in the frame
|
||||
{ Label L;
|
||||
|
||||
@ -162,7 +162,7 @@ define_pd_global(uintx, TypeProfileLevel, 111);
|
||||
"Number of milliseconds to wait before start calculating aborts " \
|
||||
"for RTM locking") \
|
||||
\
|
||||
experimental(bool, UseRTMXendForLockBusy, false, \
|
||||
experimental(bool, UseRTMXendForLockBusy, true, \
|
||||
"Use RTM Xend instead of Xabort when lock busy") \
|
||||
\
|
||||
/* assembler */ \
|
||||
|
||||
@ -1488,11 +1488,10 @@ void MacroAssembler::rtm_stack_locking(Register objReg, Register tmpReg, Registe
|
||||
movl(retry_on_abort_count_Reg, RTMRetryCount); // Retry on abort
|
||||
bind(L_rtm_retry);
|
||||
}
|
||||
if (!UseRTMXendForLockBusy) {
|
||||
movptr(tmpReg, Address(objReg, 0));
|
||||
testptr(tmpReg, markOopDesc::monitor_value); // inflated vs stack-locked|neutral|biased
|
||||
jcc(Assembler::notZero, IsInflated);
|
||||
}
|
||||
movptr(tmpReg, Address(objReg, 0));
|
||||
testptr(tmpReg, markOopDesc::monitor_value); // inflated vs stack-locked|neutral|biased
|
||||
jcc(Assembler::notZero, IsInflated);
|
||||
|
||||
if (PrintPreciseRTMLockingStatistics || profile_rtm) {
|
||||
Label L_noincrement;
|
||||
if (RTMTotalCountIncrRate > 1) {
|
||||
@ -1512,10 +1511,7 @@ void MacroAssembler::rtm_stack_locking(Register objReg, Register tmpReg, Registe
|
||||
Register abort_status_Reg = tmpReg; // status of abort is stored in RAX
|
||||
if (UseRTMXendForLockBusy) {
|
||||
xend();
|
||||
movptr(tmpReg, Address(objReg, 0));
|
||||
testptr(tmpReg, markOopDesc::monitor_value); // inflated vs stack-locked|neutral|biased
|
||||
jcc(Assembler::notZero, IsInflated);
|
||||
movptr(abort_status_Reg, 0x1); // Set the abort status to 1 (as xabort does)
|
||||
movptr(abort_status_Reg, 0x2); // Set the abort status to 2 (so we can retry)
|
||||
jmp(L_decrement_retry);
|
||||
}
|
||||
else {
|
||||
|
||||
@ -2266,7 +2266,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
if (!is_critical_native) {
|
||||
// reset handle block
|
||||
__ movptr(rcx, Address(thread, JavaThread::active_handles_offset()));
|
||||
__ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD);
|
||||
__ movl(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD);
|
||||
|
||||
// Any exception pending?
|
||||
__ cmpptr(Address(thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD);
|
||||
|
||||
@ -2509,7 +2509,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
if (!is_critical_native) {
|
||||
// reset handle block
|
||||
__ movptr(rcx, Address(r15_thread, JavaThread::active_handles_offset()));
|
||||
__ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
|
||||
__ movl(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
|
||||
}
|
||||
|
||||
// pop our frame
|
||||
|
||||
@ -1287,7 +1287,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
|
||||
// reset handle block
|
||||
__ movptr(t, Address(thread, JavaThread::active_handles_offset()));
|
||||
__ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD);
|
||||
__ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), NULL_WORD);
|
||||
|
||||
// If result was an oop then unbox and save it in the frame
|
||||
{ Label L;
|
||||
|
||||
@ -1259,7 +1259,7 @@ address InterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
|
||||
// reset handle block
|
||||
__ movptr(t, Address(r15_thread, JavaThread::active_handles_offset()));
|
||||
__ movptr(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
|
||||
__ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD);
|
||||
|
||||
// If result is an oop unbox and store it in frame where gc will see it
|
||||
// and result handler will pick it up
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2012, 2014 SAP AG. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -2811,18 +2811,13 @@ void os::yield() {
|
||||
|
||||
os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN; }
|
||||
|
||||
void os::yield_all(int attempts) {
|
||||
void os::yield_all() {
|
||||
// Yields to all threads, including threads with lower priorities
|
||||
// Threads on Linux are all with same priority. The Solaris style
|
||||
// os::yield_all() with nanosleep(1ms) is not necessary.
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
// Called from the tight loops to possibly influence time-sharing heuristics
|
||||
void os::loop_breaker(int attempts) {
|
||||
os::yield_all(attempts);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// thread priority support
|
||||
|
||||
@ -3079,7 +3074,7 @@ static bool do_suspend(OSThread* osthread) {
|
||||
|
||||
for (int n = 0; !osthread->sr.is_suspended(); n++) {
|
||||
for (int i = 0; i < RANDOMLY_LARGE_INTEGER2 && !osthread->sr.is_suspended(); i++) {
|
||||
os::yield_all(i);
|
||||
os::yield_all();
|
||||
}
|
||||
|
||||
// timeout, try to cancel the request
|
||||
@ -3113,7 +3108,7 @@ static void do_resume(OSThread* osthread) {
|
||||
if (sr_notify(osthread) == 0) {
|
||||
for (int n = 0; n < RANDOMLY_LARGE_INTEGER && !osthread->sr.is_running(); n++) {
|
||||
for (int i = 0; i < 100 && !osthread->sr.is_running(); i++) {
|
||||
os::yield_all(i);
|
||||
os::yield_all();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -917,9 +917,20 @@ void os::free_thread(OSThread* osthread) {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// thread local storage
|
||||
|
||||
// Restore the thread pointer if the destructor is called. This is in case
|
||||
// someone from JNI code sets up a destructor with pthread_key_create to run
|
||||
// detachCurrentThread on thread death. Unless we restore the thread pointer we
|
||||
// will hang or crash. When detachCurrentThread is called the key will be set
|
||||
// to null and we will not be called again. If detachCurrentThread is never
|
||||
// called we could loop forever depending on the pthread implementation.
|
||||
static void restore_thread_pointer(void* p) {
|
||||
Thread* thread = (Thread*) p;
|
||||
os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
|
||||
}
|
||||
|
||||
int os::allocate_thread_local_storage() {
|
||||
pthread_key_t key;
|
||||
int rslt = pthread_key_create(&key, NULL);
|
||||
int rslt = pthread_key_create(&key, restore_thread_pointer);
|
||||
assert(rslt == 0, "cannot allocate thread local storage");
|
||||
return (int)key;
|
||||
}
|
||||
@ -2551,18 +2562,13 @@ void os::yield() {
|
||||
|
||||
os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;}
|
||||
|
||||
void os::yield_all(int attempts) {
|
||||
void os::yield_all() {
|
||||
// Yields to all threads, including threads with lower priorities
|
||||
// Threads on Bsd are all with same priority. The Solaris style
|
||||
// os::yield_all() with nanosleep(1ms) is not necessary.
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
// Called from the tight loops to possibly influence time-sharing heuristics
|
||||
void os::loop_breaker(int attempts) {
|
||||
os::yield_all(attempts);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// thread priority support
|
||||
|
||||
|
||||
@ -1032,9 +1032,20 @@ void os::free_thread(OSThread* osthread) {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// thread local storage
|
||||
|
||||
// Restore the thread pointer if the destructor is called. This is in case
|
||||
// someone from JNI code sets up a destructor with pthread_key_create to run
|
||||
// detachCurrentThread on thread death. Unless we restore the thread pointer we
|
||||
// will hang or crash. When detachCurrentThread is called the key will be set
|
||||
// to null and we will not be called again. If detachCurrentThread is never
|
||||
// called we could loop forever depending on the pthread implementation.
|
||||
static void restore_thread_pointer(void* p) {
|
||||
Thread* thread = (Thread*) p;
|
||||
os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
|
||||
}
|
||||
|
||||
int os::allocate_thread_local_storage() {
|
||||
pthread_key_t key;
|
||||
int rslt = pthread_key_create(&key, NULL);
|
||||
int rslt = pthread_key_create(&key, restore_thread_pointer);
|
||||
assert(rslt == 0, "cannot allocate thread local storage");
|
||||
return (int)key;
|
||||
}
|
||||
@ -3781,18 +3792,13 @@ void os::yield() {
|
||||
|
||||
os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;}
|
||||
|
||||
void os::yield_all(int attempts) {
|
||||
void os::yield_all() {
|
||||
// Yields to all threads, including threads with lower priorities
|
||||
// Threads on Linux are all with same priority. The Solaris style
|
||||
// os::yield_all() with nanosleep(1ms) is not necessary.
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
// Called from the tight loops to possibly influence time-sharing heuristics
|
||||
void os::loop_breaker(int attempts) {
|
||||
os::yield_all(attempts);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// thread priority support
|
||||
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#include "services/dtraceAttacher.hpp"
|
||||
|
||||
#include <door.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
@ -668,11 +669,13 @@ static jint enable_dprobes(AttachOperation* op, outputStream* out) {
|
||||
out->print_cr("No probe specified");
|
||||
return JNI_ERR;
|
||||
} else {
|
||||
int probe_typess = atoi(probe);
|
||||
if (errno) {
|
||||
char *end;
|
||||
long val = strtol(probe, &end, 10);
|
||||
if (end == probe || val < 0 || val > INT_MAX) {
|
||||
out->print_cr("invalid probe type");
|
||||
return JNI_ERR;
|
||||
} else {
|
||||
int probe_typess = (int) val;
|
||||
DTrace::enable_dprobes(probe_typess);
|
||||
return JNI_OK;
|
||||
}
|
||||
@ -703,8 +706,9 @@ jint AttachListener::pd_set_flag(AttachOperation* op, outputStream* out) {
|
||||
bool flag = true;
|
||||
const char* arg1;
|
||||
if ((arg1 = op->arg(1)) != NULL) {
|
||||
flag = (atoi(arg1) != 0);
|
||||
if (errno) {
|
||||
char *end;
|
||||
flag = (strtol(arg1, &end, 10) != 0);
|
||||
if (arg1 == end) {
|
||||
out->print_cr("flag value has to be an integer");
|
||||
return JNI_ERR;
|
||||
}
|
||||
|
||||
@ -49,16 +49,6 @@ void OSThread::pd_destroy() {
|
||||
|
||||
// copied from synchronizer.cpp
|
||||
|
||||
void OSThread::handle_spinlock_contention(int tries) {
|
||||
if (NoYieldsInMicrolock) return;
|
||||
|
||||
if (tries > 10) {
|
||||
os::yield_all(tries); // Yield to threads of any priority
|
||||
} else if (tries > 5) {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -82,8 +82,6 @@
|
||||
void set_ucontext(ucontext_t* ptr) { _ucontext = ptr; }
|
||||
static void SR_handler(Thread* thread, ucontext_t* uc);
|
||||
|
||||
static void handle_spinlock_contention(int tries); // Used for thread local eden locking
|
||||
|
||||
// ***************************************************************
|
||||
// Platform dependent initialization and cleanup
|
||||
// ***************************************************************
|
||||
|
||||
@ -969,9 +969,6 @@ bool os::create_main_thread(JavaThread* thread) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// _T2_libthread is true if we believe we are running with the newer
|
||||
// SunSoft lwp/libthread.so (2.8 patch, 2.9 default)
|
||||
bool os::Solaris::_T2_libthread = false;
|
||||
|
||||
bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
|
||||
// Allocate the OSThread object
|
||||
@ -1056,71 +1053,10 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
|
||||
thread->set_osthread(osthread);
|
||||
|
||||
// Create the Solaris thread
|
||||
// explicit THR_BOUND for T2_libthread case in case
|
||||
// that assumption is not accurate, but our alternate signal stack
|
||||
// handling is based on it which must have bound threads
|
||||
thread_t tid = 0;
|
||||
long flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED
|
||||
| ((UseBoundThreads || os::Solaris::T2_libthread() ||
|
||||
(thr_type == vm_thread) ||
|
||||
(thr_type == cgc_thread) ||
|
||||
(thr_type == pgc_thread) ||
|
||||
(thr_type == compiler_thread && BackgroundCompilation)) ?
|
||||
THR_BOUND : 0);
|
||||
long flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED;
|
||||
int status;
|
||||
|
||||
// 4376845 -- libthread/kernel don't provide enough LWPs to utilize all CPUs.
|
||||
//
|
||||
// On multiprocessors systems, libthread sometimes under-provisions our
|
||||
// process with LWPs. On a 30-way systems, for instance, we could have
|
||||
// 50 user-level threads in ready state and only 2 or 3 LWPs assigned
|
||||
// to our process. This can result in under utilization of PEs.
|
||||
// I suspect the problem is related to libthread's LWP
|
||||
// pool management and to the kernel's SIGBLOCKING "last LWP parked"
|
||||
// upcall policy.
|
||||
//
|
||||
// The following code is palliative -- it attempts to ensure that our
|
||||
// process has sufficient LWPs to take advantage of multiple PEs.
|
||||
// Proper long-term cures include using user-level threads bound to LWPs
|
||||
// (THR_BOUND) or using LWP-based synchronization. Note that there is a
|
||||
// slight timing window with respect to sampling _os_thread_count, but
|
||||
// the race is benign. Also, we should periodically recompute
|
||||
// _processors_online as the min of SC_NPROCESSORS_ONLN and the
|
||||
// the number of PEs in our partition. You might be tempted to use
|
||||
// THR_NEW_LWP here, but I'd recommend against it as that could
|
||||
// result in undesirable growth of the libthread's LWP pool.
|
||||
// The fix below isn't sufficient; for instance, it doesn't take into count
|
||||
// LWPs parked on IO. It does, however, help certain CPU-bound benchmarks.
|
||||
//
|
||||
// Some pathologies this scheme doesn't handle:
|
||||
// * Threads can block, releasing the LWPs. The LWPs can age out.
|
||||
// When a large number of threads become ready again there aren't
|
||||
// enough LWPs available to service them. This can occur when the
|
||||
// number of ready threads oscillates.
|
||||
// * LWPs/Threads park on IO, thus taking the LWP out of circulation.
|
||||
//
|
||||
// Finally, we should call thr_setconcurrency() periodically to refresh
|
||||
// the LWP pool and thwart the LWP age-out mechanism.
|
||||
// The "+3" term provides a little slop -- we want to slightly overprovision.
|
||||
|
||||
if (AdjustConcurrency && os::Solaris::_os_thread_count < (_processors_online+3)) {
|
||||
if (!(flags & THR_BOUND)) {
|
||||
thr_setconcurrency (os::Solaris::_os_thread_count); // avoid starvation
|
||||
}
|
||||
}
|
||||
// Although this doesn't hurt, we should warn of undefined behavior
|
||||
// when using unbound T1 threads with schedctl(). This should never
|
||||
// happen, as the compiler and VM threads are always created bound
|
||||
DEBUG_ONLY(
|
||||
if ((VMThreadHintNoPreempt || CompilerThreadHintNoPreempt) &&
|
||||
(!os::Solaris::T2_libthread() && (!(flags & THR_BOUND))) &&
|
||||
((thr_type == vm_thread) || (thr_type == cgc_thread) ||
|
||||
(thr_type == pgc_thread) || (thr_type == compiler_thread && BackgroundCompilation))) {
|
||||
warning("schedctl behavior undefined when Compiler/VM/GC Threads are Unbound");
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// Mark that we don't have an lwp or thread id yet.
|
||||
// In case we attempt to set the priority before the thread starts.
|
||||
osthread->set_lwp_id(-1);
|
||||
@ -1145,13 +1081,6 @@ bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
|
||||
// Remember that we created this thread so we can set priority on it
|
||||
osthread->set_vm_created();
|
||||
|
||||
// Set the default thread priority. If using bound threads, setting
|
||||
// lwp priority will be delayed until thread start.
|
||||
set_native_priority(thread,
|
||||
DefaultThreadPriority == -1 ?
|
||||
java_to_os_priority[NormPriority] :
|
||||
DefaultThreadPriority);
|
||||
|
||||
// Initial thread state is INITIALIZED, not SUSPENDED
|
||||
osthread->set_state(INITIALIZED);
|
||||
|
||||
@ -1333,39 +1262,8 @@ void os::initialize_thread(Thread* thr) {
|
||||
jt->set_stack_size(stack_size);
|
||||
}
|
||||
|
||||
// 5/22/01: Right now alternate signal stacks do not handle
|
||||
// throwing stack overflow exceptions, see bug 4463178
|
||||
// Until a fix is found for this, T2 will NOT imply alternate signal
|
||||
// stacks.
|
||||
// If using T2 libthread threads, install an alternate signal stack.
|
||||
// Because alternate stacks associate with LWPs on Solaris,
|
||||
// see sigaltstack(2), if using UNBOUND threads, or if UseBoundThreads
|
||||
// we prefer to explicitly stack bang.
|
||||
// If not using T2 libthread, but using UseBoundThreads any threads
|
||||
// (primordial thread, jni_attachCurrentThread) we do not create,
|
||||
// probably are not bound, therefore they can not have an alternate
|
||||
// signal stack. Since our stack banging code is generated and
|
||||
// is shared across threads, all threads must be bound to allow
|
||||
// using alternate signal stacks. The alternative is to interpose
|
||||
// on _lwp_create to associate an alt sig stack with each LWP,
|
||||
// and this could be a problem when the JVM is embedded.
|
||||
// We would prefer to use alternate signal stacks with T2
|
||||
// Since there is currently no accurate way to detect T2
|
||||
// we do not. Assuming T2 when running T1 causes sig 11s or assertions
|
||||
// on installing alternate signal stacks
|
||||
|
||||
|
||||
// 05/09/03: removed alternate signal stack support for Solaris
|
||||
// The alternate signal stack mechanism is no longer needed to
|
||||
// handle stack overflow. This is now handled by allocating
|
||||
// guard pages (red zone) and stackbanging.
|
||||
// Initially the alternate signal stack mechanism was removed because
|
||||
// it did not work with T1 llibthread. Alternate
|
||||
// signal stacks MUST have all threads bound to lwps. Applications
|
||||
// can create their own threads and attach them without their being
|
||||
// bound under T1. This is frequently the case for the primordial thread.
|
||||
// If we were ever to reenable this mechanism we would need to
|
||||
// use the dynamic check for T2 libthread.
|
||||
// With the T2 libthread (T1 is no longer supported) threads are always bound
|
||||
// and we use stackbanging in all cases.
|
||||
|
||||
os::Solaris::init_thread_fpu_state();
|
||||
std::set_terminate(_handle_uncaught_cxx_exception);
|
||||
@ -2092,12 +1990,7 @@ void os::Solaris::print_distro_info(outputStream* st) {
|
||||
}
|
||||
|
||||
void os::Solaris::print_libversion_info(outputStream* st) {
|
||||
if (os::Solaris::T2_libthread()) {
|
||||
st->print(" (T2 libthread)");
|
||||
}
|
||||
else {
|
||||
st->print(" (T1 libthread)");
|
||||
}
|
||||
st->print(" (T2 libthread)");
|
||||
st->cr();
|
||||
}
|
||||
|
||||
@ -3323,48 +3216,20 @@ void os::yield() {
|
||||
|
||||
os::YieldResult os::NakedYield() { thr_yield(); return os::YIELD_UNKNOWN; }
|
||||
|
||||
|
||||
// On Solaris we found that yield_all doesn't always yield to all other threads.
|
||||
// There have been cases where there is a thread ready to execute but it doesn't
|
||||
// get an lwp as the VM thread continues to spin with sleeps of 1 millisecond.
|
||||
// The 1 millisecond wait doesn't seem long enough for the kernel to issue a
|
||||
// SIGWAITING signal which will cause a new lwp to be created. So we count the
|
||||
// number of times yield_all is called in the one loop and increase the sleep
|
||||
// time after 8 attempts. If this fails too we increase the concurrency level
|
||||
// so that the starving thread would get an lwp
|
||||
|
||||
void os::yield_all(int attempts) {
|
||||
void os::yield_all() {
|
||||
// Yields to all threads, including threads with lower priorities
|
||||
if (attempts == 0) {
|
||||
os::sleep(Thread::current(), 1, false);
|
||||
} else {
|
||||
int iterations = attempts % 30;
|
||||
if (iterations == 0 && !os::Solaris::T2_libthread()) {
|
||||
// thr_setconcurrency and _getconcurrency make sense only under T1.
|
||||
int noofLWPS = thr_getconcurrency();
|
||||
if (noofLWPS < (Threads::number_of_threads() + 2)) {
|
||||
thr_setconcurrency(thr_getconcurrency() + 1);
|
||||
}
|
||||
} else if (iterations < 25) {
|
||||
os::sleep(Thread::current(), 1, false);
|
||||
} else {
|
||||
os::sleep(Thread::current(), 10, false);
|
||||
}
|
||||
}
|
||||
os::sleep(Thread::current(), 1, false);
|
||||
}
|
||||
|
||||
// Called from the tight loops to possibly influence time-sharing heuristics
|
||||
void os::loop_breaker(int attempts) {
|
||||
os::yield_all(attempts);
|
||||
}
|
||||
|
||||
|
||||
// Interface for setting lwp priorities. If we are using T2 libthread,
|
||||
// which forces the use of BoundThreads or we manually set UseBoundThreads,
|
||||
// all of our threads will be assigned to real lwp's. Using the thr_setprio
|
||||
// function is meaningless in this mode so we must adjust the real lwp's priority
|
||||
// The routines below implement the getting and setting of lwp priorities.
|
||||
//
|
||||
// Note: T2 is now the only supported libthread. UseBoundThreads flag is
|
||||
// being deprecated and all threads are now BoundThreads
|
||||
//
|
||||
// Note: There are three priority scales used on Solaris. Java priotities
|
||||
// which range from 1 to 10, libthread "thr_setprio" scale which range
|
||||
// from 0 to 127, and the current scheduling class of the process we
|
||||
@ -3437,29 +3302,19 @@ static int lwp_priocntl_init () {
|
||||
|
||||
if (!UseThreadPriorities) return 0;
|
||||
|
||||
// We are using Bound threads, we need to determine our priority ranges
|
||||
if (os::Solaris::T2_libthread() || UseBoundThreads) {
|
||||
// If ThreadPriorityPolicy is 1, switch tables
|
||||
if (ThreadPriorityPolicy == 1) {
|
||||
for (i = 0 ; i < CriticalPriority+1; i++)
|
||||
os::java_to_os_priority[i] = prio_policy1[i];
|
||||
}
|
||||
if (UseCriticalJavaThreadPriority) {
|
||||
// MaxPriority always maps to the FX scheduling class and criticalPrio.
|
||||
// See set_native_priority() and set_lwp_class_and_priority().
|
||||
// Save original MaxPriority mapping in case attempt to
|
||||
// use critical priority fails.
|
||||
java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority];
|
||||
// Set negative to distinguish from other priorities
|
||||
os::java_to_os_priority[MaxPriority] = -criticalPrio;
|
||||
}
|
||||
}
|
||||
// Not using Bound Threads, set to ThreadPolicy 1
|
||||
else {
|
||||
for ( i = 0 ; i < CriticalPriority+1; i++ ) {
|
||||
// If ThreadPriorityPolicy is 1, switch tables
|
||||
if (ThreadPriorityPolicy == 1) {
|
||||
for (i = 0 ; i < CriticalPriority+1; i++)
|
||||
os::java_to_os_priority[i] = prio_policy1[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (UseCriticalJavaThreadPriority) {
|
||||
// MaxPriority always maps to the FX scheduling class and criticalPrio.
|
||||
// See set_native_priority() and set_lwp_class_and_priority().
|
||||
// Save original MaxPriority mapping in case attempt to
|
||||
// use critical priority fails.
|
||||
java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority];
|
||||
// Set negative to distinguish from other priorities
|
||||
os::java_to_os_priority[MaxPriority] = -criticalPrio;
|
||||
}
|
||||
|
||||
// Get IDs for a set of well-known scheduling classes.
|
||||
@ -3583,10 +3438,6 @@ int scale_to_lwp_priority (int rMin, int rMax, int x)
|
||||
|
||||
|
||||
// set_lwp_class_and_priority
|
||||
//
|
||||
// Set the class and priority of the lwp. This call should only
|
||||
// be made when using bound threads (T2 threads are bound by default).
|
||||
//
|
||||
int set_lwp_class_and_priority(int ThreadID, int lwpid,
|
||||
int newPrio, int new_class, bool scale) {
|
||||
int rslt;
|
||||
@ -3812,23 +3663,20 @@ OSReturn os::set_native_priority(Thread* thread, int newpri) {
|
||||
status = thr_setprio(thread->osthread()->thread_id(), newpri);
|
||||
}
|
||||
|
||||
if (os::Solaris::T2_libthread() ||
|
||||
(UseBoundThreads && osthread->is_vm_created())) {
|
||||
int lwp_status =
|
||||
set_lwp_class_and_priority(osthread->thread_id(),
|
||||
osthread->lwp_id(),
|
||||
newpri,
|
||||
fxcritical ? fxLimits.schedPolicy : myClass,
|
||||
!fxcritical);
|
||||
if (lwp_status != 0 && fxcritical) {
|
||||
// Try again, this time without changing the scheduling class
|
||||
newpri = java_MaxPriority_to_os_priority;
|
||||
lwp_status = set_lwp_class_and_priority(osthread->thread_id(),
|
||||
osthread->lwp_id(),
|
||||
newpri, myClass, false);
|
||||
}
|
||||
status |= lwp_status;
|
||||
int lwp_status =
|
||||
set_lwp_class_and_priority(osthread->thread_id(),
|
||||
osthread->lwp_id(),
|
||||
newpri,
|
||||
fxcritical ? fxLimits.schedPolicy : myClass,
|
||||
!fxcritical);
|
||||
if (lwp_status != 0 && fxcritical) {
|
||||
// Try again, this time without changing the scheduling class
|
||||
newpri = java_MaxPriority_to_os_priority;
|
||||
lwp_status = set_lwp_class_and_priority(osthread->thread_id(),
|
||||
osthread->lwp_id(),
|
||||
newpri, myClass, false);
|
||||
}
|
||||
status |= lwp_status;
|
||||
return (status == 0) ? OS_OK : OS_ERR;
|
||||
}
|
||||
|
||||
@ -4495,13 +4343,6 @@ const char* os::exception_name(int exception_code, char* buf, size_t size) {
|
||||
}
|
||||
}
|
||||
|
||||
// (Static) wrappers for the new libthread API
|
||||
int_fnP_thread_t_iP_uP_stack_tP_gregset_t os::Solaris::_thr_getstate;
|
||||
int_fnP_thread_t_i_gregset_t os::Solaris::_thr_setstate;
|
||||
int_fnP_thread_t_i os::Solaris::_thr_setmutator;
|
||||
int_fnP_thread_t os::Solaris::_thr_suspend_mutator;
|
||||
int_fnP_thread_t os::Solaris::_thr_continue_mutator;
|
||||
|
||||
// (Static) wrapper for getisax(2) call.
|
||||
os::Solaris::getisax_func_t os::Solaris::_getisax = 0;
|
||||
|
||||
@ -4536,78 +4377,9 @@ static address resolve_symbol(const char* name) {
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// isT2_libthread()
|
||||
//
|
||||
// Routine to determine if we are currently using the new T2 libthread.
|
||||
//
|
||||
// We determine if we are using T2 by reading /proc/self/lstatus and
|
||||
// looking for a thread with the ASLWP bit set. If we find this status
|
||||
// bit set, we must assume that we are NOT using T2. The T2 team
|
||||
// has approved this algorithm.
|
||||
//
|
||||
// We need to determine if we are running with the new T2 libthread
|
||||
// since setting native thread priorities is handled differently
|
||||
// when using this library. All threads created using T2 are bound
|
||||
// threads. Calling thr_setprio is meaningless in this case.
|
||||
//
|
||||
bool isT2_libthread() {
|
||||
static prheader_t * lwpArray = NULL;
|
||||
static int lwpSize = 0;
|
||||
static int lwpFile = -1;
|
||||
lwpstatus_t * that;
|
||||
char lwpName [128];
|
||||
bool isT2 = false;
|
||||
|
||||
#define ADR(x) ((uintptr_t)(x))
|
||||
#define LWPINDEX(ary,ix) ((lwpstatus_t *)(((ary)->pr_entsize * (ix)) + (ADR((ary) + 1))))
|
||||
|
||||
lwpFile = ::open("/proc/self/lstatus", O_RDONLY, 0);
|
||||
if (lwpFile < 0) {
|
||||
if (ThreadPriorityVerbose) warning ("Couldn't open /proc/self/lstatus\n");
|
||||
return false;
|
||||
}
|
||||
lwpSize = 16*1024;
|
||||
for (;;) {
|
||||
::lseek64 (lwpFile, 0, SEEK_SET);
|
||||
lwpArray = (prheader_t *)NEW_C_HEAP_ARRAY(char, lwpSize, mtInternal);
|
||||
if (::read(lwpFile, lwpArray, lwpSize) < 0) {
|
||||
if (ThreadPriorityVerbose) warning("Error reading /proc/self/lstatus\n");
|
||||
break;
|
||||
}
|
||||
if ((lwpArray->pr_nent * lwpArray->pr_entsize) <= lwpSize) {
|
||||
// We got a good snapshot - now iterate over the list.
|
||||
int aslwpcount = 0;
|
||||
for (int i = 0; i < lwpArray->pr_nent; i++ ) {
|
||||
that = LWPINDEX(lwpArray,i);
|
||||
if (that->pr_flags & PR_ASLWP) {
|
||||
aslwpcount++;
|
||||
}
|
||||
}
|
||||
if (aslwpcount == 0) isT2 = true;
|
||||
break;
|
||||
}
|
||||
lwpSize = lwpArray->pr_nent * lwpArray->pr_entsize;
|
||||
FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal); // retry.
|
||||
}
|
||||
|
||||
FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal);
|
||||
::close (lwpFile);
|
||||
if (ThreadPriorityVerbose) {
|
||||
if (isT2) tty->print_cr("We are running with a T2 libthread\n");
|
||||
else tty->print_cr("We are not running with a T2 libthread\n");
|
||||
}
|
||||
return isT2;
|
||||
}
|
||||
|
||||
|
||||
void os::Solaris::libthread_init() {
|
||||
address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators");
|
||||
|
||||
// Determine if we are running with the new T2 libthread
|
||||
os::Solaris::set_T2_libthread(isT2_libthread());
|
||||
|
||||
lwp_priocntl_init();
|
||||
|
||||
// RTLD_DEFAULT was not defined on some early versions of 5.5.1
|
||||
@ -4618,22 +4390,6 @@ void os::Solaris::libthread_init() {
|
||||
guarantee(func != NULL, "libthread.so is too old.");
|
||||
}
|
||||
|
||||
// Initialize the new libthread getstate API wrappers
|
||||
func = resolve_symbol("thr_getstate");
|
||||
os::Solaris::set_thr_getstate(CAST_TO_FN_PTR(int_fnP_thread_t_iP_uP_stack_tP_gregset_t, func));
|
||||
|
||||
func = resolve_symbol("thr_setstate");
|
||||
os::Solaris::set_thr_setstate(CAST_TO_FN_PTR(int_fnP_thread_t_i_gregset_t, func));
|
||||
|
||||
func = resolve_symbol("thr_setmutator");
|
||||
os::Solaris::set_thr_setmutator(CAST_TO_FN_PTR(int_fnP_thread_t_i, func));
|
||||
|
||||
func = resolve_symbol("thr_suspend_mutator");
|
||||
os::Solaris::set_thr_suspend_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func));
|
||||
|
||||
func = resolve_symbol("thr_continue_mutator");
|
||||
os::Solaris::set_thr_continue_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func));
|
||||
|
||||
int size;
|
||||
void (*handler_info_func)(address *, int *);
|
||||
handler_info_func = CAST_TO_FN_PTR(void (*)(address *, int *), resolve_symbol("thr_sighndlrinfo"));
|
||||
@ -5536,11 +5292,7 @@ void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
|
||||
}
|
||||
|
||||
bool os::is_thread_cpu_time_supported() {
|
||||
if ( os::Solaris::T2_libthread() || UseBoundThreads ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// System loadavg support. Returns -1 if load average cannot be obtained.
|
||||
|
||||
@ -41,19 +41,6 @@ class Solaris {
|
||||
#define TRS_LWPID 2
|
||||
#define TRS_INVALID 3
|
||||
|
||||
// _T2_libthread is true if we believe we are running with the newer
|
||||
// SunSoft lib/lwp/libthread: default Solaris 9, available Solaris 8
|
||||
// which is a lightweight libthread that also supports all T1
|
||||
static bool _T2_libthread;
|
||||
// These refer to new libthread interface functions
|
||||
// They get intialized if we dynamically detect new libthread
|
||||
static int_fnP_thread_t_iP_uP_stack_tP_gregset_t _thr_getstate;
|
||||
static int_fnP_thread_t_i_gregset_t _thr_setstate;
|
||||
static int_fnP_thread_t_i _thr_setmutator;
|
||||
static int_fnP_thread_t _thr_suspend_mutator;
|
||||
static int_fnP_thread_t _thr_continue_mutator;
|
||||
// libthread_init sets the above, if the new functionality is detected
|
||||
|
||||
// initialized to libthread or lwp synchronization primitives depending on UseLWPSychronization
|
||||
static int_fnP_mutex_tP _mutex_lock;
|
||||
static int_fnP_mutex_tP _mutex_trylock;
|
||||
@ -214,29 +201,6 @@ class Solaris {
|
||||
static struct sigaction *get_chained_signal_action(int sig);
|
||||
static bool chained_handler(int sig, siginfo_t *siginfo, void *context);
|
||||
|
||||
// The following allow us to link against both the old and new libthread (2.8)
|
||||
// and exploit the new libthread functionality if available.
|
||||
|
||||
static bool T2_libthread() { return _T2_libthread; }
|
||||
static void set_T2_libthread(bool T2_libthread) { _T2_libthread = T2_libthread; }
|
||||
|
||||
static int thr_getstate(thread_t tid, int *flag, unsigned *lwp, stack_t *ss, gregset_t rs)
|
||||
{ return _thr_getstate(tid, flag, lwp, ss, rs); }
|
||||
static void set_thr_getstate(int_fnP_thread_t_iP_uP_stack_tP_gregset_t func)
|
||||
{ _thr_getstate = func; }
|
||||
|
||||
static int thr_setstate(thread_t tid, int flag, gregset_t rs) { return _thr_setstate(tid, flag, rs); }
|
||||
static void set_thr_setstate(int_fnP_thread_t_i_gregset_t func) { _thr_setstate = func; }
|
||||
|
||||
static int thr_setmutator(thread_t tid, int enabled) { return _thr_setmutator(tid, enabled); }
|
||||
static void set_thr_setmutator(int_fnP_thread_t_i func) { _thr_setmutator = func; }
|
||||
|
||||
static int thr_suspend_mutator(thread_t tid) { return _thr_suspend_mutator(tid); }
|
||||
static void set_thr_suspend_mutator(int_fnP_thread_t func) { _thr_suspend_mutator = func; }
|
||||
|
||||
static int thr_continue_mutator(thread_t tid) { return _thr_continue_mutator(tid); }
|
||||
static void set_thr_continue_mutator(int_fnP_thread_t func) { _thr_continue_mutator = func; }
|
||||
|
||||
// Allows us to switch between lwp and thread -based synchronization
|
||||
static int mutex_lock(mutex_t *mx) { return _mutex_lock(mx); }
|
||||
static int mutex_trylock(mutex_t *mx) { return _mutex_trylock(mx); }
|
||||
|
||||
@ -3518,7 +3518,7 @@ os::YieldResult os::NakedYield() {
|
||||
|
||||
void os::yield() { os::NakedYield(); }
|
||||
|
||||
void os::yield_all(int attempts) {
|
||||
void os::yield_all() {
|
||||
// Yields to all threads, including threads with lower priorities
|
||||
Sleep(1);
|
||||
}
|
||||
@ -3864,12 +3864,6 @@ void os::init(void) {
|
||||
win32::setmode_streams();
|
||||
init_page_sizes((size_t) win32::vm_page_size());
|
||||
|
||||
// For better scalability on MP systems (must be called after initialize_system_info)
|
||||
#ifndef PRODUCT
|
||||
if (is_MP()) {
|
||||
NoYieldsInMicrolock = true;
|
||||
}
|
||||
#endif
|
||||
// This may be overridden later when argument processing is done.
|
||||
FLAG_SET_ERGO(bool, UseLargePagesIndividualAllocation,
|
||||
os::win32::is_windows_2003());
|
||||
|
||||
@ -52,9 +52,6 @@ inline void* os::dll_lookup(void *lib, const char *name) {
|
||||
return (void*)::GetProcAddress((HMODULE)lib, name);
|
||||
}
|
||||
|
||||
// Used to improve time-sharing on some systems
|
||||
inline void os::loop_breaker(int attempts) {}
|
||||
|
||||
inline bool os::obsolete_option(const JavaVMOption *option) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2014, 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
|
||||
@ -270,31 +270,6 @@ frame os::current_frame() {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs))
|
||||
return (err);
|
||||
if (*flags == TRS_LWPID) {
|
||||
sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(),
|
||||
*lwp);
|
||||
if ((lwpfd = ::open(lwpstatusfile, O_RDONLY)) < 0) {
|
||||
perror("thr_mutator_status: open lwpstatus");
|
||||
return (EINVAL);
|
||||
}
|
||||
if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) !=
|
||||
sizeof (lwpstatus_t)) {
|
||||
perror("thr_mutator_status: read lwpstatus");
|
||||
(void) ::close(lwpfd);
|
||||
return (EINVAL);
|
||||
}
|
||||
(void) ::close(lwpfd);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
bool os::is_allocatable(size_t bytes) {
|
||||
#ifdef _LP64
|
||||
return true;
|
||||
|
||||
@ -256,30 +256,6 @@ frame os::current_frame() {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs))
|
||||
return (err);
|
||||
if (*flags == TRS_LWPID) {
|
||||
sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(),
|
||||
*lwp);
|
||||
if ((lwpfd = open(lwpstatusfile, O_RDONLY)) < 0) {
|
||||
perror("thr_mutator_status: open lwpstatus");
|
||||
return (EINVAL);
|
||||
}
|
||||
if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) !=
|
||||
sizeof (lwpstatus_t)) {
|
||||
perror("thr_mutator_status: read lwpstatus");
|
||||
(void) close(lwpfd);
|
||||
return (EINVAL);
|
||||
}
|
||||
(void) close(lwpfd);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifndef AMD64
|
||||
|
||||
// Detecting SSE support by OS
|
||||
|
||||
@ -4180,8 +4180,12 @@ ClassFileParser::~ClassFileParser() {
|
||||
|
||||
clear_class_metadata();
|
||||
|
||||
// deallocate the klass if already created.
|
||||
MetadataFactory::free_metadata(_loader_data, _klass);
|
||||
// deallocate the klass if already created. Don't directly deallocate, but add
|
||||
// to the deallocate list so that the klass is removed from the CLD::_klasses list
|
||||
// at a safepoint.
|
||||
if (_klass != NULL) {
|
||||
_loader_data->add_to_deallocate_list(_klass);
|
||||
}
|
||||
_klass = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -464,25 +464,26 @@ bool java_lang_String::equals(oop str1, oop str2) {
|
||||
void java_lang_String::print(oop java_string, outputStream* st) {
|
||||
assert(java_string->klass() == SystemDictionary::String_klass(), "must be java_string");
|
||||
typeArrayOop value = java_lang_String::value(java_string);
|
||||
int offset = java_lang_String::offset(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
|
||||
int end = MIN2(length, 100);
|
||||
if (value == NULL) {
|
||||
// This can happen if, e.g., printing a String
|
||||
// object before its initializer has been called
|
||||
st->print_cr("NULL");
|
||||
} else {
|
||||
st->print("\"");
|
||||
for (int index = 0; index < length; index++) {
|
||||
st->print("%c", value->char_at(index + offset));
|
||||
}
|
||||
st->print("\"");
|
||||
st->print("NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
int offset = java_lang_String::offset(java_string);
|
||||
int length = java_lang_String::length(java_string);
|
||||
|
||||
st->print("\"");
|
||||
for (int index = 0; index < length; index++) {
|
||||
st->print("%c", value->char_at(index + offset));
|
||||
}
|
||||
st->print("\"");
|
||||
}
|
||||
|
||||
static void initialize_static_field(fieldDescriptor* fd, TRAPS) {
|
||||
Handle mirror (THREAD, fd->field_holder()->java_mirror());
|
||||
|
||||
static void initialize_static_field(fieldDescriptor* fd, Handle mirror, TRAPS) {
|
||||
assert(mirror.not_null() && fd->is_static(), "just checking");
|
||||
if (fd->has_initial_value()) {
|
||||
BasicType t = fd->field_type();
|
||||
@ -549,21 +550,45 @@ void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
|
||||
create_mirror(k, Handle(NULL), CHECK);
|
||||
}
|
||||
|
||||
oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
|
||||
void java_lang_Class::initialize_mirror_fields(KlassHandle k,
|
||||
Handle mirror,
|
||||
Handle protection_domain,
|
||||
TRAPS) {
|
||||
// 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);
|
||||
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, mirror, CHECK);
|
||||
}
|
||||
|
||||
void 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
|
||||
// the cached flags after the class file is parsed, but before the
|
||||
// class is put into the system dictionary.
|
||||
int computed_modifiers = k->compute_modifier_flags(CHECK_0);
|
||||
int computed_modifiers = k->compute_modifier_flags(CHECK);
|
||||
k->set_modifier_flags(computed_modifiers);
|
||||
// Class_klass has to be loaded because it is used to allocate
|
||||
// the mirror.
|
||||
if (SystemDictionary::Class_klass_loaded()) {
|
||||
// Allocate mirror (java.lang.Class instance)
|
||||
Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
|
||||
Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK);
|
||||
|
||||
// Setup indirection from mirror->klass
|
||||
if (!k.is_null()) {
|
||||
java_lang_Class::set_klass(mirror(), k());
|
||||
}
|
||||
|
||||
InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass());
|
||||
assert(oop_size(mirror()) == mk->instance_size(k), "should have been set");
|
||||
|
||||
java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
|
||||
|
||||
// It might also have a component mirror. This mirror must already exist.
|
||||
@ -576,29 +601,32 @@ oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAP
|
||||
assert(k->oop_is_objArray(), "Must be");
|
||||
Klass* element_klass = ObjArrayKlass::cast(k())->element_klass();
|
||||
assert(element_klass != NULL, "Must have an element klass");
|
||||
comp_mirror = element_klass->java_mirror();
|
||||
comp_mirror = element_klass->java_mirror();
|
||||
}
|
||||
assert(comp_mirror.not_null(), "must have a mirror");
|
||||
|
||||
// Two-way link between the array klass and its component mirror:
|
||||
// Two-way link between the array klass and its component mirror:
|
||||
ArrayKlass::cast(k())->set_component_mirror(comp_mirror());
|
||||
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);
|
||||
initialize_mirror_fields(k, mirror, protection_domain, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
// If any of the fields throws an exception like OOM remove the klass field
|
||||
// from the mirror so GC doesn't follow it after the klass has been deallocated.
|
||||
// This mirror looks like a primitive type, which logically it is because it
|
||||
// it represents no class.
|
||||
java_lang_Class::set_klass(mirror(), NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup indirection from klass->mirror last
|
||||
// after any exceptions can happen during allocations.
|
||||
if (!k.is_null()) {
|
||||
k->set_java_mirror(mirror());
|
||||
}
|
||||
return mirror();
|
||||
} else {
|
||||
if (fixup_mirror_list() == NULL) {
|
||||
GrowableArray<Klass*>* list =
|
||||
@ -606,12 +634,10 @@ oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAP
|
||||
set_fixup_mirror_list(list);
|
||||
}
|
||||
fixup_mirror_list()->push(k());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int java_lang_Class::oop_size(oop java_class) {
|
||||
assert(_oop_size_offset != 0, "must be set");
|
||||
return java_class->int_field(_oop_size_offset);
|
||||
|
||||
@ -246,11 +246,12 @@ class java_lang_Class : AllStatic {
|
||||
|
||||
static void set_init_lock(oop java_class, oop init_lock);
|
||||
static void set_protection_domain(oop java_class, oop protection_domain);
|
||||
static void initialize_mirror_fields(KlassHandle k, Handle mirror, Handle protection_domain, TRAPS);
|
||||
public:
|
||||
static void compute_offsets();
|
||||
|
||||
// Instance creation
|
||||
static oop create_mirror(KlassHandle k, Handle protection_domain, TRAPS);
|
||||
static void 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
|
||||
|
||||
@ -826,47 +826,6 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
|
||||
}
|
||||
} // load_instance_class loop
|
||||
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
// An exception, such as OOM could have happened at various places inside
|
||||
// load_instance_class. We might have partially initialized a shared class
|
||||
// and need to clean it up.
|
||||
if (class_loader.is_null()) {
|
||||
// In some cases k may be null. Let's find the shared class again.
|
||||
instanceKlassHandle ik(THREAD, find_shared_class(name));
|
||||
if (ik.not_null()) {
|
||||
if (ik->class_loader_data() == NULL) {
|
||||
// We didn't go as far as Klass::restore_unshareable_info(),
|
||||
// so nothing to clean up.
|
||||
} else {
|
||||
Klass *kk;
|
||||
{
|
||||
MutexLocker mu(SystemDictionary_lock, THREAD);
|
||||
kk = find_class(d_index, d_hash, name, ik->class_loader_data());
|
||||
}
|
||||
if (kk != NULL) {
|
||||
// No clean up is needed if the shared class has been entered
|
||||
// into system dictionary, as load_shared_class() won't be called
|
||||
// again.
|
||||
} else {
|
||||
// This must be done outside of the SystemDictionary_lock to
|
||||
// avoid deadlock.
|
||||
//
|
||||
// Note that Klass::restore_unshareable_info (called via
|
||||
// load_instance_class above) is also called outside
|
||||
// of SystemDictionary_lock. Other threads are blocked from
|
||||
// loading this class because they are waiting on the
|
||||
// SystemDictionary_lock until this thread removes
|
||||
// the placeholder below.
|
||||
//
|
||||
// This need to be re-thought when parallel-capable non-boot
|
||||
// classloaders are supported by CDS (today they're not).
|
||||
clean_up_shared_class(ik, class_loader, THREAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (load_instance_added == true) {
|
||||
// clean up placeholder entries for LOAD_INSTANCE success or error
|
||||
// This brackets the SystemDictionary updates for both defining
|
||||
@ -1272,19 +1231,6 @@ instanceKlassHandle SystemDictionary::load_shared_class(
|
||||
return ik;
|
||||
}
|
||||
|
||||
void SystemDictionary::clean_up_shared_class(instanceKlassHandle ik, Handle class_loader, TRAPS) {
|
||||
// Updating methods must be done under a lock so multiple
|
||||
// threads don't update these in parallel
|
||||
// Shared classes are all currently loaded by the bootstrap
|
||||
// classloader, so this will never cause a deadlock on
|
||||
// a custom class loader lock.
|
||||
{
|
||||
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
|
||||
check_loader_lock_contention(lockObject, THREAD);
|
||||
ObjectLocker ol(lockObject, THREAD, true);
|
||||
ik->remove_unshareable_info();
|
||||
}
|
||||
}
|
||||
|
||||
instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
|
||||
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
|
||||
|
||||
@ -617,7 +617,6 @@ private:
|
||||
Handle class_loader, TRAPS);
|
||||
static instanceKlassHandle load_shared_class(instanceKlassHandle ik,
|
||||
Handle class_loader, TRAPS);
|
||||
static void clean_up_shared_class(instanceKlassHandle ik, Handle class_loader, TRAPS);
|
||||
static instanceKlassHandle load_instance_class(Symbol* class_name, Handle class_loader, TRAPS);
|
||||
static Handle compute_loader_lock_object(Handle class_loader, TRAPS);
|
||||
static void check_loader_lock_contention(Handle loader_lock, TRAPS);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2014, 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
|
||||
@ -582,36 +582,6 @@ void CollectedHeap::post_full_gc_dump(GCTimer* timer) {
|
||||
}
|
||||
}
|
||||
|
||||
oop CollectedHeap::Class_obj_allocate(KlassHandle klass, int size, KlassHandle real_klass, TRAPS) {
|
||||
debug_only(check_for_valid_allocation_state());
|
||||
assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
|
||||
assert(size >= 0, "int won't convert to size_t");
|
||||
HeapWord* obj;
|
||||
assert(ScavengeRootsInCode > 0, "must be");
|
||||
obj = common_mem_allocate_init(real_klass, size, CHECK_NULL);
|
||||
post_allocation_setup_common(klass, obj);
|
||||
assert(Universe::is_bootstrapping() ||
|
||||
!((oop)obj)->is_array(), "must not be an array");
|
||||
NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
|
||||
oop mirror = (oop)obj;
|
||||
|
||||
java_lang_Class::set_oop_size(mirror, size);
|
||||
|
||||
// Setup indirections
|
||||
if (!real_klass.is_null()) {
|
||||
java_lang_Class::set_klass(mirror, real_klass());
|
||||
real_klass->set_java_mirror(mirror);
|
||||
}
|
||||
|
||||
InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass());
|
||||
assert(size == mk->instance_size(real_klass), "should have been set");
|
||||
|
||||
// notify jvmti and dtrace
|
||||
post_allocation_notify(klass, (oop)obj);
|
||||
|
||||
return mirror;
|
||||
}
|
||||
|
||||
/////////////// Unit tests ///////////////
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2014, 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
|
||||
@ -315,9 +315,6 @@ class CollectedHeap : public CHeapObj<mtInternal> {
|
||||
// May be overridden to set additional parallelism.
|
||||
virtual void set_par_threads(uint t) { _n_par_threads = t; };
|
||||
|
||||
// Allocate and initialize instances of Class
|
||||
static oop Class_obj_allocate(KlassHandle klass, int size, KlassHandle real_klass, TRAPS);
|
||||
|
||||
// General obj/array allocation facilities.
|
||||
inline static oop obj_allocate(KlassHandle klass, int size, TRAPS);
|
||||
inline static oop array_allocate(KlassHandle klass, int size, int length, TRAPS);
|
||||
|
||||
@ -144,6 +144,10 @@ void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data,
|
||||
// CDS support. Create a new resolved_references array.
|
||||
void ConstantPool::restore_unshareable_info(TRAPS) {
|
||||
|
||||
// Only create the new resolved references array and lock if it hasn't been
|
||||
// attempted before
|
||||
if (resolved_references() != NULL) return;
|
||||
|
||||
// restore the C++ vtable from the shared archive
|
||||
restore_vtable();
|
||||
|
||||
|
||||
@ -1289,17 +1289,18 @@ void InstanceKlass::do_local_static_fields(FieldClosure* cl) {
|
||||
}
|
||||
|
||||
|
||||
void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAPS) {
|
||||
void InstanceKlass::do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle mirror, TRAPS) {
|
||||
instanceKlassHandle h_this(THREAD, this);
|
||||
do_local_static_fields_impl(h_this, f, CHECK);
|
||||
do_local_static_fields_impl(h_this, f, mirror, CHECK);
|
||||
}
|
||||
|
||||
|
||||
void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_k, void f(fieldDescriptor* fd, TRAPS), TRAPS) {
|
||||
void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_k,
|
||||
void f(fieldDescriptor* fd, Handle, TRAPS), Handle mirror, TRAPS) {
|
||||
for (JavaFieldStream fs(this_k()); !fs.done(); fs.next()) {
|
||||
if (fs.access_flags().is_static()) {
|
||||
fieldDescriptor& fd = fs.field_descriptor();
|
||||
f(&fd, CHECK);
|
||||
f(&fd, mirror, CHECK);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2240,9 +2241,7 @@ void InstanceKlass::restore_unshareable_info(TRAPS) {
|
||||
int num_methods = methods->length();
|
||||
for (int index2 = 0; index2 < num_methods; ++index2) {
|
||||
methodHandle m(THREAD, methods->at(index2));
|
||||
m()->link_method(m, CHECK);
|
||||
// restore method's vtable by calling a virtual function
|
||||
m->restore_vtable();
|
||||
m->restore_unshareable_info(CHECK);
|
||||
}
|
||||
if (JvmtiExport::has_redefined_a_class()) {
|
||||
// Reinitialize vtable because RedefineClasses may have changed some
|
||||
@ -3409,6 +3408,10 @@ static void purge_previous_versions_internal(InstanceKlass* ik, int emcp_method_
|
||||
("purge: %s(%s): prev method @%d in version @%d is alive",
|
||||
method->name()->as_C_string(),
|
||||
method->signature()->as_C_string(), j, i));
|
||||
if (method->method_data() != NULL) {
|
||||
// Clean out any weak method links
|
||||
method->method_data()->clean_weak_method_links();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3418,6 +3421,14 @@ static void purge_previous_versions_internal(InstanceKlass* ik, int emcp_method_
|
||||
("purge: previous version stats: live=%d, deleted=%d", live_count,
|
||||
deleted_count));
|
||||
}
|
||||
|
||||
Array<Method*>* methods = ik->methods();
|
||||
int num_methods = methods->length();
|
||||
for (int index2 = 0; index2 < num_methods; ++index2) {
|
||||
if (methods->at(index2)->method_data() != NULL) {
|
||||
methods->at(index2)->method_data()->clean_weak_method_links();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// External interface for use during class unloading.
|
||||
|
||||
@ -802,7 +802,7 @@ class InstanceKlass: public Klass {
|
||||
// Iterators
|
||||
void do_local_static_fields(FieldClosure* cl);
|
||||
void do_nonstatic_fields(FieldClosure* cl); // including inherited fields
|
||||
void do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAPS);
|
||||
void do_local_static_fields(void f(fieldDescriptor*, Handle, TRAPS), Handle, TRAPS);
|
||||
|
||||
void methods_do(void f(Method* method));
|
||||
void array_klasses_do(void f(Klass* k));
|
||||
@ -1010,7 +1010,7 @@ private:
|
||||
static void set_initialization_state_and_notify_impl (instanceKlassHandle this_k, ClassState state, TRAPS);
|
||||
static void call_class_initializer_impl (instanceKlassHandle this_k, TRAPS);
|
||||
static Klass* array_klass_impl (instanceKlassHandle this_k, bool or_null, int n, TRAPS);
|
||||
static void do_local_static_fields_impl (instanceKlassHandle this_k, void f(fieldDescriptor* fd, TRAPS), TRAPS);
|
||||
static void do_local_static_fields_impl (instanceKlassHandle this_k, void f(fieldDescriptor* fd, Handle, TRAPS), Handle, TRAPS);
|
||||
/* jni_id_for_impl for jfieldID only */
|
||||
static JNIid* jni_id_for_impl (instanceKlassHandle this_k, int offset);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2014, 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
|
||||
@ -367,7 +367,12 @@ instanceOop InstanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
|
||||
// Query before forming handle.
|
||||
int size = instance_size(k);
|
||||
KlassHandle h_k(THREAD, this);
|
||||
instanceOop i = (instanceOop) CollectedHeap::Class_obj_allocate(h_k, size, k, CHECK_NULL);
|
||||
instanceOop i = (instanceOop)CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);
|
||||
|
||||
// Since mirrors can be variable sized because of the static fields, store
|
||||
// the size in the mirror itself.
|
||||
java_lang_Class::set_oop_size(i, size);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
@ -475,12 +475,8 @@ void Klass::oops_do(OopClosure* cl) {
|
||||
}
|
||||
|
||||
void Klass::remove_unshareable_info() {
|
||||
if (!DumpSharedSpaces) {
|
||||
// Clean up after OOM during class loading
|
||||
if (class_loader_data() != NULL) {
|
||||
class_loader_data()->remove_class(this);
|
||||
}
|
||||
}
|
||||
assert (DumpSharedSpaces, "only called for DumpSharedSpaces");
|
||||
|
||||
set_subklass(NULL);
|
||||
set_next_sibling(NULL);
|
||||
// Clear the java mirror
|
||||
@ -492,17 +488,26 @@ void Klass::remove_unshareable_info() {
|
||||
}
|
||||
|
||||
void Klass::restore_unshareable_info(TRAPS) {
|
||||
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
|
||||
// Restore class_loader_data to the null class loader data
|
||||
set_class_loader_data(loader_data);
|
||||
// If an exception happened during CDS restore, some of these fields may already be
|
||||
// set. We leave the class on the CLD list, even if incomplete so that we don't
|
||||
// modify the CLD list outside a safepoint.
|
||||
if (class_loader_data() == NULL) {
|
||||
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
|
||||
// Restore class_loader_data to the null class loader data
|
||||
set_class_loader_data(loader_data);
|
||||
|
||||
// Add to null class loader list first before creating the mirror
|
||||
// (same order as class file parsing)
|
||||
loader_data->add_class(this);
|
||||
// Add to null class loader list first before creating the mirror
|
||||
// (same order as class file parsing)
|
||||
loader_data->add_class(this);
|
||||
}
|
||||
|
||||
// Recreate the class mirror. The protection_domain is always null for
|
||||
// boot loader, for now.
|
||||
java_lang_Class::create_mirror(this, Handle(NULL), CHECK);
|
||||
// Only recreate it if not present. A previous attempt to restore may have
|
||||
// gotten an OOM later but keep the mirror if it was created.
|
||||
if (java_mirror() == NULL) {
|
||||
java_lang_Class::create_mirror(this, Handle(NULL), CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
Klass* Klass::array_klass_or_null(int rank) {
|
||||
|
||||
@ -903,6 +903,19 @@ address Method::make_adapters(methodHandle mh, TRAPS) {
|
||||
return adapter->get_c2i_entry();
|
||||
}
|
||||
|
||||
void Method::restore_unshareable_info(TRAPS) {
|
||||
// Since restore_unshareable_info can be called more than once for a method, don't
|
||||
// redo any work. If this field is restored, there is nothing to do.
|
||||
if (_from_compiled_entry == NULL) {
|
||||
// restore method's vtable by calling a virtual function
|
||||
restore_vtable();
|
||||
|
||||
methodHandle mh(THREAD, this);
|
||||
link_method(mh, CHECK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The verified_code_entry() must be called when a invoke is resolved
|
||||
// on this method.
|
||||
|
||||
|
||||
@ -123,6 +123,8 @@ class Method : public Metadata {
|
||||
void restore_vtable() { guarantee(is_method(), "vtable restored by this call"); }
|
||||
bool is_method() const volatile { return true; }
|
||||
|
||||
void restore_unshareable_info(TRAPS);
|
||||
|
||||
// accessors for instance variables
|
||||
|
||||
ConstMethod* constMethod() const { return _constMethod; }
|
||||
|
||||
@ -1531,9 +1531,35 @@ void MethodData::clean_extra_data_helper(DataLayout* dp, int shift, bool reset)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove SpeculativeTrapData entries that reference an unloaded
|
||||
// method
|
||||
void MethodData::clean_extra_data(BoolObjectClosure* is_alive) {
|
||||
class CleanExtraDataClosure : public StackObj {
|
||||
public:
|
||||
virtual bool is_live(Method* m) = 0;
|
||||
};
|
||||
|
||||
// Check for entries that reference an unloaded method
|
||||
class CleanExtraDataKlassClosure : public CleanExtraDataClosure {
|
||||
private:
|
||||
BoolObjectClosure* _is_alive;
|
||||
public:
|
||||
CleanExtraDataKlassClosure(BoolObjectClosure* is_alive) : _is_alive(is_alive) {}
|
||||
bool is_live(Method* m) {
|
||||
return m->method_holder()->is_loader_alive(_is_alive);
|
||||
}
|
||||
};
|
||||
|
||||
// Check for entries that reference a redefined method
|
||||
class CleanExtraDataMethodClosure : public CleanExtraDataClosure {
|
||||
public:
|
||||
CleanExtraDataMethodClosure() {}
|
||||
bool is_live(Method* m) {
|
||||
return m->on_stack();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Remove SpeculativeTrapData entries that reference an unloaded or
|
||||
// redefined method
|
||||
void MethodData::clean_extra_data(CleanExtraDataClosure* cl) {
|
||||
DataLayout* dp = extra_data_base();
|
||||
DataLayout* end = extra_data_limit();
|
||||
|
||||
@ -1544,7 +1570,7 @@ void MethodData::clean_extra_data(BoolObjectClosure* is_alive) {
|
||||
SpeculativeTrapData* data = new SpeculativeTrapData(dp);
|
||||
Method* m = data->method();
|
||||
assert(m != NULL, "should have a method");
|
||||
if (!m->method_holder()->is_loader_alive(is_alive)) {
|
||||
if (!cl->is_live(m)) {
|
||||
// "shift" accumulates the number of cells for dead
|
||||
// SpeculativeTrapData entries that have been seen so
|
||||
// far. Following entries must be shifted left by that many
|
||||
@ -1575,9 +1601,9 @@ void MethodData::clean_extra_data(BoolObjectClosure* is_alive) {
|
||||
}
|
||||
}
|
||||
|
||||
// Verify there's no unloaded method referenced by a
|
||||
// Verify there's no unloaded or redefined method referenced by a
|
||||
// SpeculativeTrapData entry
|
||||
void MethodData::verify_extra_data_clean(BoolObjectClosure* is_alive) {
|
||||
void MethodData::verify_extra_data_clean(CleanExtraDataClosure* cl) {
|
||||
#ifdef ASSERT
|
||||
DataLayout* dp = extra_data_base();
|
||||
DataLayout* end = extra_data_limit();
|
||||
@ -1587,7 +1613,7 @@ void MethodData::verify_extra_data_clean(BoolObjectClosure* is_alive) {
|
||||
case DataLayout::speculative_trap_data_tag: {
|
||||
SpeculativeTrapData* data = new SpeculativeTrapData(dp);
|
||||
Method* m = data->method();
|
||||
assert(m != NULL && m->method_holder()->is_loader_alive(is_alive), "Method should exist");
|
||||
assert(m != NULL && cl->is_live(m), "Method should exist");
|
||||
break;
|
||||
}
|
||||
case DataLayout::bit_data_tag:
|
||||
@ -1613,6 +1639,19 @@ void MethodData::clean_method_data(BoolObjectClosure* is_alive) {
|
||||
parameters->clean_weak_klass_links(is_alive);
|
||||
}
|
||||
|
||||
clean_extra_data(is_alive);
|
||||
verify_extra_data_clean(is_alive);
|
||||
CleanExtraDataKlassClosure cl(is_alive);
|
||||
clean_extra_data(&cl);
|
||||
verify_extra_data_clean(&cl);
|
||||
}
|
||||
|
||||
void MethodData::clean_weak_method_links() {
|
||||
for (ProfileData* data = first_data();
|
||||
is_valid(data);
|
||||
data = next_data(data)) {
|
||||
data->clean_weak_method_links();
|
||||
}
|
||||
|
||||
CleanExtraDataMethodClosure cl;
|
||||
clean_extra_data(&cl);
|
||||
verify_extra_data_clean(&cl);
|
||||
}
|
||||
|
||||
@ -251,6 +251,9 @@ public:
|
||||
|
||||
// GC support
|
||||
void clean_weak_klass_links(BoolObjectClosure* cl);
|
||||
|
||||
// Redefinition support
|
||||
void clean_weak_method_links();
|
||||
};
|
||||
|
||||
|
||||
@ -506,6 +509,9 @@ public:
|
||||
// GC support
|
||||
virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {}
|
||||
|
||||
// Redefinition support
|
||||
virtual void clean_weak_method_links() {}
|
||||
|
||||
// CI translation: ProfileData can represent both MethodDataOop data
|
||||
// as well as CIMethodData data. This function is provided for translating
|
||||
// an oop in a ProfileData to the ci equivalent. Generally speaking,
|
||||
@ -1989,6 +1995,7 @@ public:
|
||||
//
|
||||
|
||||
CC_INTERP_ONLY(class BytecodeInterpreter;)
|
||||
class CleanExtraDataClosure;
|
||||
|
||||
class MethodData : public Metadata {
|
||||
friend class VMStructs;
|
||||
@ -2146,9 +2153,9 @@ private:
|
||||
static bool profile_parameters_jsr292_only();
|
||||
static bool profile_all_parameters();
|
||||
|
||||
void clean_extra_data(BoolObjectClosure* is_alive);
|
||||
void clean_extra_data(CleanExtraDataClosure* cl);
|
||||
void clean_extra_data_helper(DataLayout* dp, int shift, bool reset = false);
|
||||
void verify_extra_data_clean(BoolObjectClosure* is_alive);
|
||||
void verify_extra_data_clean(CleanExtraDataClosure* cl);
|
||||
|
||||
public:
|
||||
static int header_size() {
|
||||
@ -2440,6 +2447,8 @@ public:
|
||||
static bool profile_return_jsr292_only();
|
||||
|
||||
void clean_method_data(BoolObjectClosure* is_alive);
|
||||
|
||||
void clean_weak_method_links();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_OOPS_METHODDATAOOP_HPP
|
||||
|
||||
@ -70,6 +70,7 @@ public:
|
||||
|
||||
JVMState* ParseGenerator::generate(JVMState* jvms, Parse* parent_parser) {
|
||||
Compile* C = Compile::current();
|
||||
C->print_inlining_update(this);
|
||||
|
||||
if (is_osr()) {
|
||||
// The JVMS for a OSR has a single argument (see its TypeFunc).
|
||||
@ -126,6 +127,7 @@ class DirectCallGenerator : public CallGenerator {
|
||||
|
||||
JVMState* DirectCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
|
||||
GraphKit kit(jvms);
|
||||
kit.C->print_inlining_update(this);
|
||||
bool is_static = method()->is_static();
|
||||
address target = is_static ? SharedRuntime::get_resolve_static_call_stub()
|
||||
: SharedRuntime::get_resolve_opt_virtual_call_stub();
|
||||
@ -178,6 +180,8 @@ JVMState* VirtualCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
|
||||
GraphKit kit(jvms);
|
||||
Node* receiver = kit.argument(0);
|
||||
|
||||
kit.C->print_inlining_update(this);
|
||||
|
||||
if (kit.C->log() != NULL) {
|
||||
kit.C->log()->elem("virtual_call bci='%d'", jvms->bci());
|
||||
}
|
||||
@ -271,14 +275,13 @@ class LateInlineCallGenerator : public DirectCallGenerator {
|
||||
LateInlineCallGenerator(ciMethod* method, CallGenerator* inline_cg) :
|
||||
DirectCallGenerator(method, true), _inline_cg(inline_cg) {}
|
||||
|
||||
virtual bool is_late_inline() const { return true; }
|
||||
virtual bool is_late_inline() const { return true; }
|
||||
|
||||
// Convert the CallStaticJava into an inline
|
||||
virtual void do_late_inline();
|
||||
|
||||
virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
|
||||
Compile *C = Compile::current();
|
||||
C->print_inlining_skip(this);
|
||||
|
||||
// Record that this call site should be revisited once the main
|
||||
// parse is finished.
|
||||
@ -296,10 +299,11 @@ class LateInlineCallGenerator : public DirectCallGenerator {
|
||||
virtual void print_inlining_late(const char* msg) {
|
||||
CallNode* call = call_node();
|
||||
Compile* C = Compile::current();
|
||||
C->print_inlining_insert(this);
|
||||
C->print_inlining_assert_ready();
|
||||
C->print_inlining(method(), call->jvms()->depth()-1, call->jvms()->bci(), msg);
|
||||
C->print_inlining_move_to(this);
|
||||
C->print_inlining_update_delayed(this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void LateInlineCallGenerator::do_late_inline() {
|
||||
@ -360,6 +364,10 @@ void LateInlineCallGenerator::do_late_inline() {
|
||||
map->set_argument(jvms, i1, call->in(TypeFunc::Parms + i1));
|
||||
}
|
||||
|
||||
C->print_inlining_assert_ready();
|
||||
|
||||
C->print_inlining_move_to(this);
|
||||
|
||||
// This check is done here because for_method_handle_inline() method
|
||||
// needs jvms for inlined state.
|
||||
if (!do_late_inline_check(jvms)) {
|
||||
@ -367,8 +375,6 @@ void LateInlineCallGenerator::do_late_inline() {
|
||||
return;
|
||||
}
|
||||
|
||||
C->print_inlining_insert(this);
|
||||
|
||||
CompileLog* log = C->log();
|
||||
if (log != NULL) {
|
||||
log->head("late_inline method='%d'", log->identify(method()));
|
||||
@ -388,7 +394,7 @@ void LateInlineCallGenerator::do_late_inline() {
|
||||
C->set_default_node_notes(entry_nn);
|
||||
}
|
||||
|
||||
// Now perform the inling using the synthesized JVMState
|
||||
// Now perform the inlining using the synthesized JVMState
|
||||
JVMState* new_jvms = _inline_cg->generate(jvms, NULL);
|
||||
if (new_jvms == NULL) return; // no change
|
||||
if (C->failing()) return;
|
||||
@ -431,6 +437,7 @@ class LateInlineMHCallGenerator : public LateInlineCallGenerator {
|
||||
|
||||
virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
|
||||
JVMState* new_jvms = LateInlineCallGenerator::generate(jvms, parent_parser);
|
||||
|
||||
if (_input_not_const) {
|
||||
// inlining won't be possible so no need to enqueue right now.
|
||||
call_node()->set_generator(this);
|
||||
@ -439,17 +446,14 @@ class LateInlineMHCallGenerator : public LateInlineCallGenerator {
|
||||
}
|
||||
return new_jvms;
|
||||
}
|
||||
|
||||
virtual void print_inlining_late(const char* msg) {
|
||||
if (!_input_not_const) return;
|
||||
LateInlineCallGenerator::print_inlining_late(msg);
|
||||
}
|
||||
};
|
||||
|
||||
bool LateInlineMHCallGenerator::do_late_inline_check(JVMState* jvms) {
|
||||
|
||||
CallGenerator* cg = for_method_handle_inline(jvms, _caller, method(), _input_not_const);
|
||||
|
||||
Compile::current()->print_inlining_update_delayed(this);
|
||||
|
||||
if (!_input_not_const) {
|
||||
_attempt++;
|
||||
}
|
||||
@ -479,8 +483,6 @@ class LateInlineStringCallGenerator : public LateInlineCallGenerator {
|
||||
|
||||
virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
|
||||
Compile *C = Compile::current();
|
||||
C->print_inlining_skip(this);
|
||||
|
||||
C->add_string_late_inline(this);
|
||||
|
||||
JVMState* new_jvms = DirectCallGenerator::generate(jvms, parent_parser);
|
||||
@ -502,7 +504,6 @@ class LateInlineBoxingCallGenerator : public LateInlineCallGenerator {
|
||||
|
||||
virtual JVMState* generate(JVMState* jvms, Parse* parent_parser) {
|
||||
Compile *C = Compile::current();
|
||||
C->print_inlining_skip(this);
|
||||
|
||||
C->add_boxing_late_inline(this);
|
||||
|
||||
@ -554,6 +555,8 @@ CallGenerator* CallGenerator::for_warm_call(WarmCallInfo* ci,
|
||||
|
||||
JVMState* WarmCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
|
||||
Compile* C = Compile::current();
|
||||
C->print_inlining_update(this);
|
||||
|
||||
if (C->log() != NULL) {
|
||||
C->log()->elem("warm_call bci='%d'", jvms->bci());
|
||||
}
|
||||
@ -632,6 +635,7 @@ CallGenerator* CallGenerator::for_predicted_call(ciKlass* predicted_receiver,
|
||||
|
||||
JVMState* PredictedCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
|
||||
GraphKit kit(jvms);
|
||||
kit.C->print_inlining_update(this);
|
||||
PhaseGVN& gvn = kit.gvn();
|
||||
// We need an explicit receiver null_check before checking its type.
|
||||
// We share a map with the caller, so his JVMS gets adjusted.
|
||||
@ -779,6 +783,9 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod*
|
||||
assert(cg == NULL || !cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
|
||||
if (cg != NULL && cg->is_inline())
|
||||
return cg;
|
||||
} else {
|
||||
const char* msg = "receiver not constant";
|
||||
if (PrintInlining) C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -844,11 +851,13 @@ CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod*
|
||||
// provide us with a type
|
||||
speculative_receiver_type = receiver_type->speculative_type();
|
||||
}
|
||||
|
||||
CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, speculative_receiver_type, true, true);
|
||||
assert(cg == NULL || !cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
|
||||
if (cg != NULL && cg->is_inline())
|
||||
return cg;
|
||||
} else {
|
||||
const char* msg = "member_name not constant";
|
||||
if (PrintInlining) C->print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -904,6 +913,7 @@ JVMState* PredictedIntrinsicGenerator::generate(JVMState* jvms, Parse* parent_pa
|
||||
if (kit.failing())
|
||||
return NULL; // might happen because of NodeCountInliningCutoff
|
||||
|
||||
kit.C->print_inlining_update(this);
|
||||
SafePointNode* slow_map = NULL;
|
||||
JVMState* slow_jvms;
|
||||
if (slow_ctl != NULL) {
|
||||
@ -1017,6 +1027,7 @@ CallGenerator::for_uncommon_trap(ciMethod* m,
|
||||
|
||||
JVMState* UncommonTrapCallGenerator::generate(JVMState* jvms, Parse* parent_parser) {
|
||||
GraphKit kit(jvms);
|
||||
kit.C->print_inlining_update(this);
|
||||
// Take the trap with arguments pushed on the stack. (Cf. null_check_receiver).
|
||||
int nargs = method()->arg_size();
|
||||
kit.inc_sp(nargs);
|
||||
|
||||
@ -662,6 +662,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
|
||||
_inlining_progress(false),
|
||||
_inlining_incrementally(false),
|
||||
_print_inlining_list(NULL),
|
||||
_print_inlining_stream(NULL),
|
||||
_print_inlining_idx(0),
|
||||
_preserve_jvm_state(0) {
|
||||
C = this;
|
||||
@ -723,9 +724,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
|
||||
PhaseGVN gvn(node_arena(), estimated_size);
|
||||
set_initial_gvn(&gvn);
|
||||
|
||||
if (print_inlining() || print_intrinsics()) {
|
||||
_print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer>(comp_arena(), 1, 1, PrintInliningBuffer());
|
||||
}
|
||||
print_inlining_init();
|
||||
{ // Scope for timing the parser
|
||||
TracePhase t3("parse", &_t_parser, true);
|
||||
|
||||
@ -967,6 +966,7 @@ Compile::Compile( ciEnv* ci_env,
|
||||
_inlining_progress(false),
|
||||
_inlining_incrementally(false),
|
||||
_print_inlining_list(NULL),
|
||||
_print_inlining_stream(NULL),
|
||||
_print_inlining_idx(0),
|
||||
_preserve_jvm_state(0),
|
||||
_allowed_reasons(0) {
|
||||
@ -2023,6 +2023,8 @@ void Compile::Optimize() {
|
||||
ResourceMark rm;
|
||||
int loop_opts_cnt;
|
||||
|
||||
print_inlining_reinit();
|
||||
|
||||
NOT_PRODUCT( verify_graph_edges(); )
|
||||
|
||||
print_method(PHASE_AFTER_PARSING);
|
||||
@ -3755,30 +3757,114 @@ void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n
|
||||
}
|
||||
}
|
||||
|
||||
void Compile::dump_inlining() {
|
||||
// The message about the current inlining is accumulated in
|
||||
// _print_inlining_stream and transfered into the _print_inlining_list
|
||||
// once we know whether inlining succeeds or not. For regular
|
||||
// inlining, messages are appended to the buffer pointed by
|
||||
// _print_inlining_idx in the _print_inlining_list. For late inlining,
|
||||
// a new buffer is added after _print_inlining_idx in the list. This
|
||||
// way we can update the inlining message for late inlining call site
|
||||
// when the inlining is attempted again.
|
||||
void Compile::print_inlining_init() {
|
||||
if (print_inlining() || print_intrinsics()) {
|
||||
_print_inlining_stream = new stringStream();
|
||||
_print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer>(comp_arena(), 1, 1, PrintInliningBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
void Compile::print_inlining_reinit() {
|
||||
if (print_inlining() || print_intrinsics()) {
|
||||
// Re allocate buffer when we change ResourceMark
|
||||
_print_inlining_stream = new stringStream();
|
||||
}
|
||||
}
|
||||
|
||||
void Compile::print_inlining_reset() {
|
||||
_print_inlining_stream->reset();
|
||||
}
|
||||
|
||||
void Compile::print_inlining_commit() {
|
||||
assert(print_inlining() || print_intrinsics(), "PrintInlining off?");
|
||||
// Transfer the message from _print_inlining_stream to the current
|
||||
// _print_inlining_list buffer and clear _print_inlining_stream.
|
||||
_print_inlining_list->at(_print_inlining_idx).ss()->write(_print_inlining_stream->as_string(), _print_inlining_stream->size());
|
||||
print_inlining_reset();
|
||||
}
|
||||
|
||||
void Compile::print_inlining_push() {
|
||||
// Add new buffer to the _print_inlining_list at current position
|
||||
_print_inlining_idx++;
|
||||
_print_inlining_list->insert_before(_print_inlining_idx, PrintInliningBuffer());
|
||||
}
|
||||
|
||||
Compile::PrintInliningBuffer& Compile::print_inlining_current() {
|
||||
return _print_inlining_list->at(_print_inlining_idx);
|
||||
}
|
||||
|
||||
void Compile::print_inlining_update(CallGenerator* cg) {
|
||||
if (print_inlining() || print_intrinsics()) {
|
||||
if (!cg->is_late_inline()) {
|
||||
if (print_inlining_current().cg() != NULL) {
|
||||
print_inlining_push();
|
||||
}
|
||||
print_inlining_commit();
|
||||
} else {
|
||||
if (print_inlining_current().cg() != cg &&
|
||||
(print_inlining_current().cg() != NULL ||
|
||||
print_inlining_current().ss()->size() != 0)) {
|
||||
print_inlining_push();
|
||||
}
|
||||
print_inlining_commit();
|
||||
print_inlining_current().set_cg(cg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Compile::print_inlining_move_to(CallGenerator* cg) {
|
||||
// We resume inlining at a late inlining call site. Locate the
|
||||
// corresponding inlining buffer so that we can update it.
|
||||
if (print_inlining()) {
|
||||
for (int i = 0; i < _print_inlining_list->length(); i++) {
|
||||
if (_print_inlining_list->adr_at(i)->cg() == cg) {
|
||||
_print_inlining_idx = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
|
||||
void Compile::print_inlining_update_delayed(CallGenerator* cg) {
|
||||
if (print_inlining()) {
|
||||
assert(_print_inlining_stream->size() > 0, "missing inlining msg");
|
||||
assert(print_inlining_current().cg() == cg, "wrong entry");
|
||||
// replace message with new message
|
||||
_print_inlining_list->at_put(_print_inlining_idx, PrintInliningBuffer());
|
||||
print_inlining_commit();
|
||||
print_inlining_current().set_cg(cg);
|
||||
}
|
||||
}
|
||||
|
||||
void Compile::print_inlining_assert_ready() {
|
||||
assert(!_print_inlining || _print_inlining_stream->size() == 0, "loosing data");
|
||||
}
|
||||
|
||||
void Compile::dump_inlining() {
|
||||
bool do_print_inlining = print_inlining() || print_intrinsics();
|
||||
if (do_print_inlining) {
|
||||
// Print inlining message for candidates that we couldn't inline
|
||||
// for lack of space or non constant receiver
|
||||
// for lack of space
|
||||
for (int i = 0; i < _late_inlines.length(); i++) {
|
||||
CallGenerator* cg = _late_inlines.at(i);
|
||||
cg->print_inlining_late("live nodes > LiveNodeCountInliningCutoff");
|
||||
}
|
||||
Unique_Node_List useful;
|
||||
useful.push(root());
|
||||
for (uint next = 0; next < useful.size(); ++next) {
|
||||
Node* n = useful.at(next);
|
||||
if (n->is_Call() && n->as_Call()->generator() != NULL && n->as_Call()->generator()->call_node() == n) {
|
||||
CallNode* call = n->as_Call();
|
||||
CallGenerator* cg = call->generator();
|
||||
cg->print_inlining_late("receiver not constant");
|
||||
}
|
||||
uint max = n->len();
|
||||
for ( uint i = 0; i < max; ++i ) {
|
||||
Node *m = n->in(i);
|
||||
if ( m == NULL ) continue;
|
||||
useful.push(m);
|
||||
if (!cg->is_mh_late_inline()) {
|
||||
const char* msg = "live nodes > LiveNodeCountInliningCutoff";
|
||||
if (do_print_inlining) {
|
||||
cg->print_inlining_late(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (do_print_inlining) {
|
||||
for (int i = 0; i < _print_inlining_list->length(); i++) {
|
||||
tty->print(_print_inlining_list->adr_at(i)->ss()->as_string());
|
||||
}
|
||||
|
||||
@ -416,6 +416,7 @@ class Compile : public Phase {
|
||||
void set_cg(CallGenerator* cg) { _cg = cg; }
|
||||
};
|
||||
|
||||
stringStream* _print_inlining_stream;
|
||||
GrowableArray<PrintInliningBuffer>* _print_inlining_list;
|
||||
int _print_inlining_idx;
|
||||
|
||||
@ -433,33 +434,24 @@ class Compile : public Phase {
|
||||
|
||||
void* _replay_inline_data; // Pointer to data loaded from file
|
||||
|
||||
void print_inlining_init();
|
||||
void print_inlining_reinit();
|
||||
void print_inlining_commit();
|
||||
void print_inlining_push();
|
||||
PrintInliningBuffer& print_inlining_current();
|
||||
|
||||
public:
|
||||
|
||||
outputStream* print_inlining_stream() const {
|
||||
return _print_inlining_list->adr_at(_print_inlining_idx)->ss();
|
||||
assert(print_inlining() || print_intrinsics(), "PrintInlining off?");
|
||||
return _print_inlining_stream;
|
||||
}
|
||||
|
||||
void print_inlining_skip(CallGenerator* cg) {
|
||||
if (_print_inlining) {
|
||||
_print_inlining_list->adr_at(_print_inlining_idx)->set_cg(cg);
|
||||
_print_inlining_idx++;
|
||||
_print_inlining_list->insert_before(_print_inlining_idx, PrintInliningBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
void print_inlining_insert(CallGenerator* cg) {
|
||||
if (_print_inlining) {
|
||||
for (int i = 0; i < _print_inlining_list->length(); i++) {
|
||||
if (_print_inlining_list->adr_at(i)->cg() == cg) {
|
||||
_print_inlining_list->insert_before(i+1, PrintInliningBuffer());
|
||||
_print_inlining_idx = i+1;
|
||||
_print_inlining_list->adr_at(i)->set_cg(NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
void print_inlining_update(CallGenerator* cg);
|
||||
void print_inlining_update_delayed(CallGenerator* cg);
|
||||
void print_inlining_move_to(CallGenerator* cg);
|
||||
void print_inlining_assert_ready();
|
||||
void print_inlining_reset();
|
||||
|
||||
void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) {
|
||||
stringStream ss;
|
||||
|
||||
@ -294,6 +294,8 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool
|
||||
// There was no special inlining tactic, or it bailed out.
|
||||
// Use a more generic tactic, like a simple call.
|
||||
if (call_does_dispatch) {
|
||||
const char* msg = "virtual call";
|
||||
if (PrintInlining) print_inlining(callee, jvms->depth() - 1, jvms->bci(), msg);
|
||||
return CallGenerator::for_virtual_call(callee, vtable_index);
|
||||
} else {
|
||||
// Class Hierarchy Analysis or Type Profile reveals a unique target,
|
||||
@ -396,6 +398,8 @@ void Parse::do_call() {
|
||||
// our contribution to it is cleaned up right here.
|
||||
kill_dead_locals();
|
||||
|
||||
C->print_inlining_assert_ready();
|
||||
|
||||
// Set frequently used booleans
|
||||
const bool is_virtual = bc() == Bytecodes::_invokevirtual;
|
||||
const bool is_virtual_or_interface = is_virtual || bc() == Bytecodes::_invokeinterface;
|
||||
@ -531,7 +535,8 @@ void Parse::do_call() {
|
||||
// intrinsic was expecting to optimize. Should always be possible to
|
||||
// get a normal java call that may inline in that case
|
||||
cg = C->call_generator(cg->method(), vtable_index, call_does_dispatch, jvms, try_inline, prof_factor(), speculative_receiver_type, /* allow_intrinsics= */ false);
|
||||
if ((new_jvms = cg->generate(jvms, this)) == NULL) {
|
||||
new_jvms = cg->generate(jvms, this);
|
||||
if (new_jvms == NULL) {
|
||||
guarantee(failing(), "call failed to generate: calls should work");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -620,6 +620,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms, Parse* parent_parser) {
|
||||
}
|
||||
// Push the result from the inlined method onto the stack.
|
||||
kit.push_result();
|
||||
C->print_inlining_update(this);
|
||||
return kit.transfer_exceptions_into_jvms();
|
||||
}
|
||||
|
||||
@ -637,6 +638,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms, Parse* parent_parser) {
|
||||
}
|
||||
}
|
||||
C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed);
|
||||
C->print_inlining_update(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -438,6 +438,30 @@ WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobjec
|
||||
return (mh->queued_for_compilation() || nm != NULL);
|
||||
WB_END
|
||||
|
||||
class VM_WhiteBoxOperation : public VM_Operation {
|
||||
public:
|
||||
VM_WhiteBoxOperation() { }
|
||||
VMOp_Type type() const { return VMOp_WhiteBoxOperation; }
|
||||
bool allow_nested_vm_operations() const { return true; }
|
||||
};
|
||||
|
||||
class AlwaysFalseClosure : public BoolObjectClosure {
|
||||
public:
|
||||
bool do_object_b(oop p) { return false; }
|
||||
};
|
||||
|
||||
static AlwaysFalseClosure always_false;
|
||||
|
||||
class VM_WhiteBoxCleanMethodData : public VM_WhiteBoxOperation {
|
||||
public:
|
||||
VM_WhiteBoxCleanMethodData(MethodData* mdo) : _mdo(mdo) { }
|
||||
void doit() {
|
||||
_mdo->clean_method_data(&always_false);
|
||||
}
|
||||
private:
|
||||
MethodData* _mdo;
|
||||
};
|
||||
|
||||
WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
|
||||
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
|
||||
CHECK_JNI_EXCEPTION(env);
|
||||
@ -453,6 +477,8 @@ WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
mdo->set_arg_modified(i, 0);
|
||||
}
|
||||
VM_WhiteBoxCleanMethodData op(mdo);
|
||||
VMThread::execute(&op);
|
||||
}
|
||||
|
||||
mh->clear_not_c1_compilable();
|
||||
|
||||
@ -307,6 +307,9 @@ static ObsoleteFlag obsolete_jvm_flags[] = {
|
||||
JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) },
|
||||
#endif // PRODUCT
|
||||
{ "UseVMInterruptibleIO", JDK_Version::jdk(8), JDK_Version::jdk(9) },
|
||||
{ "UseBoundThreads", JDK_Version::jdk(9), JDK_Version::jdk(10) },
|
||||
{ "DefaultThreadPriority", JDK_Version::jdk(9), JDK_Version::jdk(10) },
|
||||
{ "NoYieldsInMicrolock", JDK_Version::jdk(9), JDK_Version::jdk(10) },
|
||||
{ NULL, JDK_Version(0), JDK_Version(0) }
|
||||
};
|
||||
|
||||
@ -2078,17 +2081,6 @@ bool Arguments::check_vm_args_consistency() {
|
||||
// Note: Needs platform-dependent factoring.
|
||||
bool status = true;
|
||||
|
||||
// Allow both -XX:-UseStackBanging and -XX:-UseBoundThreads in non-product
|
||||
// builds so the cost of stack banging can be measured.
|
||||
#if (defined(PRODUCT) && defined(SOLARIS))
|
||||
if (!UseBoundThreads && !UseStackBanging) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"-UseStackBanging conflicts with -UseBoundThreads\n");
|
||||
|
||||
status = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (TLABRefillWasteFraction == 0) {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"TLABRefillWasteFraction should be a denominator, "
|
||||
|
||||
@ -929,6 +929,10 @@ void os::print_cpu_info(outputStream* st) {
|
||||
}
|
||||
|
||||
void os::print_date_and_time(outputStream *st) {
|
||||
const int secs_per_day = 86400;
|
||||
const int secs_per_hour = 3600;
|
||||
const int secs_per_min = 60;
|
||||
|
||||
time_t tloc;
|
||||
(void)time(&tloc);
|
||||
st->print("time: %s", ctime(&tloc)); // ctime adds newline.
|
||||
@ -937,7 +941,17 @@ void os::print_date_and_time(outputStream *st) {
|
||||
// NOTE: It tends to crash after a SEGV if we want to printf("%f",...) in
|
||||
// Linux. Must be a bug in glibc ? Workaround is to round "t" to int
|
||||
// before printf. We lost some precision, but who cares?
|
||||
st->print_cr("elapsed time: %d seconds", (int)t);
|
||||
int eltime = (int)t; // elapsed time in seconds
|
||||
|
||||
// print elapsed time in a human-readable format:
|
||||
int eldays = eltime / secs_per_day;
|
||||
int day_secs = eldays * secs_per_day;
|
||||
int elhours = (eltime - day_secs) / secs_per_hour;
|
||||
int hour_secs = elhours * secs_per_hour;
|
||||
int elmins = (eltime - day_secs - hour_secs) / secs_per_min;
|
||||
int minute_secs = elmins * secs_per_min;
|
||||
int elsecs = (eltime - day_secs - hour_secs - minute_secs);
|
||||
st->print_cr("elapsed time: %d seconds (%dd %dh %dm %ds)", eltime, eldays, elhours, elmins, elsecs);
|
||||
}
|
||||
|
||||
// moved from debug.cpp (used to be find()) but still called from there
|
||||
|
||||
@ -450,8 +450,8 @@ class os: AllStatic {
|
||||
// yield that can be used in lieu of blocking.
|
||||
} ;
|
||||
static YieldResult NakedYield () ;
|
||||
static void yield_all(int attempts = 0); // Yields to all other threads including lower priority
|
||||
static void loop_breaker(int attempts); // called from within tight loops to possibly influence time-sharing
|
||||
static void yield_all(); // Yields to all other threads including lower priority
|
||||
// (for the default scheduling policy)
|
||||
static OSReturn set_priority(Thread* thread, ThreadPriority priority);
|
||||
static OSReturn get_priority(const Thread* const thread, ThreadPriority& priority);
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -319,7 +319,7 @@ void SafepointSynchronize::begin() {
|
||||
if (steps < DeferThrSuspendLoopCount) {
|
||||
os::NakedYield() ;
|
||||
} else {
|
||||
os::yield_all(steps) ;
|
||||
os::yield_all() ;
|
||||
// Alternately, the VM thread could transiently depress its scheduling priority or
|
||||
// transiently increase the priority of the tardy mutator(s).
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -924,12 +924,6 @@ JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t p
|
||||
JRT_END
|
||||
#endif // !PRODUCT
|
||||
|
||||
|
||||
JRT_ENTRY(void, SharedRuntime::yield_all(JavaThread* thread, int attempts))
|
||||
os::yield_all(attempts);
|
||||
JRT_END
|
||||
|
||||
|
||||
JRT_ENTRY_NO_ASYNC(void, SharedRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
|
||||
assert(obj->is_oop(), "must be a valid oop");
|
||||
assert(obj->klass()->has_finalizer(), "shouldn't be here otherwise");
|
||||
@ -1268,8 +1262,6 @@ methodHandle SharedRuntime::resolve_sub_helper(JavaThread *thread,
|
||||
}
|
||||
#endif
|
||||
if (is_virtual) {
|
||||
nmethod* nm = callee_nm;
|
||||
if (nm == NULL) CodeCache::find_blob(caller_frame.pc());
|
||||
CompiledIC* inline_cache = CompiledIC_before(caller_nm, caller_frame.pc());
|
||||
if (inline_cache->is_clean()) {
|
||||
inline_cache->set_to_monomorphic(virtual_call_info);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2014, 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
|
||||
@ -253,9 +253,6 @@ class SharedRuntime: AllStatic {
|
||||
// bytecode tracing is only used by the TraceBytecodes
|
||||
static intptr_t trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2) PRODUCT_RETURN0;
|
||||
|
||||
// Used to back off a spin lock that is under heavy contention
|
||||
static void yield_all(JavaThread* thread, int attempts = 0);
|
||||
|
||||
static oop retrieve_receiver( Symbol* sig, frame caller );
|
||||
|
||||
static void register_finalizer(JavaThread* thread, oopDesc* obj);
|
||||
|
||||
@ -321,24 +321,38 @@ void interpretedVFrame::set_locals(StackValueCollection* values) const {
|
||||
}
|
||||
}
|
||||
|
||||
StackValueCollection* interpretedVFrame::expressions() const {
|
||||
int length = fr().interpreter_frame_expression_stack_size();
|
||||
if (method()->is_native()) {
|
||||
// If the method is native, there is no expression stack
|
||||
length = 0;
|
||||
StackValueCollection* interpretedVFrame::expressions() const {
|
||||
|
||||
InterpreterOopMap oop_mask;
|
||||
|
||||
if (!method()->is_native()) {
|
||||
// Get oopmap describing oops and int for current bci
|
||||
if (TraceDeoptimization && Verbose) {
|
||||
methodHandle m_h(method());
|
||||
OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
|
||||
} else {
|
||||
method()->mask_for(bci(), &oop_mask);
|
||||
}
|
||||
}
|
||||
|
||||
// If the bci is a call instruction, i.e. any of the invoke* instructions,
|
||||
// the InterpreterOopMap does not include expression/operand stack liveness
|
||||
// info in the oop_mask/bit_mask. This can lead to a discrepancy of what
|
||||
// is actually on the expression stack compared to what is given by the
|
||||
// oop_map. We need to use the length reported in the oop_map.
|
||||
int length = oop_mask.expression_stack_size();
|
||||
|
||||
assert(fr().interpreter_frame_expression_stack_size() >= length,
|
||||
"error in expression stack!");
|
||||
|
||||
StackValueCollection* result = new StackValueCollection(length);
|
||||
|
||||
if (0 == length) {
|
||||
return result;
|
||||
}
|
||||
|
||||
int nof_locals = method()->max_locals();
|
||||
StackValueCollection* result = new StackValueCollection(length);
|
||||
|
||||
InterpreterOopMap oop_mask;
|
||||
// Get oopmap describing oops and int for current bci
|
||||
if (TraceDeoptimization && Verbose) {
|
||||
methodHandle m_h(method());
|
||||
OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
|
||||
} else {
|
||||
method()->mask_for(bci(), &oop_mask);
|
||||
}
|
||||
// handle expressions
|
||||
for(int i=0; i < length; i++) {
|
||||
// Find stack location
|
||||
|
||||
@ -305,6 +305,9 @@ void VMThread::run() {
|
||||
_terminate_lock->notify();
|
||||
}
|
||||
|
||||
// Thread destructor usually does this.
|
||||
ThreadLocalStorage::set_thread(NULL);
|
||||
|
||||
// Deletion must be done synchronously by the JNI DestroyJavaVM thread
|
||||
// so that the VMThread deletion completes before the main thread frees
|
||||
// up the CodeHeap.
|
||||
|
||||
@ -97,6 +97,7 @@
|
||||
template(Exit) \
|
||||
template(LinuxDllLoad) \
|
||||
template(RotateGCLog) \
|
||||
template(WhiteBoxOperation) \
|
||||
|
||||
class VM_Operation: public CHeapObj<mtInternal> {
|
||||
public:
|
||||
|
||||
142
hotspot/test/compiler/profiling/spectrapredefineclass/Agent.java
Normal file
142
hotspot/test/compiler/profiling/spectrapredefineclass/Agent.java
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.security.*;
|
||||
import java.lang.instrument.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
|
||||
class A {
|
||||
void m() {
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
void m() {
|
||||
}
|
||||
}
|
||||
|
||||
class C extends A {
|
||||
void m() {
|
||||
}
|
||||
}
|
||||
|
||||
class Test {
|
||||
|
||||
static public void m() throws Exception {
|
||||
for (int i = 0; i < 20000; i++) {
|
||||
m1(a);
|
||||
}
|
||||
for (int i = 0; i < 4; i++) {
|
||||
m1(b);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean m1(A a) {
|
||||
boolean res = Agent.m2(a);
|
||||
return res;
|
||||
}
|
||||
|
||||
static public A a = new A();
|
||||
static public B b = new B();
|
||||
static public C c = new C();
|
||||
}
|
||||
|
||||
public class Agent implements ClassFileTransformer {
|
||||
|
||||
|
||||
static class MemoryChunk {
|
||||
MemoryChunk other;
|
||||
long[] array;
|
||||
MemoryChunk(MemoryChunk other) {
|
||||
other = other;
|
||||
array = new long[1024 * 1024 * 1024];
|
||||
}
|
||||
}
|
||||
|
||||
static public boolean m2(A a) {
|
||||
boolean res = false;
|
||||
if (a.getClass() == B.class) {
|
||||
a.m();
|
||||
} else {
|
||||
res = true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static public void main(String[] args) throws Exception {
|
||||
// Create speculative trap entries
|
||||
Test.m();
|
||||
|
||||
String nameOfRunningVM = ManagementFactory.getRuntimeMXBean().getName();
|
||||
int p = nameOfRunningVM.indexOf('@');
|
||||
String pid = nameOfRunningVM.substring(0, p);
|
||||
|
||||
// Make the nmethod go away
|
||||
for (int i = 0; i < 10; i++) {
|
||||
System.gc();
|
||||
}
|
||||
|
||||
// Redefine class
|
||||
try {
|
||||
VirtualMachine vm = VirtualMachine.attach(pid);
|
||||
vm.loadAgent(System.getProperty("test.classes",".") + "/agent.jar", "");
|
||||
vm.detach();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Test.m();
|
||||
// GC will hit dead method pointer
|
||||
for (int i = 0; i < 10; i++) {
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized byte[] transform(final ClassLoader classLoader,
|
||||
final String className,
|
||||
Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain,
|
||||
byte[] classfileBuffer) {
|
||||
System.out.println("Transforming class " + className);
|
||||
return classfileBuffer;
|
||||
}
|
||||
|
||||
public static void redefine(String agentArgs, Instrumentation instrumentation, Class to_redefine) {
|
||||
|
||||
try {
|
||||
instrumentation.retransformClasses(to_redefine);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void agentmain(String agentArgs, Instrumentation instrumentation) throws Exception {
|
||||
Agent transformer = new Agent();
|
||||
instrumentation.addTransformer(transformer, true);
|
||||
|
||||
redefine(agentArgs, instrumentation, Test.class);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user