mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-11 22:19:43 +00:00
Merge
This commit is contained in:
commit
fbe3993153
1
.hgtags
1
.hgtags
@ -280,3 +280,4 @@ f0c5e4b732da823bdaa4184133675f384e7cd68d jdk9-b33
|
||||
a137992d750c72f6f944f341aa19b0d0d96afe0c jdk9-b35
|
||||
41df50e7303daf73c0d661ef601c4fe250915de5 jdk9-b36
|
||||
b409bc51bc23cfd51f2bd04ea919ec83535af9d0 jdk9-b37
|
||||
948cceef81ba4cb34bc233e7cc5952951ff04e88 jdk9-b38
|
||||
|
||||
@ -280,3 +280,4 @@ e4ba01b726e263953ae129be37c94de6ed145b1d jdk9-b33
|
||||
c173ba994245380fb11ef077d1e59823386840eb jdk9-b35
|
||||
201d4e235d597a25a2d3ee1404394789ba386119 jdk9-b36
|
||||
723a67b0c442391447b1d8aad8b249d06d1032e8 jdk9-b37
|
||||
d42c0a90afc3c66ca87543076ec9aafd4b4680de jdk9-b38
|
||||
|
||||
@ -684,8 +684,6 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
|
||||
AC_SUBST(CONF_NAME, $CONF_NAME)
|
||||
AC_SUBST(OUTPUT_ROOT, $OUTPUT_ROOT)
|
||||
|
||||
# Most of the probed defines are put into config.h
|
||||
AC_CONFIG_HEADERS([$OUTPUT_ROOT/config.h:$AUTOCONF_DIR/config.h.in])
|
||||
# The spec.gmk file contains all variables for the make system.
|
||||
AC_CONFIG_FILES([$OUTPUT_ROOT/spec.gmk:$AUTOCONF_DIR/spec.gmk.in])
|
||||
# The hotspot-spec.gmk file contains legacy variables for the hotspot make system.
|
||||
@ -694,8 +692,6 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
|
||||
AC_CONFIG_FILES([$OUTPUT_ROOT/bootcycle-spec.gmk:$AUTOCONF_DIR/bootcycle-spec.gmk.in])
|
||||
# The compare.sh is used to compare the build output to other builds.
|
||||
AC_CONFIG_FILES([$OUTPUT_ROOT/compare.sh:$AUTOCONF_DIR/compare.sh.in])
|
||||
# Spec.sh is currently used by compare-objects.sh
|
||||
AC_CONFIG_FILES([$OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in])
|
||||
# The generated Makefile knows where the spec.gmk is and where the source is.
|
||||
# You can run make from the OUTPUT_ROOT, or from the top-level Makefile
|
||||
# which will look for generated configurations
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -131,7 +131,7 @@ yum_help() {
|
||||
pulse)
|
||||
PKGHANDLER_COMMAND="sudo yum install pulseaudio-libs-devel" ;;
|
||||
x11)
|
||||
PKGHANDLER_COMMAND="sudo yum install libXtst-devel libXt-devel libXrender-devel" ;;
|
||||
PKGHANDLER_COMMAND="sudo yum install libXtst-devel libXt-devel libXrender-devel libXi-devel" ;;
|
||||
ccache)
|
||||
PKGHANDLER_COMMAND="sudo yum install ccache" ;;
|
||||
esac
|
||||
|
||||
@ -91,85 +91,93 @@ AC_DEFUN_ONCE([LIB_SETUP_X11],
|
||||
# Check for X Windows
|
||||
#
|
||||
|
||||
# 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$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"
|
||||
if test "x$X11_NOT_NEEDED" = xyes; then
|
||||
if test "x${with_x}" != x; then
|
||||
AC_MSG_WARN([X11 is not used, so --with-x is ignored])
|
||||
fi
|
||||
X_CFLAGS=
|
||||
X_LIBS=
|
||||
else
|
||||
# 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$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 "$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"
|
||||
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
|
||||
fi
|
||||
|
||||
# Now let autoconf do it's magic
|
||||
AC_PATH_X
|
||||
AC_PATH_XTRA
|
||||
# Now let autoconf do it's magic
|
||||
AC_PATH_X
|
||||
AC_PATH_XTRA
|
||||
|
||||
# AC_PATH_XTRA creates X_LIBS and sometimes adds -R flags. When cross compiling
|
||||
# this doesn't make sense so we remove it.
|
||||
if test "x$COMPILE_TYPE" = xcross; then
|
||||
X_LIBS=`$ECHO $X_LIBS | $SED 's/-R \{0,1\}[[^ ]]*//g'`
|
||||
fi
|
||||
# AC_PATH_XTRA creates X_LIBS and sometimes adds -R flags. When cross compiling
|
||||
# this doesn't make sense so we remove it.
|
||||
if test "x$COMPILE_TYPE" = xcross; then
|
||||
X_LIBS=`$ECHO $X_LIBS | $SED 's/-R \{0,1\}[[^ ]]*//g'`
|
||||
fi
|
||||
|
||||
if test "x$no_x" = xyes && test "x$X11_NOT_NEEDED" != xyes; then
|
||||
HELP_MSG_MISSING_DEPENDENCY([x11])
|
||||
AC_MSG_ERROR([Could not find X11 libraries. $HELP_MSG])
|
||||
fi
|
||||
if test "x$no_x" = xyes; then
|
||||
HELP_MSG_MISSING_DEPENDENCY([x11])
|
||||
AC_MSG_ERROR([Could not find X11 libraries. $HELP_MSG])
|
||||
fi
|
||||
|
||||
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
|
||||
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_LANG_PUSH(C)
|
||||
OLD_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $SYSROOT_CFLAGS $X_CFLAGS"
|
||||
AC_LANG_PUSH(C)
|
||||
OLD_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $SYSROOT_CFLAGS $X_CFLAGS"
|
||||
|
||||
# Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10
|
||||
AC_CHECK_HEADERS([X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h],
|
||||
[X11_A_OK=yes],
|
||||
[X11_A_OK=no; break],
|
||||
[
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/Xutil.h>
|
||||
]
|
||||
)
|
||||
# Need to include Xlib.h and Xutil.h to avoid "present but cannot be compiled" warnings on Solaris 10
|
||||
AC_CHECK_HEADERS([X11/extensions/shape.h X11/extensions/Xrender.h X11/extensions/XTest.h X11/Intrinsic.h],
|
||||
[X11_HEADERS_OK=yes],
|
||||
[X11_HEADERS_OK=no; break],
|
||||
[
|
||||
# include <X11/Xlib.h>
|
||||
# include <X11/Xutil.h>
|
||||
]
|
||||
)
|
||||
|
||||
# If XLinearGradient isn't available in Xrender.h, signal that it needs to be
|
||||
# defined in libawt_xawt.
|
||||
AC_MSG_CHECKING([if XlinearGradient is defined in Xrender.h])
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <X11/extensions/Xrender.h>]],
|
||||
[[XLinearGradient x;]])],
|
||||
[AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([no])
|
||||
X_CFLAGS="$X_CFLAGS -DSOLARIS10_NO_XRENDER_STRUCTS"])
|
||||
if test "x$X11_HEADERS_OK" = xno; then
|
||||
HELP_MSG_MISSING_DEPENDENCY([x11])
|
||||
AC_MSG_ERROR([Could not find all X11 headers (shape.h Xrender.h XTest.h Intrinsic.h). $HELP_MSG])
|
||||
fi
|
||||
|
||||
CFLAGS="$OLD_CFLAGS"
|
||||
AC_LANG_POP(C)
|
||||
# If XLinearGradient isn't available in Xrender.h, signal that it needs to be
|
||||
# defined in libawt_xawt.
|
||||
AC_MSG_CHECKING([if XlinearGradient is defined in Xrender.h])
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <X11/extensions/Xrender.h>]],
|
||||
[[XLinearGradient x;]])],
|
||||
[AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([no])
|
||||
X_CFLAGS="$X_CFLAGS -DSOLARIS10_NO_XRENDER_STRUCTS"])
|
||||
|
||||
if test "x$X11_A_OK" = xno && test "x$X11_NOT_NEEDED" != xyes; then
|
||||
HELP_MSG_MISSING_DEPENDENCY([x11])
|
||||
AC_MSG_ERROR([Could not find all X11 headers (shape.h Xrender.h XTest.h Intrinsic.h). $HELP_MSG])
|
||||
fi
|
||||
CFLAGS="$OLD_CFLAGS"
|
||||
AC_LANG_POP(C)
|
||||
fi # X11_NOT_NEEDED
|
||||
|
||||
AC_SUBST(X_CFLAGS)
|
||||
AC_SUBST(X_LIBS)
|
||||
@ -264,7 +272,7 @@ AC_DEFUN([LIB_BUILD_FREETYPE],
|
||||
fi
|
||||
# Now check if configure found a version of 'msbuild.exe'
|
||||
if test "x$BUILD_FREETYPE" = xyes && test "x$MSBUILD" == x ; then
|
||||
AC_MSG_WARN([Can't find an msbuild.exe executable (you may try to install .NET 4.0) - ignoring --with-freetype-src])
|
||||
AC_MSG_WARN([Can not find an msbuild.exe executable (you may try to install .NET 4.0) - ignoring --with-freetype-src])
|
||||
BUILD_FREETYPE=no
|
||||
fi
|
||||
|
||||
@ -335,27 +343,50 @@ AC_DEFUN([LIB_CHECK_POTENTIAL_FREETYPE],
|
||||
POTENTIAL_FREETYPE_LIB_PATH="$2"
|
||||
METHOD="$3"
|
||||
|
||||
# First check if the files exists.
|
||||
if test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then
|
||||
# We found an arbitrary include file. That's a good sign.
|
||||
AC_MSG_NOTICE([Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD])
|
||||
FOUND_FREETYPE=yes
|
||||
# Let's start with an optimistic view of the world :-)
|
||||
FOUND_FREETYPE=yes
|
||||
|
||||
FREETYPE_LIB_NAME="${LIBRARY_PREFIX}freetype${SHARED_LIBRARY_SUFFIX}"
|
||||
if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then
|
||||
AC_MSG_NOTICE([Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location.])
|
||||
# First look for the canonical freetype main include file ft2build.h.
|
||||
if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then
|
||||
# Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite.
|
||||
POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2"
|
||||
if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then
|
||||
# Fail.
|
||||
FOUND_FREETYPE=no
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$FOUND_FREETYPE" = xyes; then
|
||||
# Include file found, let's continue the sanity check.
|
||||
AC_MSG_NOTICE([Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD])
|
||||
|
||||
# Reset to default value
|
||||
FREETYPE_BASE_NAME=freetype
|
||||
FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}"
|
||||
if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then
|
||||
if test "x$OPENJDK_TARGET_OS" = xmacosx \
|
||||
&& test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then
|
||||
# On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check
|
||||
# for the .6 version explicitly.
|
||||
FREETYPE_BASE_NAME=freetype.6
|
||||
FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}"
|
||||
AC_MSG_NOTICE([Compensating for missing symlink by using version 6 explicitly])
|
||||
else
|
||||
AC_MSG_NOTICE([Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location.])
|
||||
FOUND_FREETYPE=no
|
||||
fi
|
||||
else
|
||||
if test "x$OPENJDK_TARGET_OS" = xwindows; then
|
||||
# On Windows, we will need both .lib and .dll file.
|
||||
if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/freetype.lib"; then
|
||||
AC_MSG_NOTICE([Could not find $POTENTIAL_FREETYPE_LIB_PATH/freetype.lib. Ignoring location.])
|
||||
if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then
|
||||
AC_MSG_NOTICE([Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location.])
|
||||
FOUND_FREETYPE=no
|
||||
fi
|
||||
elif test "x$OPENJDK_TARGET_OS" = xsolaris \
|
||||
&& test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then
|
||||
# Found lib in isa dir, use that instead.
|
||||
POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR"
|
||||
AC_MSG_NOTICE([Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@ -392,6 +423,8 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
|
||||
AC_ARG_ENABLE(freetype-bundling, [AS_HELP_STRING([--disable-freetype-bundling],
|
||||
[disable bundling of the freetype library with the build result @<:@enabled on Windows or when using --with-freetype, disabled otherwise@:>@])])
|
||||
|
||||
# Need to specify explicitly since it needs to be overridden on some versions of macosx
|
||||
FREETYPE_BASE_NAME=freetype
|
||||
FREETYPE_CFLAGS=
|
||||
FREETYPE_LIBS=
|
||||
FREETYPE_BUNDLE_LIB_PATH=
|
||||
@ -575,9 +608,9 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
|
||||
if test "x$FREETYPE_LIBS" = x; then
|
||||
BASIC_FIXUP_PATH(FREETYPE_LIB_PATH)
|
||||
if test "x$OPENJDK_TARGET_OS" = xwindows; then
|
||||
FREETYPE_LIBS="$FREETYPE_LIB_PATH/freetype.lib"
|
||||
FREETYPE_LIBS="$FREETYPE_LIB_PATH/$FREETYPE_BASE_NAME.lib"
|
||||
else
|
||||
FREETYPE_LIBS="-L$FREETYPE_LIB_PATH -lfreetype"
|
||||
FREETYPE_LIBS="-L$FREETYPE_LIB_PATH -l$FREETYPE_BASE_NAME"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
CAT="@CAT@"
|
||||
CD=cd
|
||||
CP="@CP@"
|
||||
DIFF="@DIFF@"
|
||||
ECHO="@ECHO@"
|
||||
FIND="@FIND@"
|
||||
GREP="@GREP@"
|
||||
RM="@RM@"
|
||||
SED="@SED@"
|
||||
|
||||
POST_STRIP_CMD="@POST_STRIP_CMD@"
|
||||
@ -1,77 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2012, 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.
|
||||
#
|
||||
|
||||
# The boot_cycle.sh script performs two complete image builds (no javadoc though....)
|
||||
# where the second build uses the first build as the boot jdk.
|
||||
#
|
||||
# This is useful to verify that the build is self hoisting and assists
|
||||
# in flushing out bugs. You can follow up with compare_objects.sh to check
|
||||
# that the two boot_cycle_?/images/j2sdk are identical. They should be.
|
||||
#
|
||||
# Usage:
|
||||
# Specify the configure arguments to boot_cycle.sh, for example:
|
||||
#
|
||||
# sh common/bin/boot_cycle.sh --enable-debug --with-jvm-variants=server
|
||||
#
|
||||
# The same arguments will be used for both builds, except of course --with-boot-jdk
|
||||
# that will be adjusted to boot_cycle_1 for the second build.
|
||||
|
||||
SCRIPT_DIR=`pwd`/`dirname $0`
|
||||
ROOT_DIR=`(cd $SCRIPT_DIR/../.. ; pwd)`
|
||||
BUILD_DIR=$ROOT_DIR/build
|
||||
mkdir -p $BUILD_DIR
|
||||
AUTOCONF_DIR=`(cd $SCRIPT_DIR/../autoconf ; pwd)`
|
||||
BOOT_CYCLE_1_DIR=$BUILD_DIR/boot_cycle_1
|
||||
BOOT_CYCLE_2_DIR=$BUILD_DIR/boot_cycle_2
|
||||
|
||||
# Create the boot cycle dirs in the build directory.
|
||||
mkdir -p $BOOT_CYCLE_1_DIR
|
||||
mkdir -p $BOOT_CYCLE_2_DIR
|
||||
|
||||
cd $BOOT_CYCLE_1_DIR
|
||||
# Configure!
|
||||
sh $AUTOCONF_DIR/configure "$@"
|
||||
# Now build!
|
||||
make images
|
||||
|
||||
if ! test -x $BOOT_CYCLE_1_DIR/images/j2sdk-image/bin/java ; then
|
||||
echo Failed to build the executable $BOOT_CYCLE_1_DIR/images/j2sdk-image/bin/java
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $BOOT_CYCLE_2_DIR
|
||||
# Pickup the configure arguments, but drop any --with-boot-jdk=....
|
||||
# and add the correct --with-boot-jdk=...boot_cycle_1... at the end.
|
||||
ARGUMENTS="`cat $BOOT_CYCLE_1_DIR/configure-arguments|sed 's/--with-boot-jdk=[^ ]*//'` --with-boot-jdk=$BOOT_CYCLE_1_DIR/images/j2sdk-image"
|
||||
# Configure using these adjusted arguments.
|
||||
sh $AUTOCONF_DIR/configure $ARGUMENTS
|
||||
# Now build!
|
||||
make images
|
||||
|
||||
if ! test -x $BOOT_CYCLE_2_DIR/images/j2sdk-image/bin/java ; then
|
||||
echo Failed to build the final executable $BOOT_CYCLE_2_DIR/images/j2sdk-image/bin/java
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@ -1,235 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2012, 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.
|
||||
#
|
||||
|
||||
# MANUAL
|
||||
#
|
||||
# ./common/bin/compare-objects.sh old_jdk_build_dir new_jdk_build_dir
|
||||
#
|
||||
# Compares object files
|
||||
#
|
||||
|
||||
if [ "x$1" = "x-h" ] || [ "x$1" = "x--help" ] || [ "x$1" == "x" ]; then
|
||||
echo "bash ./common/bin/compare-objects.sh old_jdk_build_dir new_jdk_build_dir <pattern>"
|
||||
echo ""
|
||||
echo "Compare object files"
|
||||
echo ""
|
||||
exit 10
|
||||
fi
|
||||
|
||||
#######
|
||||
#
|
||||
# List of files (grep patterns) that are ignored
|
||||
#
|
||||
# 1) hotspot object files
|
||||
IGNORE="-e hotspot"
|
||||
|
||||
# 2) various build artifacts: sizer.32.o sizer.64.o dummyodbc.o
|
||||
# these are produced during build and then e.g run to produce other data
|
||||
# i.e not directly put into build => safe to ignore
|
||||
IGNORE="${IGNORE} -e sizer.32.o -e sizer.64.o"
|
||||
IGNORE="${IGNORE} -e dummyodbc.o"
|
||||
IGNORE="${IGNORE} -e genSolarisConstants.o"
|
||||
IGNORE="${IGNORE} -e genUnixConstants.o"
|
||||
|
||||
OLD="$1"
|
||||
NEW="$2"
|
||||
shift; shift
|
||||
PATTERN="$*"
|
||||
|
||||
if [ -f $NEW/spec.sh ]; then
|
||||
. $NEW/spec.sh
|
||||
elif [ -f $NEW/../../spec.sh ]; then
|
||||
. $NEW/../../spec.sh
|
||||
elif [ -f $OLD/spec.sh ]; then
|
||||
. $OLD/spec.sh
|
||||
elif [ -f $OLD/../../spec.sh ]; then
|
||||
. $OLD/../../spec.sh
|
||||
else
|
||||
echo "Unable to find spec.sh"
|
||||
echo "Giving up"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export COMPARE_ROOT=/tmp/cimages.$USER/objects
|
||||
mkdir -p $COMPARE_ROOT
|
||||
|
||||
(${CD} $OLD && ${FIND} . -name '*.o') > $COMPARE_ROOT/list.old
|
||||
(${CD} $NEW && ${FIND} . -name '*.o') > $COMPARE_ROOT/list.new
|
||||
|
||||
# On macosx JobjC is build in both i386 and x86_64 variant (universial binary)
|
||||
# but new build only builds the x86_64
|
||||
# Remove the 386 variants from comparison...to avoid "false" positives
|
||||
${GREP} -v 'JObjC.dst/Objects-normal/i386' $COMPARE_ROOT/list.old > $COMPARE_ROOT/list.old.new
|
||||
${CP} $COMPARE_ROOT/list.old $COMPARE_ROOT/list.old.full
|
||||
${CP} $COMPARE_ROOT/list.old.new $COMPARE_ROOT/list.old
|
||||
|
||||
findnew() {
|
||||
arg_1=$1
|
||||
arg_2=$2
|
||||
|
||||
# special case 1 unpack-cmd => unpackexe
|
||||
arg_1=`${ECHO} $arg_1 | ${SED} 's!unpack-cmd!unpackexe!g'`
|
||||
arg_2=`${ECHO} $arg_2 | ${SED} 's!unpack-cmd!unpackexe!g'`
|
||||
|
||||
# special case 2 /JObjC.dst/ => /libjobjc/
|
||||
arg_1=`${ECHO} $arg_1 | ${SED} 's!/JObjC.dst/!/libjobjc/!g'`
|
||||
arg_2=`${ECHO} $arg_2 | ${SED} 's!/JObjC.dst/!/libjobjc/!g'`
|
||||
|
||||
full=`${ECHO} $arg_1 | ${SED} 's!\.!\\\.!g'`
|
||||
medium=`${ECHO} $arg_1 | ${SED} 's!.*/\([^/]*/[^/]*\)!\1!'`
|
||||
short=`${ECHO} $arg_2 | ${SED} 's!\.!\\\.!g'`
|
||||
if [ "`${GREP} -c "/$full" $COMPARE_ROOT/list.new`" -eq 1 ]
|
||||
then
|
||||
${ECHO} $NEW/$arg_1
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "`${GREP} -c "$medium" $COMPARE_ROOT/list.new`" -eq 1 ]
|
||||
then
|
||||
${GREP} "$medium" $COMPARE_ROOT/list.new
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "`${GREP} -c "/$short" $COMPARE_ROOT/list.new`" -eq 1 ]
|
||||
then
|
||||
${GREP} "/$short" $COMPARE_ROOT/list.new
|
||||
return
|
||||
fi
|
||||
|
||||
# old style has "dir" before obj{64}
|
||||
dir=`${ECHO} $arg_1 | ${SED} 's!.*/\([^/]*\)/obj[64]*.*!\1!g'`
|
||||
if [ -n "$dir" -a "$dir" != "$arg_1" ]
|
||||
then
|
||||
if [ "`${GREP} $dir $COMPARE_ROOT/list.new | ${GREP} -c "/$short"`" -eq 1 ]
|
||||
then
|
||||
${GREP} $dir $COMPARE_ROOT/list.new | ${GREP} "/$short"
|
||||
return
|
||||
fi
|
||||
|
||||
# Try with lib$dir/
|
||||
if [ "`${GREP} "lib$dir/" $COMPARE_ROOT/list.new | ${GREP} -c "/$short"`" -eq 1 ]
|
||||
then
|
||||
${GREP} "lib$dir/" $COMPARE_ROOT/list.new | ${GREP} "/$short"
|
||||
return
|
||||
fi
|
||||
|
||||
# Try with $dir_objs
|
||||
if [ "`${GREP} "${dir}_objs" $COMPARE_ROOT/list.new | ${GREP} -c "/$short"`" -eq 1 ]
|
||||
then
|
||||
${GREP} "${dir}_objs" $COMPARE_ROOT/list.new | ${GREP} "/$short"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# check for some specifics...
|
||||
for i in demo hotspot jobjc
|
||||
do
|
||||
if [ "`${ECHO} $full | ${GREP} -c $i`" -gt 0 ]
|
||||
then
|
||||
if [ "`${GREP} $i $COMPARE_ROOT/list.new | ${GREP} -c "/$short"`" -eq 1 ]
|
||||
then
|
||||
${GREP} $i $COMPARE_ROOT/list.new | ${GREP} "/$short"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# check for specific demo
|
||||
demo=`${ECHO} $arg_1 | ${SED} 's!.*/demo/jvmti/\([^/]*\)/.*!\1!g'`
|
||||
if [ -n "$demo" -a "$dir" != "$demo" ]
|
||||
then
|
||||
if [ "`${GREP} $demo $COMPARE_ROOT/list.new | ${GREP} -c "/$short"`" -eq 1 ]
|
||||
then
|
||||
${GREP} $demo $COMPARE_ROOT/list.new | ${GREP} "/$short"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
compare() {
|
||||
old=$1
|
||||
new=$2
|
||||
${DIFF} $old $new > /dev/null
|
||||
res=$?
|
||||
if [ $res -eq 0 ]
|
||||
then
|
||||
${ECHO} 0
|
||||
return
|
||||
fi
|
||||
|
||||
# check if stripped objects gives equality
|
||||
${CP} $old $COMPARE_ROOT/`basename $old`.old
|
||||
${CP} $new $COMPARE_ROOT/`basename $old`.new
|
||||
${POST_STRIP_CMD} $COMPARE_ROOT/`basename $old`.old $COMPARE_ROOT/`basename $old`.new > /dev/null 2>&1
|
||||
${DIFF} $COMPARE_ROOT/`basename $old`.old $COMPARE_ROOT/`basename $old`.new > /dev/null
|
||||
res=$?
|
||||
${RM} $COMPARE_ROOT/`basename $old`.old $COMPARE_ROOT/`basename $old`.new
|
||||
if [ $res -eq 0 ]
|
||||
then
|
||||
${ECHO} S
|
||||
return
|
||||
fi
|
||||
|
||||
name=`basename $1 | ${SED} 's!\.o!!'`
|
||||
cntold=`strings $old | ${GREP} -c $name`
|
||||
cntnew=`strings $new | ${GREP} -c $name`
|
||||
|
||||
if [ $cntold -gt 0 -a $cntnew -gt 0 ]
|
||||
then
|
||||
${ECHO} F
|
||||
return
|
||||
fi
|
||||
|
||||
${ECHO} 1
|
||||
}
|
||||
|
||||
for F in `${CAT} $COMPARE_ROOT/list.old`
|
||||
do
|
||||
if [ "${IGNORE}" ] && [ "`${ECHO} $F | ${GREP} ${IGNORE}`" ]
|
||||
then
|
||||
#
|
||||
# skip ignored files
|
||||
#
|
||||
continue;
|
||||
fi
|
||||
|
||||
if [ "$PATTERN" ] && [ `${ECHO} $F | ${GREP} -c $PATTERN` -eq 0 ]
|
||||
then
|
||||
continue;
|
||||
fi
|
||||
|
||||
f=`basename $F`
|
||||
o=$OLD/$F
|
||||
n=`findnew $F $f`
|
||||
|
||||
if [ "$n" ]
|
||||
then
|
||||
n="$NEW/$n"
|
||||
${ECHO} `compare $o $n` : $f : $o : $n
|
||||
else
|
||||
${ECHO} "- : $f : $o "
|
||||
fi
|
||||
done
|
||||
@ -280,3 +280,4 @@ cfdac5887952c2dd73c73a1d8d9aa880d0539bbf jdk9-b33
|
||||
9bc2dbd3dfb8c9fa88e00056b8b93a81ee6d306e jdk9-b35
|
||||
ffd90c81d4ef9d94d880fc852e2fc482ecd9b374 jdk9-b36
|
||||
7e9add74ad50841fb39dae75db56374aefa1de4c jdk9-b37
|
||||
8acf056126e819cf536eef02aee0f61f207a6b52 jdk9-b38
|
||||
|
||||
@ -440,3 +440,4 @@ af46576a8d7cb4003028b8ee8bf408cfe227315b jdk9-b32
|
||||
438cb613151c4bd290bb732697517cba1cafcb04 jdk9-b35
|
||||
464ab653fbb17eb518d8ef60f8df301de7ef00d0 jdk9-b36
|
||||
b1c2dd843f247a1db19e1e85eb62ca405f72dc26 jdk9-b37
|
||||
c363a8b87e477ee45d6d3cb2a36cb365141bc596 jdk9-b38
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.jvm.hotspot.runtime;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
|
||||
public class CodeCacheSweeperThread extends JavaThread {
|
||||
public CodeCacheSweeperThread(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isJavaThread() { return false; }
|
||||
public boolean isHiddenFromExternalView() { return true; }
|
||||
public boolean isCodeCacheSweeperThread() { return true; }
|
||||
|
||||
}
|
||||
@ -118,9 +118,10 @@ public class JavaThread extends Thread {
|
||||
return VM.getVM().getThreads().createJavaThreadWrapper(threadAddr);
|
||||
}
|
||||
|
||||
/** NOTE: for convenience, this differs in definition from the
|
||||
underlying VM. Only "pure" JavaThreads return true;
|
||||
CompilerThreads and JVMDIDebuggerThreads return false. FIXME:
|
||||
/** NOTE: for convenience, this differs in definition from the underlying VM.
|
||||
Only "pure" JavaThreads return true; CompilerThreads, the CodeCacheSweeperThread,
|
||||
JVMDIDebuggerThreads return false.
|
||||
FIXME:
|
||||
consider encapsulating platform-specific functionality in an
|
||||
object instead of using inheritance (which is the primary reason
|
||||
we can't traverse CompilerThreads, etc; didn't want to have, for
|
||||
|
||||
@ -111,14 +111,15 @@ public class Thread extends VMObject {
|
||||
return allocatedBytesField.getValue(addr);
|
||||
}
|
||||
|
||||
public boolean isVMThread() { return false; }
|
||||
public boolean isJavaThread() { return false; }
|
||||
public boolean isCompilerThread() { return false; }
|
||||
public boolean isHiddenFromExternalView() { return false; }
|
||||
public boolean isJvmtiAgentThread() { return false; }
|
||||
public boolean isWatcherThread() { return false; }
|
||||
public boolean isVMThread() { return false; }
|
||||
public boolean isJavaThread() { return false; }
|
||||
public boolean isCompilerThread() { return false; }
|
||||
public boolean isCodeCacheSweeperThread() { return false; }
|
||||
public boolean isHiddenFromExternalView() { return false; }
|
||||
public boolean isJvmtiAgentThread() { return false; }
|
||||
public boolean isWatcherThread() { return false; }
|
||||
public boolean isConcurrentMarkSweepThread() { return false; }
|
||||
public boolean isServiceThread() { return false; }
|
||||
public boolean isServiceThread() { return false; }
|
||||
|
||||
/** Memory operations */
|
||||
public void oopsDo(AddressVisitor oopVisitor) {
|
||||
|
||||
@ -120,6 +120,7 @@ public class Threads {
|
||||
virtualConstructor.addMapping("JavaThread", JavaThread.class);
|
||||
if (!VM.getVM().isCore()) {
|
||||
virtualConstructor.addMapping("CompilerThread", CompilerThread.class);
|
||||
virtualConstructor.addMapping("CodeCacheSweeperThread", CodeCacheSweeperThread.class);
|
||||
}
|
||||
// for now, use JavaThread itself. fix it later with appropriate class if needed
|
||||
virtualConstructor.addMapping("SurrogateLockerThread", JavaThread.class);
|
||||
@ -164,7 +165,7 @@ public class Threads {
|
||||
return thread;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to deduce type of thread from address " + threadAddr +
|
||||
" (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread, or SurrogateLockerThread)", e);
|
||||
" (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread, SurrogateLockerThread, or CodeCacheSweeperThread)", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,7 +202,7 @@ public class Threads {
|
||||
public List getPendingThreads(ObjectMonitor monitor) {
|
||||
List pendingThreads = new ArrayList();
|
||||
for (JavaThread thread = first(); thread != null; thread = thread.next()) {
|
||||
if (thread.isCompilerThread()) {
|
||||
if (thread.isCompilerThread() || thread.isCodeCacheSweeperThread()) {
|
||||
continue;
|
||||
}
|
||||
ObjectMonitor pending = thread.getCurrentPendingMonitor();
|
||||
|
||||
@ -836,6 +836,7 @@ vmType2Class["InterpreterCodelet"] = sapkg.interpreter.InterpreterCodelet;
|
||||
// Java Threads
|
||||
vmType2Class["JavaThread"] = sapkg.runtime.JavaThread;
|
||||
vmType2Class["CompilerThread"] = sapkg.runtime.CompilerThread;
|
||||
vmType2Class["CodeCacheSweeperThread"] = sapkg.runtime.CodeCacheSweeperThread;
|
||||
vmType2Class["SurrogateLockerThread"] = sapkg.runtime.JavaThread;
|
||||
vmType2Class["DebuggerThread"] = sapkg.runtime.DebuggerThread;
|
||||
|
||||
|
||||
@ -158,7 +158,7 @@ LD=link.exe
|
||||
!endif
|
||||
LD_FLAGS= $(LD_FLAGS) kernel32.lib user32.lib gdi32.lib winspool.lib \
|
||||
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
|
||||
uuid.lib Wsock32.lib winmm.lib /nologo /machine:$(MACHINE) /opt:REF \
|
||||
uuid.lib Wsock32.lib winmm.lib version.lib /nologo /machine:$(MACHINE) /opt:REF \
|
||||
/opt:ICF,8
|
||||
!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
|
||||
LD_FLAGS= $(LD_FLAGS) /map /debug
|
||||
|
||||
@ -237,7 +237,7 @@ IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(
|
||||
// handle arguments
|
||||
// Warning: We use reg arg slot 00 temporarily to return the RegArgSignature
|
||||
// back to the code that pops the arguments into the CPU registers
|
||||
SlowSignatureHandler(m, (address)from, m->is_static() ? to+2 : to+1, to).iterate(UCONST64(-1));
|
||||
SlowSignatureHandler(m, (address)from, m->is_static() ? to+2 : to+1, to).iterate((uint64_t)CONST64(-1));
|
||||
// return result handler
|
||||
return Interpreter::result_handler(m->result_type());
|
||||
IRT_END
|
||||
|
||||
@ -60,10 +60,10 @@ static jlong* double_quadword(jlong *adr, jlong lo, jlong hi) {
|
||||
static jlong fp_signmask_pool[(4+1)*2]; // 4*128bits(data) + 128bits(alignment)
|
||||
|
||||
// Static initialization during VM startup.
|
||||
static jlong *float_signmask_pool = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF));
|
||||
static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF));
|
||||
static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000));
|
||||
static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000));
|
||||
static jlong *float_signmask_pool = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF));
|
||||
static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF));
|
||||
static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], (jlong)UCONST64(0x8000000080000000), (jlong)UCONST64(0x8000000080000000));
|
||||
static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], (jlong)UCONST64(0x8000000000000000), (jlong)UCONST64(0x8000000000000000));
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1597,7 +1597,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
__ movl(rdx, 0x80000000);
|
||||
__ xorl(rax, rax);
|
||||
#else
|
||||
__ mov64(rax, CONST64(0x8000000000000000));
|
||||
__ mov64(rax, UCONST64(0x8000000000000000));
|
||||
#endif // _LP64
|
||||
__ jmp(do_return);
|
||||
|
||||
|
||||
@ -135,7 +135,7 @@ IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread
|
||||
methodHandle m(thread, (Method*)method);
|
||||
assert(m->is_native(), "sanity check");
|
||||
// handle arguments
|
||||
SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1));
|
||||
SlowSignatureHandler(m, (address)from, to + 1).iterate((uint64_t)CONST64(-1));
|
||||
// return result handler
|
||||
return Interpreter::result_handler(m->result_type());
|
||||
IRT_END
|
||||
|
||||
@ -487,7 +487,7 @@ IRT_ENTRY(address,
|
||||
assert(m->is_native(), "sanity check");
|
||||
|
||||
// handle arguments
|
||||
SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1));
|
||||
SlowSignatureHandler(m, (address)from, to + 1).iterate((uint64_t)CONST64(-1));
|
||||
|
||||
// return result handler
|
||||
return Interpreter::result_handler(m->result_type());
|
||||
|
||||
@ -155,7 +155,7 @@ IRT_ENTRY(address,
|
||||
|
||||
intptr_t *buf = (intptr_t *) stack->alloc(required_words * wordSize);
|
||||
SlowSignatureHandlerGenerator sshg(methodHandle(thread, method), buf);
|
||||
sshg.generate(UCONST64(-1));
|
||||
sshg.generate((uint64_t)CONST64(-1));
|
||||
|
||||
SignatureHandler *handler = sshg.handler();
|
||||
handler->finalize();
|
||||
|
||||
@ -1641,7 +1641,8 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
char* rp = realpath((char *)dlinfo.dli_fname, buf);
|
||||
assert(rp != NULL, "error in realpath(): maybe the 'path' argument is too long?");
|
||||
|
||||
strcpy(saved_jvm_path, buf);
|
||||
strncpy(saved_jvm_path, buf, sizeof(saved_jvm_path));
|
||||
saved_jvm_path[sizeof(saved_jvm_path) - 1] = '\0';
|
||||
}
|
||||
|
||||
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
|
||||
@ -3829,11 +3830,6 @@ jint os::init_2(void) {
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
// this is called at the end of vm_initialization
|
||||
void os::init_3(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark the polling page as unreadable
|
||||
void os::make_polling_page_unreadable(void) {
|
||||
if (!guard_memory((char*)_polling_page, Aix::page_size())) {
|
||||
|
||||
@ -506,6 +506,7 @@ static void cleanup_sharedmem_resources(const char* dirname) {
|
||||
|
||||
if (!is_directory_secure(dirname)) {
|
||||
// the directory is not a secure directory
|
||||
os::closedir(dirp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -853,6 +854,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
|
||||
//
|
||||
if (!is_directory_secure(dirname)) {
|
||||
FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
|
||||
if (luser != user) {
|
||||
FREE_C_HEAP_ARRAY(char, luser, mtInternal);
|
||||
}
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
||||
"Process not found");
|
||||
}
|
||||
|
||||
@ -1875,6 +1875,7 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
}
|
||||
|
||||
strncpy(saved_jvm_path, buf, MAXPATHLEN);
|
||||
saved_jvm_path[MAXPATHLEN - 1] = '\0';
|
||||
}
|
||||
|
||||
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
|
||||
@ -3635,9 +3636,6 @@ jint os::init_2(void) {
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
// this is called at the end of vm_initialization
|
||||
void os::init_3(void) { }
|
||||
|
||||
// Mark the polling page as unreadable
|
||||
void os::make_polling_page_unreadable(void) {
|
||||
if (!guard_memory((char*)_polling_page, Bsd::page_size())) {
|
||||
@ -4118,7 +4116,18 @@ void os::pause() {
|
||||
}
|
||||
|
||||
|
||||
// Refer to the comments in os_solaris.cpp park-unpark.
|
||||
// Refer to the comments in os_solaris.cpp park-unpark. The next two
|
||||
// comment paragraphs are worth repeating here:
|
||||
//
|
||||
// Assumption:
|
||||
// Only one parker can exist on an event, which is why we allocate
|
||||
// them per-thread. Multiple unparkers can coexist.
|
||||
//
|
||||
// _Event serves as a restricted-range semaphore.
|
||||
// -1 : thread is blocked, i.e. there is a waiter
|
||||
// 0 : neutral: thread is running or ready,
|
||||
// could have been signaled after a wait started
|
||||
// 1 : signaled - thread is running or ready
|
||||
//
|
||||
// Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
|
||||
// hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
|
||||
@ -4203,6 +4212,11 @@ static struct timespec* compute_abstime(struct timespec* abstime,
|
||||
}
|
||||
|
||||
void os::PlatformEvent::park() { // AKA "down()"
|
||||
// Transitions for _Event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
// 0 => -1 : block; then set _Event to 0 before returning
|
||||
|
||||
// Invariant: Only the thread associated with the Event/PlatformEvent
|
||||
// may call park().
|
||||
// TODO: assert that _Assoc != NULL or _Assoc == Self
|
||||
@ -4240,6 +4254,11 @@ void os::PlatformEvent::park() { // AKA "down()"
|
||||
}
|
||||
|
||||
int os::PlatformEvent::park(jlong millis) {
|
||||
// Transitions for _Event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
// 0 => -1 : block; then set _Event to 0 before returning
|
||||
|
||||
guarantee(_nParked == 0, "invariant");
|
||||
|
||||
int v;
|
||||
@ -4303,11 +4322,11 @@ int os::PlatformEvent::park(jlong millis) {
|
||||
|
||||
void os::PlatformEvent::unpark() {
|
||||
// Transitions for _Event:
|
||||
// 0 :=> 1
|
||||
// 1 :=> 1
|
||||
// -1 :=> either 0 or 1; must signal target thread
|
||||
// That is, we can safely transition _Event from -1 to either
|
||||
// 0 or 1.
|
||||
// 0 => 1 : just return
|
||||
// 1 => 1 : just return
|
||||
// -1 => either 0 or 1; must signal target thread
|
||||
// That is, we can safely transition _Event from -1 to either
|
||||
// 0 or 1.
|
||||
// See also: "Semaphores in Plan 9" by Mullender & Cox
|
||||
//
|
||||
// Note: Forcing a transition from "-1" to "1" on an unpark() means
|
||||
@ -4330,15 +4349,16 @@ void os::PlatformEvent::unpark() {
|
||||
status = pthread_mutex_unlock(_mutex);
|
||||
assert_status(status == 0, status, "mutex_unlock");
|
||||
if (AnyWaiters != 0) {
|
||||
// Note that we signal() *after* dropping the lock for "immortal" Events.
|
||||
// This is safe and avoids a common class of futile wakeups. In rare
|
||||
// circumstances this can cause a thread to return prematurely from
|
||||
// cond_{timed}wait() but the spurious wakeup is benign and the victim
|
||||
// will simply re-test the condition and re-park itself.
|
||||
// This provides particular benefit if the underlying platform does not
|
||||
// provide wait morphing.
|
||||
status = pthread_cond_signal(_cond);
|
||||
assert_status(status == 0, status, "cond_signal");
|
||||
}
|
||||
|
||||
// Note that we signal() _after dropping the lock for "immortal" Events.
|
||||
// This is safe and avoids a common class of futile wakeups. In rare
|
||||
// circumstances this can cause a thread to return prematurely from
|
||||
// cond_{timed}wait() but the spurious wakeup is benign and the victim will
|
||||
// simply re-test the condition and re-park itself.
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -506,6 +506,7 @@ static void cleanup_sharedmem_resources(const char* dirname) {
|
||||
|
||||
if (!is_directory_secure(dirname)) {
|
||||
// the directory is not a secure directory
|
||||
os::closedir(dirp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -872,6 +873,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
|
||||
//
|
||||
if (!is_directory_secure(dirname)) {
|
||||
FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
|
||||
if (luser != user) {
|
||||
FREE_C_HEAP_ARRAY(char, luser, mtInternal);
|
||||
}
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
||||
"Process not found");
|
||||
}
|
||||
|
||||
@ -163,35 +163,6 @@ static pthread_mutex_t dl_mutex;
|
||||
// Declarations
|
||||
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
|
||||
|
||||
#ifdef JAVASE_EMBEDDED
|
||||
class MemNotifyThread: public Thread {
|
||||
friend class VMStructs;
|
||||
public:
|
||||
virtual void run();
|
||||
|
||||
private:
|
||||
static MemNotifyThread* _memnotify_thread;
|
||||
int _fd;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
MemNotifyThread(int fd);
|
||||
|
||||
// Tester
|
||||
bool is_memnotify_thread() const { return true; }
|
||||
|
||||
// Printing
|
||||
char* name() const { return (char*)"Linux MemNotify Thread"; }
|
||||
|
||||
// Returns the single instance of the MemNotifyThread
|
||||
static MemNotifyThread* memnotify_thread() { return _memnotify_thread; }
|
||||
|
||||
// Create and start the single instance of MemNotifyThread
|
||||
static void start();
|
||||
};
|
||||
#endif // JAVASE_EMBEDDED
|
||||
|
||||
// utility functions
|
||||
|
||||
static int SR_initialize();
|
||||
@ -384,7 +355,10 @@ void os::init_system_properties_values() {
|
||||
|
||||
// Found the full path to libjvm.so.
|
||||
// Now cut the path to <java_home>/jre if we can.
|
||||
*(strrchr(buf, '/')) = '\0'; // Get rid of /libjvm.so.
|
||||
pslash = strrchr(buf, '/');
|
||||
if (pslash != NULL) {
|
||||
*pslash = '\0'; // Get rid of /libjvm.so.
|
||||
}
|
||||
pslash = strrchr(buf, '/');
|
||||
if (pslash != NULL) {
|
||||
*pslash = '\0'; // Get rid of /{client|server|hotspot}.
|
||||
@ -1223,7 +1197,7 @@ void os::Linux::capture_initial_stack(size_t max_size) {
|
||||
i = 0;
|
||||
if (s) {
|
||||
// Skip blank chars
|
||||
do s++; while (isspace(*s));
|
||||
do { s++; } while (s && isspace(*s));
|
||||
|
||||
#define _UFM UINTX_FORMAT
|
||||
#define _DFM INTX_FORMAT
|
||||
@ -2372,6 +2346,9 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
|
||||
// Check the current module name "libjvm.so".
|
||||
p = strrchr(buf, '/');
|
||||
if (p == NULL) {
|
||||
return;
|
||||
}
|
||||
assert(strstr(p, "/libjvm") == p, "invalid library name");
|
||||
|
||||
rp = realpath(java_home_var, buf);
|
||||
@ -2405,6 +2382,7 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
}
|
||||
|
||||
strncpy(saved_jvm_path, buf, MAXPATHLEN);
|
||||
saved_jvm_path[MAXPATHLEN - 1] = '\0';
|
||||
}
|
||||
|
||||
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
|
||||
@ -4866,17 +4844,6 @@ jint os::init_2(void) {
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
// this is called at the end of vm_initialization
|
||||
void os::init_3(void) {
|
||||
#ifdef JAVASE_EMBEDDED
|
||||
// Start the MemNotifyThread
|
||||
if (LowMemoryProtection) {
|
||||
MemNotifyThread::start();
|
||||
}
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Mark the polling page as unreadable
|
||||
void os::make_polling_page_unreadable(void) {
|
||||
if (!guard_memory((char*)_polling_page, Linux::page_size())) {
|
||||
@ -5103,9 +5070,38 @@ int os::open(const char *path, int oflag, int mode) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
int fd;
|
||||
|
||||
fd = ::open64(path, oflag, mode);
|
||||
// All file descriptors that are opened in the Java process and not
|
||||
// specifically destined for a subprocess should have the close-on-exec
|
||||
// flag set. If we don't set it, then careless 3rd party native code
|
||||
// might fork and exec without closing all appropriate file descriptors
|
||||
// (e.g. as we do in closeDescriptors in UNIXProcess.c), and this in
|
||||
// turn might:
|
||||
//
|
||||
// - cause end-of-file to fail to be detected on some file
|
||||
// descriptors, resulting in mysterious hangs, or
|
||||
//
|
||||
// - might cause an fopen in the subprocess to fail on a system
|
||||
// suffering from bug 1085341.
|
||||
//
|
||||
// (Yes, the default setting of the close-on-exec flag is a Unix
|
||||
// design flaw)
|
||||
//
|
||||
// See:
|
||||
// 1085341: 32-bit stdio routines should support file descriptors >255
|
||||
// 4843136: (process) pipe file descriptor from Runtime.exec not being closed
|
||||
// 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
|
||||
//
|
||||
// Modern Linux kernels (after 2.6.23 2007) support O_CLOEXEC with open().
|
||||
// O_CLOEXEC is preferable to using FD_CLOEXEC on an open file descriptor
|
||||
// because it saves a system call and removes a small window where the flag
|
||||
// is unset. On ancient Linux kernels the O_CLOEXEC flag will be ignored
|
||||
// and we fall back to using FD_CLOEXEC (see below).
|
||||
#ifdef O_CLOEXEC
|
||||
oflag |= O_CLOEXEC;
|
||||
#endif
|
||||
|
||||
int fd = ::open64(path, oflag, mode);
|
||||
if (fd == -1) return -1;
|
||||
|
||||
//If the open succeeded, the file might still be a directory
|
||||
@ -5126,32 +5122,17 @@ int os::open(const char *path, int oflag, int mode) {
|
||||
}
|
||||
}
|
||||
|
||||
// All file descriptors that are opened in the JVM and not
|
||||
// specifically destined for a subprocess should have the
|
||||
// close-on-exec flag set. If we don't set it, then careless 3rd
|
||||
// party native code might fork and exec without closing all
|
||||
// appropriate file descriptors (e.g. as we do in closeDescriptors in
|
||||
// UNIXProcess.c), and this in turn might:
|
||||
//
|
||||
// - cause end-of-file to fail to be detected on some file
|
||||
// descriptors, resulting in mysterious hangs, or
|
||||
//
|
||||
// - might cause an fopen in the subprocess to fail on a system
|
||||
// suffering from bug 1085341.
|
||||
//
|
||||
// (Yes, the default setting of the close-on-exec flag is a Unix
|
||||
// design flaw)
|
||||
//
|
||||
// See:
|
||||
// 1085341: 32-bit stdio routines should support file descriptors >255
|
||||
// 4843136: (process) pipe file descriptor from Runtime.exec not being closed
|
||||
// 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
|
||||
//
|
||||
#ifdef FD_CLOEXEC
|
||||
{
|
||||
// Validate that the use of the O_CLOEXEC flag on open above worked.
|
||||
// With recent kernels, we will perform this check exactly once.
|
||||
static sig_atomic_t O_CLOEXEC_is_known_to_work = 0;
|
||||
if (!O_CLOEXEC_is_known_to_work) {
|
||||
int flags = ::fcntl(fd, F_GETFD);
|
||||
if (flags != -1) {
|
||||
::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
|
||||
if ((flags & FD_CLOEXEC) != 0)
|
||||
O_CLOEXEC_is_known_to_work = 1;
|
||||
else
|
||||
::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -5340,7 +5321,7 @@ static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
|
||||
if (s == NULL) return -1;
|
||||
|
||||
// Skip blank chars
|
||||
do s++; while (isspace(*s));
|
||||
do { s++; } while (s && isspace(*s));
|
||||
|
||||
count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
|
||||
&cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
|
||||
@ -5401,7 +5382,18 @@ void os::pause() {
|
||||
}
|
||||
|
||||
|
||||
// Refer to the comments in os_solaris.cpp park-unpark.
|
||||
// Refer to the comments in os_solaris.cpp park-unpark. The next two
|
||||
// comment paragraphs are worth repeating here:
|
||||
//
|
||||
// Assumption:
|
||||
// Only one parker can exist on an event, which is why we allocate
|
||||
// them per-thread. Multiple unparkers can coexist.
|
||||
//
|
||||
// _Event serves as a restricted-range semaphore.
|
||||
// -1 : thread is blocked, i.e. there is a waiter
|
||||
// 0 : neutral: thread is running or ready,
|
||||
// could have been signaled after a wait started
|
||||
// 1 : signaled - thread is running or ready
|
||||
//
|
||||
// Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
|
||||
// hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
|
||||
@ -5500,6 +5492,11 @@ static struct timespec* compute_abstime(timespec* abstime, jlong millis) {
|
||||
}
|
||||
|
||||
void os::PlatformEvent::park() { // AKA "down()"
|
||||
// Transitions for _Event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
// 0 => -1 : block; then set _Event to 0 before returning
|
||||
|
||||
// Invariant: Only the thread associated with the Event/PlatformEvent
|
||||
// may call park().
|
||||
// TODO: assert that _Assoc != NULL or _Assoc == Self
|
||||
@ -5537,6 +5534,11 @@ void os::PlatformEvent::park() { // AKA "down()"
|
||||
}
|
||||
|
||||
int os::PlatformEvent::park(jlong millis) {
|
||||
// Transitions for _Event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
// 0 => -1 : block; then set _Event to 0 before returning
|
||||
|
||||
guarantee(_nParked == 0, "invariant");
|
||||
|
||||
int v;
|
||||
@ -5600,11 +5602,11 @@ int os::PlatformEvent::park(jlong millis) {
|
||||
|
||||
void os::PlatformEvent::unpark() {
|
||||
// Transitions for _Event:
|
||||
// 0 :=> 1
|
||||
// 1 :=> 1
|
||||
// -1 :=> either 0 or 1; must signal target thread
|
||||
// That is, we can safely transition _Event from -1 to either
|
||||
// 0 or 1.
|
||||
// 0 => 1 : just return
|
||||
// 1 => 1 : just return
|
||||
// -1 => either 0 or 1; must signal target thread
|
||||
// That is, we can safely transition _Event from -1 to either
|
||||
// 0 or 1.
|
||||
// See also: "Semaphores in Plan 9" by Mullender & Cox
|
||||
//
|
||||
// Note: Forcing a transition from "-1" to "1" on an unpark() means
|
||||
@ -5627,15 +5629,16 @@ void os::PlatformEvent::unpark() {
|
||||
status = pthread_mutex_unlock(_mutex);
|
||||
assert_status(status == 0, status, "mutex_unlock");
|
||||
if (AnyWaiters != 0) {
|
||||
// Note that we signal() *after* dropping the lock for "immortal" Events.
|
||||
// This is safe and avoids a common class of futile wakeups. In rare
|
||||
// circumstances this can cause a thread to return prematurely from
|
||||
// cond_{timed}wait() but the spurious wakeup is benign and the victim
|
||||
// will simply re-test the condition and re-park itself.
|
||||
// This provides particular benefit if the underlying platform does not
|
||||
// provide wait morphing.
|
||||
status = pthread_cond_signal(_cond);
|
||||
assert_status(status == 0, status, "cond_signal");
|
||||
}
|
||||
|
||||
// Note that we signal() _after dropping the lock for "immortal" Events.
|
||||
// This is safe and avoids a common class of futile wakeups. In rare
|
||||
// circumstances this can cause a thread to return prematurely from
|
||||
// cond_{timed}wait() but the spurious wakeup is benign and the victim will
|
||||
// simply re-test the condition and re-park itself.
|
||||
}
|
||||
|
||||
|
||||
@ -5997,82 +6000,6 @@ int os::get_core_path(char* buffer, size_t bufferSize) {
|
||||
return strlen(buffer);
|
||||
}
|
||||
|
||||
#ifdef JAVASE_EMBEDDED
|
||||
//
|
||||
// A thread to watch the '/dev/mem_notify' device, which will tell us when the OS is running low on memory.
|
||||
//
|
||||
MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL;
|
||||
|
||||
// ctor
|
||||
//
|
||||
MemNotifyThread::MemNotifyThread(int fd): Thread() {
|
||||
assert(memnotify_thread() == NULL, "we can only allocate one MemNotifyThread");
|
||||
_fd = fd;
|
||||
|
||||
if (os::create_thread(this, os::os_thread)) {
|
||||
_memnotify_thread = this;
|
||||
os::set_priority(this, NearMaxPriority);
|
||||
os::start_thread(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Where all the work gets done
|
||||
//
|
||||
void MemNotifyThread::run() {
|
||||
assert(this == memnotify_thread(), "expected the singleton MemNotifyThread");
|
||||
|
||||
// Set up the select arguments
|
||||
fd_set rfds;
|
||||
if (_fd != -1) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(_fd, &rfds);
|
||||
}
|
||||
|
||||
// Now wait for the mem_notify device to wake up
|
||||
while (1) {
|
||||
// Wait for the mem_notify device to signal us..
|
||||
int rc = select(_fd+1, _fd != -1 ? &rfds : NULL, NULL, NULL, NULL);
|
||||
if (rc == -1) {
|
||||
perror("select!\n");
|
||||
break;
|
||||
} else if (rc) {
|
||||
//ssize_t free_before = os::available_memory();
|
||||
//tty->print ("Notified: Free: %dK \n",os::available_memory()/1024);
|
||||
|
||||
// The kernel is telling us there is not much memory left...
|
||||
// try to do something about that
|
||||
|
||||
// If we are not already in a GC, try one.
|
||||
if (!Universe::heap()->is_gc_active()) {
|
||||
Universe::heap()->collect(GCCause::_allocation_failure);
|
||||
|
||||
//ssize_t free_after = os::available_memory();
|
||||
//tty->print ("Post-Notify: Free: %dK\n",free_after/1024);
|
||||
//tty->print ("GC freed: %dK\n", (free_after - free_before)/1024);
|
||||
}
|
||||
// We might want to do something like the following if we find the GC's are not helping...
|
||||
// Universe::heap()->size_policy()->set_gc_time_limit_exceeded(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See if the /dev/mem_notify device exists, and if so, start a thread to monitor it.
|
||||
//
|
||||
void MemNotifyThread::start() {
|
||||
int fd;
|
||||
fd = open("/dev/mem_notify", O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (memnotify_thread() == NULL) {
|
||||
new MemNotifyThread(fd);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // JAVASE_EMBEDDED
|
||||
|
||||
|
||||
/////////////// Unit tests ///////////////
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
@ -506,6 +506,7 @@ static void cleanup_sharedmem_resources(const char* dirname) {
|
||||
|
||||
if (!is_directory_secure(dirname)) {
|
||||
// the directory is not a secure directory
|
||||
os::closedir(dirp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -872,6 +873,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
|
||||
//
|
||||
if (!is_directory_secure(dirname)) {
|
||||
FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
|
||||
if (luser != user) {
|
||||
FREE_C_HEAP_ARRAY(char, luser, mtInternal);
|
||||
}
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
||||
"Process not found");
|
||||
}
|
||||
|
||||
@ -663,7 +663,10 @@ const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) {
|
||||
}
|
||||
}
|
||||
|
||||
jio_snprintf(out, outlen, ret);
|
||||
if (out && outlen > 0) {
|
||||
strncpy(out, ret, outlen);
|
||||
out[outlen - 1] = '\0';
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@ -2221,6 +2221,7 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
}
|
||||
|
||||
strncpy(saved_jvm_path, buf, MAXPATHLEN);
|
||||
saved_jvm_path[MAXPATHLEN - 1] = '\0';
|
||||
}
|
||||
|
||||
|
||||
@ -4761,10 +4762,6 @@ jint os::init_2(void) {
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
void os::init_3(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark the polling page as unreadable
|
||||
void os::make_polling_page_unreadable(void) {
|
||||
if (mprotect((char *)_polling_page, page_size, PROT_NONE) != 0) {
|
||||
@ -5372,31 +5369,32 @@ extern "C" {
|
||||
// to immediately return 0 your code should still work,
|
||||
// albeit degenerating to a spin loop.
|
||||
//
|
||||
// An interesting optimization for park() is to use a trylock()
|
||||
// to attempt to acquire the mutex. If the trylock() fails
|
||||
// then we know that a concurrent unpark() operation is in-progress.
|
||||
// in that case the park() code could simply set _count to 0
|
||||
// and return immediately. The subsequent park() operation *might*
|
||||
// return immediately. That's harmless as the caller of park() is
|
||||
// expected to loop. By using trylock() we will have avoided a
|
||||
// avoided a context switch caused by contention on the per-thread mutex.
|
||||
// In a sense, park()-unpark() just provides more polite spinning
|
||||
// and polling with the key difference over naive spinning being
|
||||
// that a parked thread needs to be explicitly unparked() in order
|
||||
// to wake up and to poll the underlying condition.
|
||||
//
|
||||
// TODO-FIXME:
|
||||
// 1. Reconcile Doug's JSR166 j.u.c park-unpark with the
|
||||
// objectmonitor implementation.
|
||||
// 2. Collapse the JSR166 parker event, and the
|
||||
// objectmonitor ParkEvent into a single "Event" construct.
|
||||
// 3. In park() and unpark() add:
|
||||
// assert (Thread::current() == AssociatedWith).
|
||||
// 4. add spurious wakeup injection on a -XX:EarlyParkReturn=N switch.
|
||||
// 1-out-of-N park() operations will return immediately.
|
||||
// Assumption:
|
||||
// Only one parker can exist on an event, which is why we allocate
|
||||
// them per-thread. Multiple unparkers can coexist.
|
||||
//
|
||||
// _Event transitions in park()
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
// 0 => -1 : block
|
||||
// 0 => -1 : block; then set _Event to 0 before returning
|
||||
//
|
||||
// _Event transitions in unpark()
|
||||
// 0 => 1 : just return
|
||||
// 1 => 1 : just return
|
||||
// -1 => either 0 or 1; must signal target thread
|
||||
// That is, we can safely transition _Event from -1 to either
|
||||
// 0 or 1.
|
||||
//
|
||||
// _Event serves as a restricted-range semaphore.
|
||||
// -1 : thread is blocked, i.e. there is a waiter
|
||||
// 0 : neutral: thread is running or ready,
|
||||
// could have been signaled after a wait started
|
||||
// 1 : signaled - thread is running or ready
|
||||
//
|
||||
// Another possible encoding of _Event would be with
|
||||
// explicit "PARKED" == 01b and "SIGNALED" == 10b bits.
|
||||
@ -5456,6 +5454,11 @@ static timestruc_t* compute_abstime(timestruc_t* abstime, jlong millis) {
|
||||
}
|
||||
|
||||
void os::PlatformEvent::park() { // AKA: down()
|
||||
// Transitions for _Event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
// 0 => -1 : block; then set _Event to 0 before returning
|
||||
|
||||
// Invariant: Only the thread associated with the Event/PlatformEvent
|
||||
// may call park().
|
||||
assert(_nParked == 0, "invariant");
|
||||
@ -5497,6 +5500,11 @@ void os::PlatformEvent::park() { // AKA: down()
|
||||
}
|
||||
|
||||
int os::PlatformEvent::park(jlong millis) {
|
||||
// Transitions for _Event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
// 0 => -1 : block; then set _Event to 0 before returning
|
||||
|
||||
guarantee(_nParked == 0, "invariant");
|
||||
int v;
|
||||
for (;;) {
|
||||
@ -5542,11 +5550,11 @@ int os::PlatformEvent::park(jlong millis) {
|
||||
|
||||
void os::PlatformEvent::unpark() {
|
||||
// Transitions for _Event:
|
||||
// 0 :=> 1
|
||||
// 1 :=> 1
|
||||
// -1 :=> either 0 or 1; must signal target thread
|
||||
// That is, we can safely transition _Event from -1 to either
|
||||
// 0 or 1.
|
||||
// 0 => 1 : just return
|
||||
// 1 => 1 : just return
|
||||
// -1 => either 0 or 1; must signal target thread
|
||||
// That is, we can safely transition _Event from -1 to either
|
||||
// 0 or 1.
|
||||
// See also: "Semaphores in Plan 9" by Mullender & Cox
|
||||
//
|
||||
// Note: Forcing a transition from "-1" to "1" on an unpark() means
|
||||
@ -5566,8 +5574,13 @@ void os::PlatformEvent::unpark() {
|
||||
assert_status(status == 0, status, "mutex_unlock");
|
||||
guarantee(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
|
||||
if (AnyWaiters != 0) {
|
||||
// We intentional signal *after* dropping the lock
|
||||
// to avoid a common class of futile wakeups.
|
||||
// Note that we signal() *after* dropping the lock for "immortal" Events.
|
||||
// This is safe and avoids a common class of futile wakeups. In rare
|
||||
// circumstances this can cause a thread to return prematurely from
|
||||
// cond_{timed}wait() but the spurious wakeup is benign and the victim
|
||||
// will simply re-test the condition and re-park itself.
|
||||
// This provides particular benefit if the underlying platform does not
|
||||
// provide wait morphing.
|
||||
status = os::Solaris::cond_signal(_cond);
|
||||
assert_status(status == 0, status, "cond_signal");
|
||||
}
|
||||
|
||||
@ -545,6 +545,7 @@ static void cleanup_sharedmem_resources(const char* dirname) {
|
||||
|
||||
if (!is_directory_secure(dirname)) {
|
||||
// the directory is not a secure directory
|
||||
os::closedir(dirp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -890,6 +891,9 @@ static void mmap_attach_shared(const char* user, int vmid, PerfMemory::PerfMemor
|
||||
//
|
||||
if (!is_directory_secure(dirname)) {
|
||||
FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
|
||||
if (luser != user) {
|
||||
FREE_C_HEAP_ARRAY(char, luser, mtInternal);
|
||||
}
|
||||
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
|
||||
"Process not found");
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <signal.h> // SIGBREAK
|
||||
#include <stdio.h>
|
||||
|
||||
// The AttachListener thread services a queue of operations. It blocks in the dequeue
|
||||
// function until an operation is enqueued. A client enqueues an operation by creating
|
||||
@ -269,6 +270,7 @@ HANDLE Win32AttachOperation::open_pipe() {
|
||||
if (hPipe != INVALID_HANDLE_VALUE) {
|
||||
// shouldn't happen as there is a pipe created per operation
|
||||
if (::GetLastError() == ERROR_PIPE_BUSY) {
|
||||
::CloseHandle(hPipe);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
@ -313,7 +315,8 @@ void Win32AttachOperation::complete(jint result, bufferedStream* result_stream)
|
||||
BOOL fSuccess;
|
||||
|
||||
char msg[32];
|
||||
sprintf(msg, "%d\n", result);
|
||||
_snprintf(msg, sizeof(msg), "%d\n", result);
|
||||
msg[sizeof(msg) - 1] = '\0';
|
||||
|
||||
fSuccess = write_pipe(hPipe, msg, (int)strlen(msg));
|
||||
if (fSuccess) {
|
||||
|
||||
@ -96,7 +96,7 @@
|
||||
#include <vdmdbg.h>
|
||||
|
||||
// for timer info max values which include all bits
|
||||
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
|
||||
#define ALL_64_BITS CONST64(-1)
|
||||
|
||||
// For DLL loading/load error detection
|
||||
// Values of PE COFF
|
||||
@ -211,6 +211,7 @@ void os::init_system_properties_values() {
|
||||
}
|
||||
strcpy(home_path, home_dir);
|
||||
Arguments::set_java_home(home_path);
|
||||
FREE_C_HEAP_ARRAY(char, home_path, mtInternal);
|
||||
|
||||
dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1,
|
||||
mtInternal);
|
||||
@ -220,6 +221,7 @@ void os::init_system_properties_values() {
|
||||
strcpy(dll_path, home_dir);
|
||||
strcat(dll_path, bin);
|
||||
Arguments::set_dll_dir(dll_path);
|
||||
FREE_C_HEAP_ARRAY(char, dll_path, mtInternal);
|
||||
|
||||
if (!set_boot_path('\\', ';')) {
|
||||
return;
|
||||
@ -297,6 +299,9 @@ void os::init_system_properties_values() {
|
||||
char * buf = NEW_C_HEAP_ARRAY(char, len, mtInternal);
|
||||
sprintf(buf, "%s%s", Arguments::get_java_home(), ENDORSED_DIR);
|
||||
Arguments::set_endorsed_dirs(buf);
|
||||
// (Arguments::set_endorsed_dirs() calls SystemProperty::set_value(), which
|
||||
// duplicates the input.)
|
||||
FREE_C_HEAP_ARRAY(char, buf, mtInternal);
|
||||
#undef ENDORSED_DIR
|
||||
}
|
||||
|
||||
@ -436,9 +441,9 @@ static unsigned __stdcall java_start(Thread* thread) {
|
||||
}
|
||||
|
||||
// Diagnostic code to investigate JDK-6573254
|
||||
int res = 90115; // non-java thread
|
||||
int res = 50115; // non-java thread
|
||||
if (thread->is_Java_thread()) {
|
||||
res = 60115; // java thread
|
||||
res = 40115; // java thread
|
||||
}
|
||||
|
||||
// Install a win32 structured exception handler around every thread created
|
||||
@ -1610,96 +1615,123 @@ void os::print_os_info(outputStream* st) {
|
||||
|
||||
void os::win32::print_windows_version(outputStream* st) {
|
||||
OSVERSIONINFOEX osvi;
|
||||
SYSTEM_INFO si;
|
||||
VS_FIXEDFILEINFO *file_info;
|
||||
TCHAR kernel32_path[MAX_PATH];
|
||||
UINT len, ret;
|
||||
|
||||
// Use the GetVersionEx information to see if we're on a server or
|
||||
// workstation edition of Windows. Starting with Windows 8.1 we can't
|
||||
// trust the OS version information returned by this API.
|
||||
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
|
||||
if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
|
||||
st->print_cr("N/A");
|
||||
st->print_cr("Call to GetVersionEx failed");
|
||||
return;
|
||||
}
|
||||
bool is_workstation = (osvi.wProductType == VER_NT_WORKSTATION);
|
||||
|
||||
// Get the full path to \Windows\System32\kernel32.dll and use that for
|
||||
// determining what version of Windows we're running on.
|
||||
len = MAX_PATH - (UINT)strlen("\\kernel32.dll") - 1;
|
||||
ret = GetSystemDirectory(kernel32_path, len);
|
||||
if (ret == 0 || ret > len) {
|
||||
st->print_cr("Call to GetSystemDirectory failed");
|
||||
return;
|
||||
}
|
||||
strncat(kernel32_path, "\\kernel32.dll", MAX_PATH - ret);
|
||||
|
||||
DWORD version_size = GetFileVersionInfoSize(kernel32_path, NULL);
|
||||
if (version_size == 0) {
|
||||
st->print_cr("Call to GetFileVersionInfoSize failed");
|
||||
return;
|
||||
}
|
||||
|
||||
int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion;
|
||||
LPTSTR version_info = (LPTSTR)os::malloc(version_size, mtInternal);
|
||||
if (version_info == NULL) {
|
||||
st->print_cr("Failed to allocate version_info");
|
||||
return;
|
||||
}
|
||||
|
||||
ZeroMemory(&si, sizeof(SYSTEM_INFO));
|
||||
if (os_vers >= 5002) {
|
||||
// Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
|
||||
// find out whether we are running on 64 bit processor or not.
|
||||
if (os::Kernel32Dll::GetNativeSystemInfoAvailable()) {
|
||||
os::Kernel32Dll::GetNativeSystemInfo(&si);
|
||||
if (!GetFileVersionInfo(kernel32_path, NULL, version_size, version_info)) {
|
||||
os::free(version_info);
|
||||
st->print_cr("Call to GetFileVersionInfo failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VerQueryValue(version_info, TEXT("\\"), (LPVOID*)&file_info, &len)) {
|
||||
os::free(version_info);
|
||||
st->print_cr("Call to VerQueryValue failed");
|
||||
return;
|
||||
}
|
||||
|
||||
int major_version = HIWORD(file_info->dwProductVersionMS);
|
||||
int minor_version = LOWORD(file_info->dwProductVersionMS);
|
||||
int build_number = HIWORD(file_info->dwProductVersionLS);
|
||||
int build_minor = LOWORD(file_info->dwProductVersionLS);
|
||||
int os_vers = major_version * 1000 + minor_version;
|
||||
os::free(version_info);
|
||||
|
||||
st->print(" Windows ");
|
||||
switch (os_vers) {
|
||||
|
||||
case 6000:
|
||||
if (is_workstation) {
|
||||
st->print("Vista");
|
||||
} else {
|
||||
GetSystemInfo(&si);
|
||||
st->print("Server 2008");
|
||||
}
|
||||
break;
|
||||
|
||||
case 6001:
|
||||
if (is_workstation) {
|
||||
st->print("7");
|
||||
} else {
|
||||
st->print("Server 2008 R2");
|
||||
}
|
||||
break;
|
||||
|
||||
case 6002:
|
||||
if (is_workstation) {
|
||||
st->print("8");
|
||||
} else {
|
||||
st->print("Server 2012");
|
||||
}
|
||||
break;
|
||||
|
||||
case 6003:
|
||||
if (is_workstation) {
|
||||
st->print("8.1");
|
||||
} else {
|
||||
st->print("Server 2012 R2");
|
||||
}
|
||||
break;
|
||||
|
||||
case 6004:
|
||||
if (is_workstation) {
|
||||
st->print("10");
|
||||
} else {
|
||||
// The server version name of Windows 10 is not known at this time
|
||||
st->print("%d.%d", major_version, minor_version);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unrecognized windows, print out its major and minor versions
|
||||
st->print("%d.%d", major_version, minor_version);
|
||||
break;
|
||||
}
|
||||
|
||||
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
|
||||
switch (os_vers) {
|
||||
case 3051: st->print(" Windows NT 3.51"); break;
|
||||
case 4000: st->print(" Windows NT 4.0"); break;
|
||||
case 5000: st->print(" Windows 2000"); break;
|
||||
case 5001: st->print(" Windows XP"); break;
|
||||
case 5002:
|
||||
if (osvi.wProductType == VER_NT_WORKSTATION &&
|
||||
si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
|
||||
st->print(" Windows XP x64 Edition");
|
||||
} else {
|
||||
st->print(" Windows Server 2003 family");
|
||||
}
|
||||
break;
|
||||
|
||||
case 6000:
|
||||
if (osvi.wProductType == VER_NT_WORKSTATION) {
|
||||
st->print(" Windows Vista");
|
||||
} else {
|
||||
st->print(" Windows Server 2008");
|
||||
}
|
||||
break;
|
||||
|
||||
case 6001:
|
||||
if (osvi.wProductType == VER_NT_WORKSTATION) {
|
||||
st->print(" Windows 7");
|
||||
} else {
|
||||
st->print(" Windows Server 2008 R2");
|
||||
}
|
||||
break;
|
||||
|
||||
case 6002:
|
||||
if (osvi.wProductType == VER_NT_WORKSTATION) {
|
||||
st->print(" Windows 8");
|
||||
} else {
|
||||
st->print(" Windows Server 2012");
|
||||
}
|
||||
break;
|
||||
|
||||
case 6003:
|
||||
if (osvi.wProductType == VER_NT_WORKSTATION) {
|
||||
st->print(" Windows 8.1");
|
||||
} else {
|
||||
st->print(" Windows Server 2012 R2");
|
||||
}
|
||||
break;
|
||||
|
||||
default: // future os
|
||||
// Unrecognized windows, print out its major and minor versions
|
||||
st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
|
||||
}
|
||||
} else {
|
||||
switch (os_vers) {
|
||||
case 4000: st->print(" Windows 95"); break;
|
||||
case 4010: st->print(" Windows 98"); break;
|
||||
case 4090: st->print(" Windows Me"); break;
|
||||
default: // future windows, print out its major and minor versions
|
||||
st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
|
||||
}
|
||||
}
|
||||
|
||||
if (os_vers >= 6000 && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
|
||||
// Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
|
||||
// find out whether we are running on 64 bit processor or not
|
||||
SYSTEM_INFO si;
|
||||
ZeroMemory(&si, sizeof(SYSTEM_INFO));
|
||||
os::Kernel32Dll::GetNativeSystemInfo(&si);
|
||||
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
|
||||
st->print(" , 64 bit");
|
||||
}
|
||||
|
||||
st->print(" Build %d", osvi.dwBuildNumber);
|
||||
st->print(" %s", osvi.szCSDVersion); // service pack
|
||||
st->print(" Build %d", build_number);
|
||||
st->print(" (%d.%d.%d.%d)", major_version, minor_version, build_number, build_minor);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
@ -1807,6 +1839,7 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
GetModuleFileName(vm_lib_handle, buf, buflen);
|
||||
}
|
||||
strncpy(saved_jvm_path, buf, MAX_PATH);
|
||||
saved_jvm_path[MAX_PATH - 1] = '\0';
|
||||
}
|
||||
|
||||
|
||||
@ -3719,8 +3752,12 @@ HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf,
|
||||
|
||||
// search system directory
|
||||
if ((size = GetSystemDirectory(path, pathLen)) > 0) {
|
||||
strcat(path, "\\");
|
||||
strcat(path, name);
|
||||
if (size >= pathLen) {
|
||||
return NULL; // truncated
|
||||
}
|
||||
if (jio_snprintf(path + size, pathLen - size, "\\%s", name) == -1) {
|
||||
return NULL; // truncated
|
||||
}
|
||||
if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {
|
||||
return result;
|
||||
}
|
||||
@ -3728,8 +3765,12 @@ HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf,
|
||||
|
||||
// try Windows directory
|
||||
if ((size = GetWindowsDirectory(path, pathLen)) > 0) {
|
||||
strcat(path, "\\");
|
||||
strcat(path, name);
|
||||
if (size >= pathLen) {
|
||||
return NULL; // truncated
|
||||
}
|
||||
if (jio_snprintf(path + size, pathLen - size, "\\%s", name) == -1) {
|
||||
return NULL; // truncated
|
||||
}
|
||||
if ((result = (HINSTANCE)os::dll_load(path, ebuf, ebuflen)) != NULL) {
|
||||
return result;
|
||||
}
|
||||
@ -3740,68 +3781,134 @@ HINSTANCE os::win32::load_Windows_dll(const char* name, char *ebuf,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define MIN_EXIT_MUTEXES 1
|
||||
#define MAX_EXIT_MUTEXES 16
|
||||
#define MAX_EXIT_HANDLES 16
|
||||
#define EXIT_TIMEOUT 1000 /* 1 sec */
|
||||
|
||||
struct ExitMutexes {
|
||||
DWORD count;
|
||||
HANDLE handles[MAX_EXIT_MUTEXES];
|
||||
};
|
||||
|
||||
static BOOL CALLBACK init_muts_call(PINIT_ONCE, PVOID ppmuts, PVOID*) {
|
||||
static ExitMutexes muts;
|
||||
|
||||
muts.count = os::processor_count();
|
||||
if (muts.count < MIN_EXIT_MUTEXES) {
|
||||
muts.count = MIN_EXIT_MUTEXES;
|
||||
} else if (muts.count > MAX_EXIT_MUTEXES) {
|
||||
muts.count = MAX_EXIT_MUTEXES;
|
||||
}
|
||||
|
||||
for (DWORD i = 0; i < muts.count; ++i) {
|
||||
muts.handles[i] = CreateMutex(NULL, FALSE, NULL);
|
||||
if (muts.handles[i] == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
*((ExitMutexes**)ppmuts) = &muts;
|
||||
static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) {
|
||||
InitializeCriticalSection((CRITICAL_SECTION*)pcrit_sect);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int os::win32::exit_process_or_thread(Ept what, int exit_code) {
|
||||
if (os::win32::has_exit_bug()) {
|
||||
static INIT_ONCE init_once_muts = INIT_ONCE_STATIC_INIT;
|
||||
static ExitMutexes* pmuts;
|
||||
// Basic approach:
|
||||
// - Each exiting thread registers its intent to exit and then does so.
|
||||
// - A thread trying to terminate the process must wait for all
|
||||
// threads currently exiting to complete their exit.
|
||||
|
||||
if (!InitOnceExecuteOnce(&init_once_muts, init_muts_call, &pmuts, NULL)) {
|
||||
warning("ExitMutex initialization failed in %s: %d\n", __FILE__, __LINE__);
|
||||
} else if (WaitForMultipleObjects(pmuts->count, pmuts->handles,
|
||||
(what != EPT_THREAD), // exiting process waits for all mutexes
|
||||
INFINITE) == WAIT_FAILED) {
|
||||
warning("ExitMutex acquisition failed in %s: %d\n", __FILE__, __LINE__);
|
||||
if (os::win32::has_exit_bug()) {
|
||||
// The array holds handles of the threads that have started exiting by calling
|
||||
// _endthreadex().
|
||||
// Should be large enough to avoid blocking the exiting thread due to lack of
|
||||
// a free slot.
|
||||
static HANDLE handles[MAX_EXIT_HANDLES];
|
||||
static int handle_count = 0;
|
||||
|
||||
static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT;
|
||||
static CRITICAL_SECTION crit_sect;
|
||||
int i, j;
|
||||
DWORD res;
|
||||
HANDLE hproc, hthr;
|
||||
|
||||
// The first thread that reached this point, initializes the critical section.
|
||||
if (!InitOnceExecuteOnce(&init_once_crit_sect, init_crit_sect_call, &crit_sect, NULL)) {
|
||||
warning("crit_sect initialization failed in %s: %d\n", __FILE__, __LINE__);
|
||||
} else {
|
||||
EnterCriticalSection(&crit_sect);
|
||||
|
||||
if (what == EPT_THREAD) {
|
||||
// Remove from the array those handles of the threads that have completed exiting.
|
||||
for (i = 0, j = 0; i < handle_count; ++i) {
|
||||
res = WaitForSingleObject(handles[i], 0 /* don't wait */);
|
||||
if (res == WAIT_TIMEOUT) {
|
||||
handles[j++] = handles[i];
|
||||
} else {
|
||||
if (res != WAIT_OBJECT_0) {
|
||||
warning("WaitForSingleObject failed in %s: %d\n", __FILE__, __LINE__);
|
||||
// Don't keep the handle, if we failed waiting for it.
|
||||
}
|
||||
CloseHandle(handles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// If there's no free slot in the array of the kept handles, we'll have to
|
||||
// wait until at least one thread completes exiting.
|
||||
if ((handle_count = j) == MAX_EXIT_HANDLES) {
|
||||
res = WaitForMultipleObjects(MAX_EXIT_HANDLES, handles, FALSE, EXIT_TIMEOUT);
|
||||
if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) {
|
||||
i = (res - WAIT_OBJECT_0);
|
||||
handle_count = MAX_EXIT_HANDLES - 1;
|
||||
for (; i < handle_count; ++i) {
|
||||
handles[i] = handles[i + 1];
|
||||
}
|
||||
} else {
|
||||
warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
|
||||
// Don't keep handles, if we failed waiting for them.
|
||||
for (i = 0; i < MAX_EXIT_HANDLES; ++i) {
|
||||
CloseHandle(handles[i]);
|
||||
}
|
||||
handle_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Store a duplicate of the current thread handle in the array of handles.
|
||||
hproc = GetCurrentProcess();
|
||||
hthr = GetCurrentThread();
|
||||
if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count],
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS)) {
|
||||
warning("DuplicateHandle failed in %s: %d\n", __FILE__, __LINE__);
|
||||
} else {
|
||||
++handle_count;
|
||||
}
|
||||
|
||||
// The current exiting thread has stored its handle in the array, and now
|
||||
// should leave the critical section before calling _endthreadex().
|
||||
|
||||
} else { // what != EPT_THREAD
|
||||
if (handle_count > 0) {
|
||||
// Before ending the process, make sure all the threads that had called
|
||||
// _endthreadex() completed.
|
||||
res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT);
|
||||
if (res == WAIT_FAILED) {
|
||||
warning("WaitForMultipleObjects failed in %s: %d\n", __FILE__, __LINE__);
|
||||
}
|
||||
for (i = 0; i < handle_count; ++i) {
|
||||
CloseHandle(handles[i]);
|
||||
}
|
||||
handle_count = 0;
|
||||
}
|
||||
|
||||
// End the process, not leaving critical section.
|
||||
// This makes sure no other thread executes exit-related code at the same
|
||||
// time, thus a race is avoided.
|
||||
if (what == EPT_PROCESS) {
|
||||
::exit(exit_code);
|
||||
} else {
|
||||
_exit(exit_code);
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&crit_sect);
|
||||
}
|
||||
}
|
||||
|
||||
switch (what) {
|
||||
case EPT_THREAD:
|
||||
// We are here if either
|
||||
// - there's no 'race at exit' bug on this OS release;
|
||||
// - initialization of the critical section failed (unlikely);
|
||||
// - the current thread has stored its handle and left the critical section.
|
||||
if (what == EPT_THREAD) {
|
||||
_endthreadex((unsigned)exit_code);
|
||||
break;
|
||||
|
||||
case EPT_PROCESS:
|
||||
} else if (what == EPT_PROCESS) {
|
||||
::exit(exit_code);
|
||||
break;
|
||||
|
||||
case EPT_PROCESS_DIE:
|
||||
} else {
|
||||
_exit(exit_code);
|
||||
break;
|
||||
}
|
||||
|
||||
// should not reach here
|
||||
// Should not reach here
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
#undef MIN_EXIT_MUTEXES
|
||||
#undef MAX_EXIT_MUTEXES
|
||||
#undef MAX_EXIT_HANDLES
|
||||
#undef EXIT_TIMEOUT
|
||||
|
||||
void os::win32::setmode_streams() {
|
||||
_setmode(_fileno(stdin), _O_BINARY);
|
||||
@ -4047,10 +4154,6 @@ jint os::init_2(void) {
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
void os::init_3(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark the polling page as unreadable
|
||||
void os::make_polling_page_unreadable(void) {
|
||||
DWORD old_status;
|
||||
@ -4792,27 +4895,46 @@ bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
|
||||
// 3. Collapse the interrupt_event, the JSR166 parker event, and the objectmonitor ParkEvent
|
||||
// into a single win32 CreateEvent() handle.
|
||||
//
|
||||
// Assumption:
|
||||
// Only one parker can exist on an event, which is why we allocate
|
||||
// them per-thread. Multiple unparkers can coexist.
|
||||
//
|
||||
// _Event transitions in park()
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
// 0 => -1 : block
|
||||
// 0 => -1 : block; then set _Event to 0 before returning
|
||||
//
|
||||
// _Event serves as a restricted-range semaphore :
|
||||
// -1 : thread is blocked
|
||||
// 0 : neutral - thread is running or ready
|
||||
// 1 : signaled - thread is running or ready
|
||||
// _Event transitions in unpark()
|
||||
// 0 => 1 : just return
|
||||
// 1 => 1 : just return
|
||||
// -1 => either 0 or 1; must signal target thread
|
||||
// That is, we can safely transition _Event from -1 to either
|
||||
// 0 or 1.
|
||||
//
|
||||
// _Event serves as a restricted-range semaphore.
|
||||
// -1 : thread is blocked, i.e. there is a waiter
|
||||
// 0 : neutral: thread is running or ready,
|
||||
// could have been signaled after a wait started
|
||||
// 1 : signaled - thread is running or ready
|
||||
//
|
||||
// Another possible encoding of _Event would be with
|
||||
// explicit "PARKED" == 01b and "SIGNALED" == 10b bits.
|
||||
//
|
||||
// Another possible encoding of _Event would be
|
||||
// with explicit "PARKED" and "SIGNALED" bits.
|
||||
|
||||
int os::PlatformEvent::park(jlong Millis) {
|
||||
// Transitions for _Event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
// 0 => -1 : block; then set _Event to 0 before returning
|
||||
|
||||
guarantee(_ParkHandle != NULL , "Invariant");
|
||||
guarantee(Millis > 0 , "Invariant");
|
||||
int v;
|
||||
|
||||
// CONSIDER: defer assigning a CreateEvent() handle to the Event until
|
||||
// the initial park() operation.
|
||||
// Consider: use atomic decrement instead of CAS-loop
|
||||
|
||||
int v;
|
||||
for (;;) {
|
||||
v = _Event;
|
||||
if (Atomic::cmpxchg(v-1, &_Event, v) == v) break;
|
||||
@ -4860,9 +4982,15 @@ int os::PlatformEvent::park(jlong Millis) {
|
||||
}
|
||||
|
||||
void os::PlatformEvent::park() {
|
||||
// Transitions for _Event:
|
||||
// -1 => -1 : illegal
|
||||
// 1 => 0 : pass - return immediately
|
||||
// 0 => -1 : block; then set _Event to 0 before returning
|
||||
|
||||
guarantee(_ParkHandle != NULL, "Invariant");
|
||||
// Invariant: Only the thread associated with the Event/PlatformEvent
|
||||
// may call park().
|
||||
// Consider: use atomic decrement instead of CAS-loop
|
||||
int v;
|
||||
for (;;) {
|
||||
v = _Event;
|
||||
@ -4891,11 +5019,11 @@ void os::PlatformEvent::unpark() {
|
||||
guarantee(_ParkHandle != NULL, "Invariant");
|
||||
|
||||
// Transitions for _Event:
|
||||
// 0 :=> 1
|
||||
// 1 :=> 1
|
||||
// -1 :=> either 0 or 1; must signal target thread
|
||||
// That is, we can safely transition _Event from -1 to either
|
||||
// 0 or 1.
|
||||
// 0 => 1 : just return
|
||||
// 1 => 1 : just return
|
||||
// -1 => either 0 or 1; must signal target thread
|
||||
// That is, we can safely transition _Event from -1 to either
|
||||
// 0 or 1.
|
||||
// See also: "Semaphores in Plan 9" by Mullender & Cox
|
||||
//
|
||||
// Note: Forcing a transition from "-1" to "1" on an unpark() means
|
||||
@ -5303,11 +5431,6 @@ inline BOOL os::Kernel32Dll::Module32Next(HANDLE hSnapshot,
|
||||
return ::Module32Next(hSnapshot, lpme);
|
||||
}
|
||||
|
||||
|
||||
inline BOOL os::Kernel32Dll::GetNativeSystemInfoAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void os::Kernel32Dll::GetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) {
|
||||
::GetNativeSystemInfo(lpSystemInfo);
|
||||
}
|
||||
|
||||
@ -210,7 +210,6 @@ public:
|
||||
static BOOL Module32First(HANDLE,LPMODULEENTRY32);
|
||||
static BOOL Module32Next(HANDLE,LPMODULEENTRY32);
|
||||
|
||||
static BOOL GetNativeSystemInfoAvailable();
|
||||
static void GetNativeSystemInfo(LPSYSTEM_INFO);
|
||||
|
||||
// NUMA calls
|
||||
|
||||
@ -910,7 +910,7 @@ void os::workaround_expand_exec_shield_cs_limit() {
|
||||
*/
|
||||
char* hint = (char*) (Linux::initial_thread_stack_bottom() -
|
||||
((StackYellowPages + StackRedPages + 1) * page_size));
|
||||
char* codebuf = os::reserve_memory(page_size, hint);
|
||||
char* codebuf = os::attempt_reserve_memory_at(page_size, hint);
|
||||
if ( (codebuf == NULL) || (!os::commit_memory(codebuf, page_size, true)) ) {
|
||||
return; // No matter, we tried, best effort.
|
||||
}
|
||||
|
||||
@ -411,7 +411,7 @@ class CompilerInterfaceVC10 extends CompilerInterface {
|
||||
"/export:jio_vsnprintf "+
|
||||
"/export:JVM_GetVersionInfo "+
|
||||
"/export:JVM_InitAgentProperties");
|
||||
addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib");
|
||||
addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib;version.lib");
|
||||
addAttr(rv, "OutputFile", outDll);
|
||||
addAttr(rv, "SuppressStartupBanner", "true");
|
||||
addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
|
||||
|
||||
@ -553,6 +553,7 @@ ClassLoaderData* ClassLoaderDataGraph::_saved_unloading = NULL;
|
||||
ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
|
||||
|
||||
bool ClassLoaderDataGraph::_should_purge = false;
|
||||
bool ClassLoaderDataGraph::_metaspace_oom = false;
|
||||
|
||||
// Add a new class loader data node to the list. Assign the newly created
|
||||
// ClassLoaderData into the java/lang/ClassLoader object as a hidden field
|
||||
@ -804,12 +805,17 @@ void ClassLoaderDataGraph::purge() {
|
||||
ClassLoaderData* list = _unloading;
|
||||
_unloading = NULL;
|
||||
ClassLoaderData* next = list;
|
||||
bool classes_unloaded = false;
|
||||
while (next != NULL) {
|
||||
ClassLoaderData* purge_me = next;
|
||||
next = purge_me->next();
|
||||
delete purge_me;
|
||||
classes_unloaded = true;
|
||||
}
|
||||
if (classes_unloaded) {
|
||||
Metaspace::purge();
|
||||
set_metaspace_oom(false);
|
||||
}
|
||||
Metaspace::purge();
|
||||
}
|
||||
|
||||
void ClassLoaderDataGraph::post_class_unload_events(void) {
|
||||
|
||||
@ -68,6 +68,9 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
static ClassLoaderData* _saved_head;
|
||||
static ClassLoaderData* _saved_unloading;
|
||||
static bool _should_purge;
|
||||
// OOM has been seen in metaspace allocation. Used to prevent some
|
||||
// allocations until class unloading
|
||||
static bool _metaspace_oom;
|
||||
|
||||
static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS);
|
||||
static void post_class_unload_events(void);
|
||||
@ -107,6 +110,9 @@ class ClassLoaderDataGraph : public AllStatic {
|
||||
}
|
||||
}
|
||||
|
||||
static bool has_metaspace_oom() { return _metaspace_oom; }
|
||||
static void set_metaspace_oom(bool value) { _metaspace_oom = value; }
|
||||
|
||||
static void free_deallocate_lists();
|
||||
|
||||
static void dump_on(outputStream * const out) PRODUCT_RETURN;
|
||||
|
||||
@ -185,6 +185,14 @@ class CompilationLog : public StringEventLog {
|
||||
lm.print("\n");
|
||||
log(thread, "%s", (const char*)lm);
|
||||
}
|
||||
|
||||
void log_metaspace_failure(const char* reason) {
|
||||
ResourceMark rm;
|
||||
StringLogMessage lm;
|
||||
lm.print("%4d COMPILE PROFILING SKIPPED: %s", -1, reason);
|
||||
lm.print("\n");
|
||||
log(JavaThread::current(), "%s", (const char*)lm);
|
||||
}
|
||||
};
|
||||
|
||||
static CompilationLog* _compilation_log = NULL;
|
||||
@ -1817,6 +1825,18 @@ void CompileBroker::init_compiler_thread_log() {
|
||||
warning("Cannot open log file: %s", file_name);
|
||||
}
|
||||
|
||||
void CompileBroker::log_metaspace_failure() {
|
||||
const char* message = "some methods may not be compiled because metaspace "
|
||||
"is out of memory";
|
||||
if (_compilation_log != NULL) {
|
||||
_compilation_log->log_metaspace_failure(message);
|
||||
}
|
||||
if (PrintCompilation) {
|
||||
tty->print_cr("COMPILE PROFILING SKIPPED: %s", message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// CompileBroker::set_should_block
|
||||
//
|
||||
|
||||
@ -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
|
||||
@ -471,6 +471,9 @@ class CompileBroker: AllStatic {
|
||||
static int get_sum_nmethod_code_size() { return _sum_nmethod_code_size; }
|
||||
static long get_peak_compilation_time() { return _peak_compilation_time; }
|
||||
static long get_total_compilation_time() { return _t_total_compilation.milliseconds(); }
|
||||
|
||||
// Log that compilation profiling is skipped because metaspace is full.
|
||||
static void log_metaspace_failure();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_COMPILER_COMPILEBROKER_HPP
|
||||
|
||||
@ -714,12 +714,17 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
|
||||
int class_list_path_len = (int)strlen(class_list_path_str);
|
||||
if (class_list_path_len >= 3) {
|
||||
if (strcmp(class_list_path_str + class_list_path_len - 3, "lib") != 0) {
|
||||
strcat(class_list_path_str, os::file_separator());
|
||||
strcat(class_list_path_str, "lib");
|
||||
if (class_list_path_len < JVM_MAXPATHLEN - 4) {
|
||||
strncat(class_list_path_str, os::file_separator(), 1);
|
||||
strncat(class_list_path_str, "lib", 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
strcat(class_list_path_str, os::file_separator());
|
||||
strcat(class_list_path_str, "classlist");
|
||||
class_list_path_len = (int)strlen(class_list_path_str);
|
||||
if (class_list_path_len < JVM_MAXPATHLEN - 10) {
|
||||
strncat(class_list_path_str, os::file_separator(), 1);
|
||||
strncat(class_list_path_str, "classlist", 9);
|
||||
}
|
||||
class_list_path = class_list_path_str;
|
||||
} else {
|
||||
class_list_path = SharedClassListFile;
|
||||
|
||||
@ -277,7 +277,7 @@ public:
|
||||
bool has_stackmap_table() const { return _stackmap_data != NULL; }
|
||||
|
||||
void init_fingerprint() {
|
||||
const uint64_t initval = CONST64(0x8000000000000000);
|
||||
const uint64_t initval = UCONST64(0x8000000000000000);
|
||||
_fingerprint = initval;
|
||||
}
|
||||
|
||||
|
||||
@ -1730,6 +1730,25 @@ jmethodID InstanceKlass::get_jmethod_id(instanceKlassHandle ik_h, methodHandle m
|
||||
return id;
|
||||
}
|
||||
|
||||
// Figure out how many jmethodIDs haven't been allocated, and make
|
||||
// sure space for them is pre-allocated. This makes getting all
|
||||
// method ids much, much faster with classes with more than 8
|
||||
// methods, and has a *substantial* effect on performance with jvmti
|
||||
// code that loads all jmethodIDs for all classes.
|
||||
void InstanceKlass::ensure_space_for_methodids(int start_offset) {
|
||||
int new_jmeths = 0;
|
||||
int length = methods()->length();
|
||||
for (int index = start_offset; index < length; index++) {
|
||||
Method* m = methods()->at(index);
|
||||
jmethodID id = m->find_jmethod_id_or_null();
|
||||
if (id == NULL) {
|
||||
new_jmeths++;
|
||||
}
|
||||
}
|
||||
if (new_jmeths != 0) {
|
||||
Method::ensure_jmethod_ids(class_loader_data(), new_jmeths);
|
||||
}
|
||||
}
|
||||
|
||||
// Common code to fetch the jmethodID from the cache or update the
|
||||
// cache with the new jmethodID. This function should never do anything
|
||||
@ -2499,7 +2518,7 @@ const char* InstanceKlass::signature_name() const {
|
||||
// If this is an anonymous class, append a hash to make the name unique
|
||||
if (is_anonymous()) {
|
||||
intptr_t hash = (java_mirror() != NULL) ? java_mirror()->identity_hash() : 0;
|
||||
sprintf(hash_buf, "/" UINTX_FORMAT, (uintx)hash);
|
||||
jio_snprintf(hash_buf, sizeof(hash_buf), "/" UINTX_FORMAT, (uintx)hash);
|
||||
hash_len = (int)strlen(hash_buf);
|
||||
}
|
||||
|
||||
|
||||
@ -698,6 +698,7 @@ class InstanceKlass: public Klass {
|
||||
jmethodID** to_dealloc_jmeths_p);
|
||||
static void get_jmethod_id_length_value(jmethodID* cache, size_t idnum,
|
||||
size_t *length_p, jmethodID* id_p);
|
||||
void ensure_space_for_methodids(int start_offset = 0);
|
||||
jmethodID jmethod_id_or_null(Method* method);
|
||||
|
||||
// annotations support
|
||||
|
||||
@ -368,6 +368,13 @@ void Method::print_invocation_count() {
|
||||
// Build a MethodData* object to hold information about this method
|
||||
// collected in the interpreter.
|
||||
void Method::build_interpreter_method_data(methodHandle method, TRAPS) {
|
||||
// Do not profile the method if metaspace has hit an OOM previously
|
||||
// allocating profiling data. Callers clear pending exception so don't
|
||||
// add one here.
|
||||
if (ClassLoaderDataGraph::has_metaspace_oom()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not profile method if current thread holds the pending list lock,
|
||||
// which avoids deadlock for acquiring the MethodData_lock.
|
||||
if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
|
||||
@ -379,7 +386,13 @@ void Method::build_interpreter_method_data(methodHandle method, TRAPS) {
|
||||
MutexLocker ml(MethodData_lock, THREAD);
|
||||
if (method->method_data() == NULL) {
|
||||
ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
|
||||
MethodData* method_data = MethodData::allocate(loader_data, method, CHECK);
|
||||
MethodData* method_data = MethodData::allocate(loader_data, method, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
CompileBroker::log_metaspace_failure();
|
||||
ClassLoaderDataGraph::set_metaspace_oom(true);
|
||||
return; // return the exception (which is cleared)
|
||||
}
|
||||
|
||||
method->set_method_data(method_data);
|
||||
if (PrintMethodData && (Verbose || WizardMode)) {
|
||||
ResourceMark rm(THREAD);
|
||||
@ -392,9 +405,19 @@ void Method::build_interpreter_method_data(methodHandle method, TRAPS) {
|
||||
}
|
||||
|
||||
MethodCounters* Method::build_method_counters(Method* m, TRAPS) {
|
||||
// Do not profile the method if metaspace has hit an OOM previously
|
||||
if (ClassLoaderDataGraph::has_metaspace_oom()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
methodHandle mh(m);
|
||||
ClassLoaderData* loader_data = mh->method_holder()->class_loader_data();
|
||||
MethodCounters* counters = MethodCounters::allocate(loader_data, CHECK_NULL);
|
||||
MethodCounters* counters = MethodCounters::allocate(loader_data, THREAD);
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
CompileBroker::log_metaspace_failure();
|
||||
ClassLoaderDataGraph::set_metaspace_oom(true);
|
||||
return NULL; // return the exception (which is cleared)
|
||||
}
|
||||
if (!mh->init_method_counters(counters)) {
|
||||
MetadataFactory::free_metadata(loader_data, counters);
|
||||
}
|
||||
@ -1708,59 +1731,98 @@ void BreakpointInfo::clear(Method* method) {
|
||||
// jmethodID handling
|
||||
|
||||
// This is a block allocating object, sort of like JNIHandleBlock, only a
|
||||
// lot simpler. There aren't many of these, they aren't long, they are rarely
|
||||
// deleted and so we can do some suboptimal things.
|
||||
// lot simpler.
|
||||
// It's allocated on the CHeap because once we allocate a jmethodID, we can
|
||||
// never get rid of it.
|
||||
// It would be nice to be able to parameterize the number of methods for
|
||||
// the null_class_loader but then we'd have to turn this and ClassLoaderData
|
||||
// into templates.
|
||||
|
||||
// I feel like this brain dead class should exist somewhere in the STL
|
||||
static const int min_block_size = 8;
|
||||
|
||||
class JNIMethodBlockNode : public CHeapObj<mtClass> {
|
||||
friend class JNIMethodBlock;
|
||||
Method** _methods;
|
||||
int _number_of_methods;
|
||||
int _top;
|
||||
JNIMethodBlockNode* _next;
|
||||
|
||||
public:
|
||||
|
||||
JNIMethodBlockNode(int num_methods = min_block_size);
|
||||
|
||||
~JNIMethodBlockNode() { FREE_C_HEAP_ARRAY(Method*, _methods, mtInternal); }
|
||||
|
||||
void ensure_methods(int num_addl_methods) {
|
||||
if (_top < _number_of_methods) {
|
||||
num_addl_methods -= _number_of_methods - _top;
|
||||
if (num_addl_methods <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_next == NULL) {
|
||||
_next = new JNIMethodBlockNode(MAX2(num_addl_methods, min_block_size));
|
||||
} else {
|
||||
_next->ensure_methods(num_addl_methods);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class JNIMethodBlock : public CHeapObj<mtClass> {
|
||||
enum { number_of_methods = 8 };
|
||||
|
||||
Method* _methods[number_of_methods];
|
||||
int _top;
|
||||
JNIMethodBlock* _next;
|
||||
JNIMethodBlockNode _head;
|
||||
JNIMethodBlockNode *_last_free;
|
||||
public:
|
||||
static Method* const _free_method;
|
||||
|
||||
JNIMethodBlock() : _next(NULL), _top(0) {
|
||||
for (int i = 0; i< number_of_methods; i++) _methods[i] = _free_method;
|
||||
JNIMethodBlock(int initial_capacity = min_block_size)
|
||||
: _head(initial_capacity), _last_free(&_head) {}
|
||||
|
||||
void ensure_methods(int num_addl_methods) {
|
||||
_last_free->ensure_methods(num_addl_methods);
|
||||
}
|
||||
|
||||
Method** add_method(Method* m) {
|
||||
if (_top < number_of_methods) {
|
||||
// top points to the next free entry.
|
||||
int i = _top;
|
||||
_methods[i] = m;
|
||||
_top++;
|
||||
return &_methods[i];
|
||||
} else if (_top == number_of_methods) {
|
||||
// if the next free entry ran off the block see if there's a free entry
|
||||
for (int i = 0; i< number_of_methods; i++) {
|
||||
if (_methods[i] == _free_method) {
|
||||
_methods[i] = m;
|
||||
return &_methods[i];
|
||||
for (JNIMethodBlockNode* b = _last_free; b != NULL; b = b->_next) {
|
||||
if (b->_top < b->_number_of_methods) {
|
||||
// top points to the next free entry.
|
||||
int i = b->_top;
|
||||
b->_methods[i] = m;
|
||||
b->_top++;
|
||||
_last_free = b;
|
||||
return &(b->_methods[i]);
|
||||
} else if (b->_top == b->_number_of_methods) {
|
||||
// if the next free entry ran off the block see if there's a free entry
|
||||
for (int i = 0; i < b->_number_of_methods; i++) {
|
||||
if (b->_methods[i] == _free_method) {
|
||||
b->_methods[i] = m;
|
||||
_last_free = b;
|
||||
return &(b->_methods[i]);
|
||||
}
|
||||
}
|
||||
// Only check each block once for frees. They're very unlikely.
|
||||
// Increment top past the end of the block.
|
||||
b->_top++;
|
||||
}
|
||||
// need to allocate a next block.
|
||||
if (b->_next == NULL) {
|
||||
b->_next = _last_free = new JNIMethodBlockNode();
|
||||
}
|
||||
// Only check each block once for frees. They're very unlikely.
|
||||
// Increment top past the end of the block.
|
||||
_top++;
|
||||
}
|
||||
// need to allocate a next block.
|
||||
if (_next == NULL) {
|
||||
_next = new JNIMethodBlock();
|
||||
}
|
||||
return _next->add_method(m);
|
||||
guarantee(false, "Should always allocate a free block");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool contains(Method** m) {
|
||||
for (JNIMethodBlock* b = this; b != NULL; b = b->_next) {
|
||||
for (int i = 0; i< number_of_methods; i++) {
|
||||
if (&(b->_methods[i]) == m) {
|
||||
if (m == NULL) return false;
|
||||
for (JNIMethodBlockNode* b = &_head; b != NULL; b = b->_next) {
|
||||
if (b->_methods <= m && m < b->_methods + b->_number_of_methods) {
|
||||
// This is a bit of extra checking, for two reasons. One is
|
||||
// that contains() deals with pointers that are passed in by
|
||||
// JNI code, so making sure that the pointer is aligned
|
||||
// correctly is valuable. The other is that <= and > are
|
||||
// technically not defined on pointers, so the if guard can
|
||||
// pass spuriously; no modern compiler is likely to make that
|
||||
// a problem, though (and if one did, the guard could also
|
||||
// fail spuriously, which would be bad).
|
||||
ptrdiff_t idx = m - b->_methods;
|
||||
if (b->_methods + idx == m) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1779,9 +1841,9 @@ class JNIMethodBlock : public CHeapObj<mtClass> {
|
||||
// During class unloading the methods are cleared, which is different
|
||||
// than freed.
|
||||
void clear_all_methods() {
|
||||
for (JNIMethodBlock* b = this; b != NULL; b = b->_next) {
|
||||
for (int i = 0; i< number_of_methods; i++) {
|
||||
_methods[i] = NULL;
|
||||
for (JNIMethodBlockNode* b = &_head; b != NULL; b = b->_next) {
|
||||
for (int i = 0; i< b->_number_of_methods; i++) {
|
||||
b->_methods[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1789,9 +1851,9 @@ class JNIMethodBlock : public CHeapObj<mtClass> {
|
||||
int count_methods() {
|
||||
// count all allocated methods
|
||||
int count = 0;
|
||||
for (JNIMethodBlock* b = this; b != NULL; b = b->_next) {
|
||||
for (int i = 0; i< number_of_methods; i++) {
|
||||
if (_methods[i] != _free_method) count++;
|
||||
for (JNIMethodBlockNode* b = &_head; b != NULL; b = b->_next) {
|
||||
for (int i = 0; i< b->_number_of_methods; i++) {
|
||||
if (b->_methods[i] != _free_method) count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
@ -1802,6 +1864,36 @@ class JNIMethodBlock : public CHeapObj<mtClass> {
|
||||
// Something that can't be mistaken for an address or a markOop
|
||||
Method* const JNIMethodBlock::_free_method = (Method*)55;
|
||||
|
||||
JNIMethodBlockNode::JNIMethodBlockNode(int num_methods) : _next(NULL), _top(0) {
|
||||
_number_of_methods = MAX2(num_methods, min_block_size);
|
||||
_methods = NEW_C_HEAP_ARRAY(Method*, _number_of_methods, mtInternal);
|
||||
for (int i = 0; i < _number_of_methods; i++) {
|
||||
_methods[i] = JNIMethodBlock::_free_method;
|
||||
}
|
||||
}
|
||||
|
||||
void Method::ensure_jmethod_ids(ClassLoaderData* loader_data, int capacity) {
|
||||
ClassLoaderData* cld = loader_data;
|
||||
if (!SafepointSynchronize::is_at_safepoint()) {
|
||||
// Have to add jmethod_ids() to class loader data thread-safely.
|
||||
// Also have to add the method to the list safely, which the cld lock
|
||||
// protects as well.
|
||||
MutexLockerEx ml(cld->metaspace_lock(), Mutex::_no_safepoint_check_flag);
|
||||
if (cld->jmethod_ids() == NULL) {
|
||||
cld->set_jmethod_ids(new JNIMethodBlock(capacity));
|
||||
} else {
|
||||
cld->jmethod_ids()->ensure_methods(capacity);
|
||||
}
|
||||
} else {
|
||||
// At safepoint, we are single threaded and can set this.
|
||||
if (cld->jmethod_ids() == NULL) {
|
||||
cld->set_jmethod_ids(new JNIMethodBlock(capacity));
|
||||
} else {
|
||||
cld->jmethod_ids()->ensure_methods(capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a method id to the jmethod_ids
|
||||
jmethodID Method::make_jmethod_id(ClassLoaderData* loader_data, Method* m) {
|
||||
ClassLoaderData* cld = loader_data;
|
||||
|
||||
@ -729,6 +729,11 @@ class Method : public Metadata {
|
||||
static jmethodID make_jmethod_id(ClassLoaderData* loader_data, Method* mh);
|
||||
static void destroy_jmethod_id(ClassLoaderData* loader_data, jmethodID mid);
|
||||
|
||||
// Ensure there is enough capacity in the internal tracking data
|
||||
// structures to hold the number of jmethodIDs you plan to generate.
|
||||
// This saves substantial time doing allocations.
|
||||
static void ensure_jmethod_ids(ClassLoaderData* loader_data, int capacity);
|
||||
|
||||
// Use resolve_jmethod_id() in situations where the caller is expected
|
||||
// to provide a valid jmethodID; the only sanity checks are in asserts;
|
||||
// result guaranteed not to be NULL.
|
||||
|
||||
@ -610,7 +610,7 @@ Node *AndLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// convert masks which would cause a sign extension of the integer
|
||||
// value. This check includes UI2L masks (0x00000000FFFFFFFF) which
|
||||
// would be optimized away later in Identity.
|
||||
if (op == Op_ConvI2L && (mask & CONST64(0xFFFFFFFF80000000)) == 0) {
|
||||
if (op == Op_ConvI2L && (mask & UCONST64(0xFFFFFFFF80000000)) == 0) {
|
||||
Node* andi = new AndINode(in1->in(1), phase->intcon(mask));
|
||||
andi = phase->transform(andi);
|
||||
return new ConvI2LNode(andi);
|
||||
|
||||
@ -951,8 +951,9 @@ class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {
|
||||
|
||||
// Optimized path if we have the bitvector form of signature
|
||||
void iterate( uint64_t fingerprint ) {
|
||||
if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate();// Must be too many arguments
|
||||
else {
|
||||
if (fingerprint == (uint64_t)CONST64(-1)) {
|
||||
SignatureIterator::iterate(); // Must be too many arguments
|
||||
} else {
|
||||
_return_type = (BasicType)((fingerprint >> static_feature_size) &
|
||||
result_feature_mask);
|
||||
|
||||
@ -1022,8 +1023,9 @@ class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
|
||||
|
||||
// Optimized path if we have the bitvector form of signature
|
||||
void iterate( uint64_t fingerprint ) {
|
||||
if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate(); // Must be too many arguments
|
||||
else {
|
||||
if (fingerprint == (uint64_t)CONST64(-1)) {
|
||||
SignatureIterator::iterate(); // Must be too many arguments
|
||||
} else {
|
||||
_return_type = (BasicType)((fingerprint >> static_feature_size) &
|
||||
result_feature_mask);
|
||||
assert(fingerprint, "Fingerprint should not be 0");
|
||||
|
||||
@ -2583,7 +2583,14 @@ ATTRIBUTE_PRINTF(3, 0)
|
||||
int jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) {
|
||||
// see bug 4399518, 4417214
|
||||
if ((intptr_t)count <= 0) return -1;
|
||||
return vsnprintf(str, count, fmt, args);
|
||||
|
||||
int result = vsnprintf(str, count, fmt, args);
|
||||
if ((result > 0 && (size_t)result >= count) || result == -1) {
|
||||
str[count - 1] = '\0';
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ATTRIBUTE_PRINTF(3, 0)
|
||||
|
||||
@ -2263,6 +2263,8 @@ JvmtiEnv::GetClassMethods(oop k_mirror, jint* method_count_ptr, jmethodID** meth
|
||||
int result_length = instanceK_h->methods()->length();
|
||||
jmethodID* result_list = (jmethodID*)jvmtiMalloc(result_length * sizeof(jmethodID));
|
||||
int index;
|
||||
bool jmethodids_found = true;
|
||||
|
||||
if (JvmtiExport::can_maintain_original_method_order()) {
|
||||
// Use the original method ordering indices stored in the class, so we can emit
|
||||
// jmethodIDs in the order they appeared in the class file
|
||||
@ -2270,14 +2272,40 @@ JvmtiEnv::GetClassMethods(oop k_mirror, jint* method_count_ptr, jmethodID** meth
|
||||
Method* m = instanceK_h->methods()->at(index);
|
||||
int original_index = instanceK_h->method_ordering()->at(index);
|
||||
assert(original_index >= 0 && original_index < result_length, "invalid original method index");
|
||||
jmethodID id = m->jmethod_id();
|
||||
jmethodID id;
|
||||
if (jmethodids_found) {
|
||||
id = m->find_jmethod_id_or_null();
|
||||
if (id == NULL) {
|
||||
// If we find an uninitialized value, make sure there is
|
||||
// enough space for all the uninitialized values we might
|
||||
// find.
|
||||
instanceK_h->ensure_space_for_methodids(index);
|
||||
jmethodids_found = false;
|
||||
id = m->jmethod_id();
|
||||
}
|
||||
} else {
|
||||
id = m->jmethod_id();
|
||||
}
|
||||
result_list[original_index] = id;
|
||||
}
|
||||
} else {
|
||||
// otherwise just copy in any order
|
||||
for (index = 0; index < result_length; index++) {
|
||||
Method* m = instanceK_h->methods()->at(index);
|
||||
jmethodID id = m->jmethod_id();
|
||||
jmethodID id;
|
||||
if (jmethodids_found) {
|
||||
id = m->find_jmethod_id_or_null();
|
||||
if (id == NULL) {
|
||||
// If we find an uninitialized value, make sure there is
|
||||
// enough space for all the uninitialized values we might
|
||||
// find.
|
||||
instanceK_h->ensure_space_for_methodids(index);
|
||||
jmethodids_found = false;
|
||||
id = m->jmethod_id();
|
||||
}
|
||||
} else {
|
||||
id = m->jmethod_id();
|
||||
}
|
||||
result_list[index] = id;
|
||||
}
|
||||
}
|
||||
|
||||
@ -802,8 +802,7 @@ UNSAFE_END
|
||||
|
||||
static inline void throw_new(JNIEnv *env, const char *ename) {
|
||||
char buf[100];
|
||||
strcpy(buf, "java/lang/");
|
||||
strcat(buf, ename);
|
||||
jio_snprintf(buf, 100, "%s%s", "java/lang/", ename);
|
||||
jclass cls = env->FindClass(buf);
|
||||
if (env->ExceptionCheck()) {
|
||||
env->ExceptionClear();
|
||||
|
||||
@ -282,7 +282,7 @@ WB_END
|
||||
// NMT picks it up correctly
|
||||
WB_ENTRY(jlong, WB_NMTMalloc(JNIEnv* env, jobject o, jlong size))
|
||||
jlong addr = 0;
|
||||
addr = (jlong)(uintptr_t)os::malloc(size, mtTest);
|
||||
addr = (jlong)(uintptr_t)os::malloc(size, mtTest);
|
||||
return addr;
|
||||
WB_END
|
||||
|
||||
@ -291,7 +291,7 @@ WB_END
|
||||
WB_ENTRY(jlong, WB_NMTMallocWithPseudoStack(JNIEnv* env, jobject o, jlong size, jint pseudo_stack))
|
||||
address pc = (address)(size_t)pseudo_stack;
|
||||
NativeCallStack stack(&pc, 1);
|
||||
return (jlong)os::malloc(size, mtTest, stack);
|
||||
return (jlong)(uintptr_t)os::malloc(size, mtTest, stack);
|
||||
WB_END
|
||||
|
||||
// Free the memory allocated by NMTAllocTest
|
||||
@ -326,15 +326,6 @@ WB_ENTRY(jboolean, WB_NMTIsDetailSupported(JNIEnv* env))
|
||||
return MemTracker::tracking_level() == NMT_detail;
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(void, WB_NMTOverflowHashBucket(JNIEnv* env, jobject o, jlong num))
|
||||
address pc = (address)1;
|
||||
for (jlong index = 0; index < num; index ++) {
|
||||
NativeCallStack stack(&pc, 1);
|
||||
os::malloc(0, mtTest, stack);
|
||||
pc += MallocSiteTable::hash_buckets();
|
||||
}
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jboolean, WB_NMTChangeTrackingLevel(JNIEnv* env))
|
||||
// Test that we can downgrade NMT levels but not upgrade them.
|
||||
if (MemTracker::tracking_level() == NMT_off) {
|
||||
@ -365,6 +356,12 @@ WB_ENTRY(jboolean, WB_NMTChangeTrackingLevel(JNIEnv* env))
|
||||
return MemTracker::tracking_level() == NMT_minimal;
|
||||
}
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jint, WB_NMTGetHashSize(JNIEnv* env, jobject o))
|
||||
int hash_size = MallocSiteTable::hash_buckets();
|
||||
assert(hash_size > 0, "NMT hash_size should be > 0");
|
||||
return (jint)hash_size;
|
||||
WB_END
|
||||
#endif // INCLUDE_NMT
|
||||
|
||||
static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) {
|
||||
@ -992,9 +989,9 @@ static JNINativeMethod methods[] = {
|
||||
{CC"NMTCommitMemory", CC"(JJ)V", (void*)&WB_NMTCommitMemory },
|
||||
{CC"NMTUncommitMemory", CC"(JJ)V", (void*)&WB_NMTUncommitMemory },
|
||||
{CC"NMTReleaseMemory", CC"(JJ)V", (void*)&WB_NMTReleaseMemory },
|
||||
{CC"NMTOverflowHashBucket", CC"(J)V", (void*)&WB_NMTOverflowHashBucket},
|
||||
{CC"NMTIsDetailSupported",CC"()Z", (void*)&WB_NMTIsDetailSupported},
|
||||
{CC"NMTChangeTrackingLevel", CC"()Z", (void*)&WB_NMTChangeTrackingLevel},
|
||||
{CC"NMTGetHashSize", CC"()I", (void*)&WB_NMTGetHashSize },
|
||||
#endif // INCLUDE_NMT
|
||||
{CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll },
|
||||
{CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;Z)I",
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
// Note: This is a special bug reporting site for the JVM
|
||||
#define DEFAULT_VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/crash.jsp"
|
||||
#define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp"
|
||||
#define DEFAULT_JAVA_LAUNCHER "generic"
|
||||
|
||||
// Disable options not supported in this release, with a warning if they
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/globals.hpp"
|
||||
#include "runtime/globals_extension.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/top.hpp"
|
||||
@ -818,15 +819,12 @@ bool CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Fl
|
||||
trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin);
|
||||
char* new_value = NULL;
|
||||
if (*value != NULL) {
|
||||
new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1, mtInternal);
|
||||
strcpy(new_value, *value);
|
||||
new_value = os::strdup_check_oom(*value);
|
||||
}
|
||||
result->set_ccstr(new_value);
|
||||
if (result->is_default() && old_value != NULL) {
|
||||
// Prior value is NOT heap allocated, but was a literal constant.
|
||||
char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1, mtInternal);
|
||||
strcpy(old_value_to_free, old_value);
|
||||
old_value = old_value_to_free;
|
||||
old_value = os::strdup_check_oom(old_value);
|
||||
}
|
||||
*value = old_value;
|
||||
result->set_origin(origin);
|
||||
@ -838,8 +836,7 @@ void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, F
|
||||
guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
|
||||
ccstr old_value = faddr->get_ccstr();
|
||||
trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
|
||||
char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1, mtInternal);
|
||||
strcpy(new_value, value);
|
||||
char* new_value = os::strdup_check_oom(value);
|
||||
faddr->set_ccstr(new_value);
|
||||
if (!faddr->is_default() && old_value != NULL) {
|
||||
// Prior value is heap allocated so free it.
|
||||
|
||||
@ -2066,9 +2066,6 @@ class CommandLineFlags {
|
||||
"Provide more detailed and expensive TLAB statistics " \
|
||||
"(with PrintTLAB)") \
|
||||
\
|
||||
EMBEDDED_ONLY(product(bool, LowMemoryProtection, true, \
|
||||
"Enable LowMemoryProtection")) \
|
||||
\
|
||||
product_pd(bool, NeverActAsServerClassMachine, \
|
||||
"Never act like a server-class machine") \
|
||||
\
|
||||
|
||||
@ -705,25 +705,35 @@ int JDK_Version::compare(const JDK_Version& other) const {
|
||||
}
|
||||
|
||||
void JDK_Version::to_string(char* buffer, size_t buflen) const {
|
||||
assert(buffer && buflen > 0, "call with useful buffer");
|
||||
size_t index = 0;
|
||||
|
||||
if (!is_valid()) {
|
||||
jio_snprintf(buffer, buflen, "%s", "(uninitialized)");
|
||||
} else if (is_partially_initialized()) {
|
||||
jio_snprintf(buffer, buflen, "%s", "(uninitialized) pre-1.6.0");
|
||||
} else {
|
||||
index += jio_snprintf(
|
||||
int rc = jio_snprintf(
|
||||
&buffer[index], buflen - index, "%d.%d", _major, _minor);
|
||||
if (rc == -1) return;
|
||||
index += rc;
|
||||
if (_micro > 0) {
|
||||
index += jio_snprintf(&buffer[index], buflen - index, ".%d", _micro);
|
||||
rc = jio_snprintf(&buffer[index], buflen - index, ".%d", _micro);
|
||||
}
|
||||
if (_update > 0) {
|
||||
index += jio_snprintf(&buffer[index], buflen - index, "_%02d", _update);
|
||||
rc = jio_snprintf(&buffer[index], buflen - index, "_%02d", _update);
|
||||
if (rc == -1) return;
|
||||
index += rc;
|
||||
}
|
||||
if (_special > 0) {
|
||||
index += jio_snprintf(&buffer[index], buflen - index, "%c", _special);
|
||||
rc = jio_snprintf(&buffer[index], buflen - index, "%c", _special);
|
||||
if (rc == -1) return;
|
||||
index += rc;
|
||||
}
|
||||
if (_build > 0) {
|
||||
index += jio_snprintf(&buffer[index], buflen - index, "-b%02d", _build);
|
||||
rc = jio_snprintf(&buffer[index], buflen - index, "-b%02d", _build);
|
||||
if (rc == -1) return;
|
||||
index += rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -571,17 +571,6 @@ void* os::malloc(size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
|
||||
NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
|
||||
NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
|
||||
|
||||
#if INCLUDE_NMT
|
||||
// NMT can not track malloc allocation size > MAX_MALLOC_SIZE, which is
|
||||
// (1GB - 1) on 32-bit system. It is not an issue on 64-bit system, where
|
||||
// MAX_MALLOC_SIZE = ((1 << 62) - 1).
|
||||
// VM code does not have such large malloc allocation. However, it can come
|
||||
// Unsafe call.
|
||||
if (MemTracker::tracking_level() >= NMT_summary && size > MAX_MALLOC_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ASSERT
|
||||
// checking for the WatcherThread and crash_protection first
|
||||
// since os::malloc can be called when the libjvm.{dll,so} is
|
||||
@ -652,12 +641,6 @@ void* os::realloc(void *memblock, size_t size, MEMFLAGS flags) {
|
||||
}
|
||||
|
||||
void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCallStack& stack) {
|
||||
#if INCLUDE_NMT
|
||||
// See comments in os::malloc() above
|
||||
if (MemTracker::tracking_level() >= NMT_summary && size > MAX_MALLOC_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ASSERT
|
||||
NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
|
||||
|
||||
@ -158,7 +158,6 @@ class os: AllStatic {
|
||||
static void init_globals(void) { // Called from init_globals() in init.cpp
|
||||
init_globals_ext();
|
||||
}
|
||||
static void init_3(void); // Called at the end of vm init
|
||||
|
||||
// File names are case-insensitive on windows only
|
||||
// Override me as needed
|
||||
|
||||
@ -158,7 +158,7 @@ void SignatureIterator::iterate_parameters( uint64_t fingerprint ) {
|
||||
uint64_t saved_fingerprint = fingerprint;
|
||||
|
||||
// Check for too many arguments
|
||||
if ( fingerprint == UCONST64(-1) ) {
|
||||
if (fingerprint == (uint64_t)CONST64(-1)) {
|
||||
SignatureIterator::iterate_parameters();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ class Fingerprinter: public SignatureIterator {
|
||||
}
|
||||
|
||||
if (mh->size_of_parameters() > max_size_of_parameters ) {
|
||||
_fingerprint = UCONST64(-1);
|
||||
_fingerprint = (uint64_t)CONST64(-1);
|
||||
mh->constMethod()->set_fingerprint(_fingerprint);
|
||||
return _fingerprint;
|
||||
}
|
||||
|
||||
@ -3617,9 +3617,6 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
|
||||
}
|
||||
}
|
||||
|
||||
// Give os specific code one last chance to start
|
||||
os::init_3();
|
||||
|
||||
create_vm_timer.end();
|
||||
#ifdef ASSERT
|
||||
_vm_complete = true;
|
||||
@ -3642,7 +3639,7 @@ static OnLoadEntry_t lookup_on_load(AgentLibrary* agent,
|
||||
|
||||
if (!agent->valid()) {
|
||||
char buffer[JVM_MAXPATHLEN];
|
||||
char ebuf[1024];
|
||||
char ebuf[1024] = "";
|
||||
const char *name = agent->name();
|
||||
const char *msg = "Could not find agent library ";
|
||||
|
||||
|
||||
@ -1594,6 +1594,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
|
||||
declare_type(JvmtiAgentThread, JavaThread) \
|
||||
declare_type(ServiceThread, JavaThread) \
|
||||
declare_type(CompilerThread, JavaThread) \
|
||||
declare_type(CodeCacheSweeperThread, JavaThread) \
|
||||
declare_toplevel_type(OSThread) \
|
||||
declare_toplevel_type(JavaFrameAnchor) \
|
||||
\
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
@ -143,7 +143,8 @@ typedef enum {
|
||||
JMM_VMGLOBAL_TYPE_UNKNOWN = 0,
|
||||
JMM_VMGLOBAL_TYPE_JBOOLEAN = 1,
|
||||
JMM_VMGLOBAL_TYPE_JSTRING = 2,
|
||||
JMM_VMGLOBAL_TYPE_JLONG = 3
|
||||
JMM_VMGLOBAL_TYPE_JLONG = 3,
|
||||
JMM_VMGLOBAL_TYPE_JDOUBLE = 4
|
||||
} jmmVMGlobalType;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@ -72,7 +72,7 @@ void MallocHeader::release() const {
|
||||
|
||||
MallocMemorySummary::record_free(size(), flags());
|
||||
MallocMemorySummary::record_free_malloc_header(sizeof(MallocHeader));
|
||||
if (tracking_level() == NMT_detail) {
|
||||
if (MemTracker::tracking_level() == NMT_detail) {
|
||||
MallocSiteTable::deallocation_at(size(), _bucket_idx, _pos_idx);
|
||||
}
|
||||
}
|
||||
@ -128,36 +128,18 @@ void* MallocTracker::record_malloc(void* malloc_base, size_t size, MEMFLAGS flag
|
||||
}
|
||||
|
||||
// Uses placement global new operator to initialize malloc header
|
||||
switch(level) {
|
||||
case NMT_off:
|
||||
return malloc_base;
|
||||
case NMT_minimal: {
|
||||
MallocHeader* hdr = ::new (malloc_base) MallocHeader();
|
||||
break;
|
||||
}
|
||||
case NMT_summary: {
|
||||
assert(size <= MAX_MALLOC_SIZE, "malloc size overrun for NMT");
|
||||
header = ::new (malloc_base) MallocHeader(size, flags);
|
||||
break;
|
||||
}
|
||||
case NMT_detail: {
|
||||
assert(size <= MAX_MALLOC_SIZE, "malloc size overrun for NMT");
|
||||
header = ::new (malloc_base) MallocHeader(size, flags, stack);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
|
||||
if (level == NMT_off) {
|
||||
return malloc_base;
|
||||
}
|
||||
|
||||
header = ::new (malloc_base)MallocHeader(size, flags, stack, level);
|
||||
memblock = (void*)((char*)malloc_base + sizeof(MallocHeader));
|
||||
|
||||
// The alignment check: 8 bytes alignment for 32 bit systems.
|
||||
// 16 bytes alignment for 64-bit systems.
|
||||
assert(((size_t)memblock & (sizeof(size_t) * 2 - 1)) == 0, "Alignment check");
|
||||
|
||||
// Sanity check
|
||||
assert(get_memory_tracking_level(memblock) == level,
|
||||
"Wrong tracking level");
|
||||
|
||||
#ifdef ASSERT
|
||||
if (level > NMT_minimal) {
|
||||
// Read back
|
||||
|
||||
@ -239,68 +239,46 @@ class MallocMemorySummary : AllStatic {
|
||||
|
||||
class MallocHeader VALUE_OBJ_CLASS_SPEC {
|
||||
#ifdef _LP64
|
||||
size_t _size : 62;
|
||||
size_t _level : 2;
|
||||
size_t _size : 64;
|
||||
size_t _flags : 8;
|
||||
size_t _pos_idx : 16;
|
||||
size_t _bucket_idx: 40;
|
||||
#define MAX_MALLOCSITE_TABLE_SIZE ((size_t)1 << 40)
|
||||
#define MAX_BUCKET_LENGTH ((size_t)(1 << 16))
|
||||
#define MAX_MALLOC_SIZE (((size_t)1 << 62) - 1)
|
||||
#else
|
||||
size_t _size : 30;
|
||||
size_t _level : 2;
|
||||
size_t _size : 32;
|
||||
size_t _flags : 8;
|
||||
size_t _pos_idx : 8;
|
||||
size_t _bucket_idx: 16;
|
||||
#define MAX_MALLOCSITE_TABLE_SIZE ((size_t)(1 << 16))
|
||||
#define MAX_BUCKET_LENGTH ((size_t)(1 << 8))
|
||||
// Max malloc size = 1GB - 1 on 32 bit system, such has total 4GB memory
|
||||
#define MAX_MALLOC_SIZE ((size_t)(1 << 30) - 1)
|
||||
#endif // _LP64
|
||||
|
||||
public:
|
||||
// Summary tracking header
|
||||
MallocHeader(size_t size, MEMFLAGS flags) {
|
||||
MallocHeader(size_t size, MEMFLAGS flags, const NativeCallStack& stack, NMT_TrackingLevel level) {
|
||||
assert(sizeof(MallocHeader) == sizeof(void*) * 2,
|
||||
"Wrong header size");
|
||||
|
||||
_level = NMT_summary;
|
||||
_flags = flags;
|
||||
set_size(size);
|
||||
MallocMemorySummary::record_malloc(size, flags);
|
||||
MallocMemorySummary::record_new_malloc_header(sizeof(MallocHeader));
|
||||
}
|
||||
// Detail tracking header
|
||||
MallocHeader(size_t size, MEMFLAGS flags, const NativeCallStack& stack) {
|
||||
assert(sizeof(MallocHeader) == sizeof(void*) * 2,
|
||||
"Wrong header size");
|
||||
|
||||
_level = NMT_detail;
|
||||
_flags = flags;
|
||||
set_size(size);
|
||||
size_t bucket_idx;
|
||||
size_t pos_idx;
|
||||
if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) {
|
||||
assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index");
|
||||
assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index");
|
||||
_bucket_idx = bucket_idx;
|
||||
_pos_idx = pos_idx;
|
||||
if (level == NMT_minimal) {
|
||||
return;
|
||||
}
|
||||
|
||||
_flags = flags;
|
||||
set_size(size);
|
||||
if (level == NMT_detail) {
|
||||
size_t bucket_idx;
|
||||
size_t pos_idx;
|
||||
if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) {
|
||||
assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index");
|
||||
assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index");
|
||||
_bucket_idx = bucket_idx;
|
||||
_pos_idx = pos_idx;
|
||||
}
|
||||
}
|
||||
|
||||
MallocMemorySummary::record_malloc(size, flags);
|
||||
MallocMemorySummary::record_new_malloc_header(sizeof(MallocHeader));
|
||||
}
|
||||
// Minimal tracking header
|
||||
MallocHeader() {
|
||||
assert(sizeof(MallocHeader) == sizeof(void*) * 2,
|
||||
"Wrong header size");
|
||||
|
||||
_level = (unsigned short)NMT_minimal;
|
||||
}
|
||||
|
||||
inline NMT_TrackingLevel tracking_level() const {
|
||||
return (NMT_TrackingLevel)_level;
|
||||
}
|
||||
|
||||
inline size_t size() const { return _size; }
|
||||
inline MEMFLAGS flags() const { return (MEMFLAGS)_flags; }
|
||||
@ -311,7 +289,6 @@ class MallocHeader VALUE_OBJ_CLASS_SPEC {
|
||||
|
||||
private:
|
||||
inline void set_size(size_t size) {
|
||||
assert(size <= MAX_MALLOC_SIZE, "Malloc size too large, should use virtual memory?");
|
||||
_size = size;
|
||||
}
|
||||
bool record_malloc_site(const NativeCallStack& stack, size_t size,
|
||||
@ -347,10 +324,6 @@ class MallocTracker : AllStatic {
|
||||
// Record free on specified memory block
|
||||
static void* record_free(void* memblock);
|
||||
|
||||
// Get tracking level of specified memory block
|
||||
static inline NMT_TrackingLevel get_memory_tracking_level(void* memblock);
|
||||
|
||||
|
||||
// Offset memory address to header address
|
||||
static inline void* get_base(void* memblock);
|
||||
static inline void* get_base(void* memblock, NMT_TrackingLevel level) {
|
||||
@ -361,16 +334,12 @@ class MallocTracker : AllStatic {
|
||||
// Get memory size
|
||||
static inline size_t get_size(void* memblock) {
|
||||
MallocHeader* header = malloc_header(memblock);
|
||||
assert(header->tracking_level() >= NMT_summary,
|
||||
"Wrong tracking level");
|
||||
return header->size();
|
||||
}
|
||||
|
||||
// Get memory type
|
||||
static inline MEMFLAGS get_flags(void* memblock) {
|
||||
MallocHeader* header = malloc_header(memblock);
|
||||
assert(header->tracking_level() >= NMT_summary,
|
||||
"Wrong tracking level");
|
||||
return header->flags();
|
||||
}
|
||||
|
||||
@ -394,7 +363,6 @@ class MallocTracker : AllStatic {
|
||||
static inline MallocHeader* malloc_header(void *memblock) {
|
||||
assert(memblock != NULL, "NULL pointer");
|
||||
MallocHeader* header = (MallocHeader*)((char*)memblock - sizeof(MallocHeader));
|
||||
assert(header->tracking_level() >= NMT_minimal, "Bad header");
|
||||
return header;
|
||||
}
|
||||
};
|
||||
|
||||
@ -28,13 +28,6 @@
|
||||
#include "services/mallocTracker.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
|
||||
inline NMT_TrackingLevel MallocTracker::get_memory_tracking_level(void* memblock) {
|
||||
assert(memblock != NULL, "Sanity check");
|
||||
if (MemTracker::tracking_level() == NMT_off) return NMT_off;
|
||||
MallocHeader* header = malloc_header(memblock);
|
||||
return header->tracking_level();
|
||||
}
|
||||
|
||||
inline void* MallocTracker::get_base(void* memblock){
|
||||
return get_base(memblock, MemTracker::tracking_level());
|
||||
}
|
||||
|
||||
@ -1333,7 +1333,7 @@ JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboo
|
||||
GrowableArray<oop>* locked_monitors = frame->locked_monitors();
|
||||
for (j = 0; j < len; j++) {
|
||||
oop monitor = locked_monitors->at(j);
|
||||
assert(monitor != NULL && monitor->is_instance(), "must be a Java object");
|
||||
assert(monitor != NULL, "must be a Java object");
|
||||
monitors_array->obj_at_put(count, monitor);
|
||||
depths_array->int_at_put(count, depth);
|
||||
count++;
|
||||
@ -1343,7 +1343,7 @@ JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboo
|
||||
GrowableArray<oop>* jni_locked_monitors = stacktrace->jni_locked_monitors();
|
||||
for (j = 0; j < jni_locked_monitors->length(); j++) {
|
||||
oop object = jni_locked_monitors->at(j);
|
||||
assert(object != NULL && object->is_instance(), "must be a Java object");
|
||||
assert(object != NULL, "must be a Java object");
|
||||
monitors_array->obj_at_put(count, object);
|
||||
// Monitor locked via JNI MonitorEnter call doesn't have stack depth info
|
||||
depths_array->int_at_put(count, -1);
|
||||
@ -1572,6 +1572,9 @@ bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag,
|
||||
} else if (flag->is_uint64_t()) {
|
||||
global->value.j = (jlong)flag->get_uint64_t();
|
||||
global->type = JMM_VMGLOBAL_TYPE_JLONG;
|
||||
} else if (flag->is_double()) {
|
||||
global->value.d = (jdouble)flag->get_double();
|
||||
global->type = JMM_VMGLOBAL_TYPE_JDOUBLE;
|
||||
} else if (flag->is_size_t()) {
|
||||
global->value.j = (jlong)flag->get_size_t();
|
||||
global->type = JMM_VMGLOBAL_TYPE_JLONG;
|
||||
|
||||
@ -38,6 +38,7 @@ PerfCounter* RuntimeService::_sync_time_ticks = NULL;
|
||||
PerfCounter* RuntimeService::_total_safepoints = NULL;
|
||||
PerfCounter* RuntimeService::_safepoint_time_ticks = NULL;
|
||||
PerfCounter* RuntimeService::_application_time_ticks = NULL;
|
||||
double RuntimeService::_last_safepoint_sync_time_sec = 0.0;
|
||||
|
||||
void RuntimeService::init() {
|
||||
// Make sure the VM version is initialized
|
||||
@ -96,6 +97,7 @@ void RuntimeService::record_safepoint_begin() {
|
||||
|
||||
// update the time stamp to begin recording safepoint time
|
||||
_safepoint_timer.update();
|
||||
_last_safepoint_sync_time_sec = 0.0;
|
||||
if (UsePerfData) {
|
||||
_total_safepoints->inc();
|
||||
if (_app_timer.is_updated()) {
|
||||
@ -108,6 +110,9 @@ void RuntimeService::record_safepoint_synchronized() {
|
||||
if (UsePerfData) {
|
||||
_sync_time_ticks->inc(_safepoint_timer.ticks_since_update());
|
||||
}
|
||||
if (PrintGCApplicationStoppedTime) {
|
||||
_last_safepoint_sync_time_sec = last_safepoint_time_sec();
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeService::record_safepoint_end() {
|
||||
@ -119,8 +124,10 @@ void RuntimeService::record_safepoint_end() {
|
||||
gclog_or_tty->date_stamp(PrintGCDateStamps);
|
||||
gclog_or_tty->stamp(PrintGCTimeStamps);
|
||||
gclog_or_tty->print_cr("Total time for which application threads "
|
||||
"were stopped: %3.7f seconds",
|
||||
last_safepoint_time_sec());
|
||||
"were stopped: %3.7f seconds, "
|
||||
"Stopping threads took: %3.7f seconds",
|
||||
last_safepoint_time_sec(),
|
||||
_last_safepoint_sync_time_sec);
|
||||
}
|
||||
|
||||
// update the time stamp to begin recording app time
|
||||
|
||||
@ -37,6 +37,7 @@ private:
|
||||
|
||||
static TimeStamp _safepoint_timer;
|
||||
static TimeStamp _app_timer;
|
||||
static double _last_safepoint_sync_time_sec;
|
||||
|
||||
public:
|
||||
static void init();
|
||||
|
||||
@ -597,7 +597,7 @@ bool ThreadStackTrace::is_owned_monitor_on_stack(oop object) {
|
||||
GrowableArray<oop>* locked_monitors = frame->locked_monitors();
|
||||
for (int j = 0; j < len; j++) {
|
||||
oop monitor = locked_monitors->at(j);
|
||||
assert(monitor != NULL && monitor->is_instance(), "must be a Java object");
|
||||
assert(monitor != NULL, "must be a Java object");
|
||||
if (monitor == object) {
|
||||
found = true;
|
||||
break;
|
||||
|
||||
@ -1048,7 +1048,7 @@ const int badHandleValue = 0xBC; // value used to zap
|
||||
const int badResourceValue = 0xAB; // value used to zap resource area
|
||||
const int freeBlockPad = 0xBA; // value used to pad freed blocks.
|
||||
const int uninitBlockPad = 0xF1; // value used to zap newly malloc'd blocks.
|
||||
const intptr_t badJNIHandleVal = (intptr_t) CONST64(0xFEFEFEFEFEFEFEFE); // value used to zap jni handle area
|
||||
const intptr_t badJNIHandleVal = (intptr_t) UCONST64(0xFEFEFEFEFEFEFEFE); // value used to zap jni handle area
|
||||
const juint badHeapWordVal = 0xBAADBABE; // value used to zap heap after GC
|
||||
const juint badMetaWordVal = 0xBAADFADE; // value used to zap metadata heap after GC
|
||||
const int badCodeHeapNewVal= 0xCC; // value used to zap Code heap at allocation
|
||||
|
||||
@ -151,11 +151,11 @@ inline int g_isfinite(jdouble f) { return _finite(f); }
|
||||
// Constant for jlong (specifying an long long constant is C++ compiler specific)
|
||||
|
||||
// Build a 64bit integer constant on with Visual C++
|
||||
#define CONST64(x) (x ## i64)
|
||||
#define UCONST64(x) ((uint64_t)CONST64(x))
|
||||
#define CONST64(x) (x ## i64)
|
||||
#define UCONST64(x) (x ## ui64)
|
||||
|
||||
const jlong min_jlong = CONST64(0x8000000000000000);
|
||||
const jlong max_jlong = CONST64(0x7fffffffffffffff);
|
||||
const jlong min_jlong = (jlong)UCONST64(0x8000000000000000);
|
||||
const jlong max_jlong = CONST64(0x7fffffffffffffff);
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Miscellaneous
|
||||
|
||||
@ -76,6 +76,8 @@ const char* outputStream::do_vsnprintf(char* buffer, size_t buflen,
|
||||
const char* format, va_list ap,
|
||||
bool add_cr,
|
||||
size_t& result_len) {
|
||||
assert(buflen >= 2, "buffer too small");
|
||||
|
||||
const char* result;
|
||||
if (add_cr) buflen--;
|
||||
if (!strchr(format, '%')) {
|
||||
@ -88,14 +90,21 @@ const char* outputStream::do_vsnprintf(char* buffer, size_t buflen,
|
||||
result = va_arg(ap, const char*);
|
||||
result_len = strlen(result);
|
||||
if (add_cr && result_len >= buflen) result_len = buflen-1; // truncate
|
||||
} else if (vsnprintf(buffer, buflen, format, ap) >= 0) {
|
||||
result = buffer;
|
||||
result_len = strlen(result);
|
||||
} else {
|
||||
DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");)
|
||||
// Handle truncation:
|
||||
// posix: upon truncation, vsnprintf returns number of bytes which
|
||||
// would have been written (excluding terminating zero) had the buffer
|
||||
// been large enough
|
||||
// windows: upon truncation, vsnprintf returns -1
|
||||
const int written = vsnprintf(buffer, buflen, format, ap);
|
||||
result = buffer;
|
||||
result_len = buflen - 1;
|
||||
buffer[result_len] = 0;
|
||||
if (written < (int) buflen && written >= 0) {
|
||||
result_len = written;
|
||||
} else {
|
||||
DEBUG_ONLY(warning("increase O_BUFLEN in ostream.hpp -- output truncated");)
|
||||
result_len = buflen - 1;
|
||||
buffer[result_len] = 0;
|
||||
}
|
||||
}
|
||||
if (add_cr) {
|
||||
if (result != buffer) {
|
||||
|
||||
@ -975,11 +975,13 @@ void VMError::report_and_die() {
|
||||
// Run error reporting to determine whether or not to report the crash.
|
||||
if (!transmit_report_done && should_report_bug(first_error->_id)) {
|
||||
transmit_report_done = true;
|
||||
FILE* hs_err = os::open(log.fd(), "r");
|
||||
const int fd2 = ::dup(log.fd());
|
||||
FILE* const hs_err = ::fdopen(fd2, "r");
|
||||
if (NULL != hs_err) {
|
||||
ErrorReporter er;
|
||||
er.call(hs_err, buffer, O_BUFLEN);
|
||||
}
|
||||
::fclose(hs_err);
|
||||
}
|
||||
|
||||
if (log.fd() != defaultStream::output_fd()) {
|
||||
|
||||
@ -30,3 +30,4 @@
|
||||
keys=cte_test jcmd nmt regression gc stress
|
||||
|
||||
groups=TEST.groups [closed/TEST.groups]
|
||||
requires.properties=sun.arch.data.model
|
||||
|
||||
@ -87,7 +87,6 @@ needs_jdk = \
|
||||
runtime/NMT/SummarySanityCheck.java \
|
||||
runtime/NMT/ThreadedMallocTestType.java \
|
||||
runtime/NMT/ThreadedVirtualAllocTestType.java \
|
||||
runtime/NMT/UnsafeMallocLimit.java \
|
||||
runtime/NMT/VirtualAllocCommitUncommitRecommit.java \
|
||||
runtime/NMT/VirtualAllocTestType.java \
|
||||
runtime/RedefineObject/TestRedefineObject.java \
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
* @summary Creates several threads with different java priorities and checks
|
||||
* whether jstack reports correct priorities for them.
|
||||
*
|
||||
* @ignore 8060219
|
||||
* @run main Test7194254
|
||||
*/
|
||||
|
||||
|
||||
@ -24,41 +24,56 @@
|
||||
/*
|
||||
* @test
|
||||
* @summary Test corner case that overflows malloc site hashtable bucket
|
||||
* @requires sun.arch.data.model == "32"
|
||||
* @key nmt jcmd stress
|
||||
* @library /testlibrary /testlibrary/whitebox
|
||||
* @ignore - This test is disabled since it will stress NMT and timeout during normal testing
|
||||
* @ignore 8062870
|
||||
* @build MallocSiteHashOverflow
|
||||
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||
* @run main/othervm/timeout=480 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocSiteHashOverflow
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocSiteHashOverflow
|
||||
*/
|
||||
|
||||
import com.oracle.java.testlibrary.*;
|
||||
import sun.hotspot.WhiteBox;
|
||||
|
||||
public class MallocSiteHashOverflow {
|
||||
private static long K = 1024;
|
||||
public static void main(String args[]) throws Exception {
|
||||
String vm_name = System.getProperty("java.vm.name");
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
|
||||
// Size of entries based on malloc tracking header defined in mallocTracker.hpp
|
||||
// For 32-bit systems, create 257 malloc sites with the same hash bucket to overflow a hash bucket
|
||||
// For 64-bit systems, create 64K + 1 malloc sites with the same hash bucket to overflow a hash bucket
|
||||
long entries = 257;
|
||||
if (Platform.is64bit()) {
|
||||
entries = 64 * K + 1;
|
||||
}
|
||||
|
||||
OutputAnalyzer output;
|
||||
WhiteBox wb = WhiteBox.getWhiteBox();
|
||||
int MAX_HASH_SIZE = wb.NMTGetHashSize();
|
||||
|
||||
// Grab my own PID
|
||||
String pid = Integer.toString(ProcessTools.getProcessId());
|
||||
ProcessBuilder pb = new ProcessBuilder();
|
||||
|
||||
wb.NMTOverflowHashBucket(entries);
|
||||
|
||||
// Run 'jcmd <pid> VM.native_memory summary'
|
||||
// Verify that current tracking level is "detail"
|
||||
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "statistics"});
|
||||
output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain("Tracking level has been downgraded due to lack of resources");
|
||||
output.shouldContain("Native Memory Tracking Statistics");
|
||||
|
||||
// Attempt to cause NMT to downgrade tracking level by allocating small amounts
|
||||
// of memory with random pseudo call stack
|
||||
int pc = 1;
|
||||
for (int i = 0; i < entries; i++) {
|
||||
long addr = wb.NMTMallocWithPseudoStack(1, pc);
|
||||
if (addr == 0) {
|
||||
throw new RuntimeException("NMTMallocWithPseudoStack: out of memory");
|
||||
}
|
||||
// We free memory here since it doesn't affect pseudo malloc alloc site hash table entries
|
||||
wb.NMTFree(addr);
|
||||
pc += MAX_HASH_SIZE;
|
||||
if (i == entries) {
|
||||
// Verify that tracking has been downgraded
|
||||
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "statistics"});
|
||||
output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain("Tracking level has been downgraded due to lack of resources");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ import java.util.Random;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @ignore 8061157
|
||||
* @bug 8016304
|
||||
* @summary Make sure no deadlock is reported for this program which has no deadlocks.
|
||||
* @library /testlibrary
|
||||
|
||||
@ -98,10 +98,10 @@ public class WhiteBox {
|
||||
public native void NMTCommitMemory(long addr, long size);
|
||||
public native void NMTUncommitMemory(long addr, long size);
|
||||
public native void NMTReleaseMemory(long addr, long size);
|
||||
public native void NMTOverflowHashBucket(long num);
|
||||
public native long NMTMallocWithPseudoStack(long size, int index);
|
||||
public native boolean NMTIsDetailSupported();
|
||||
public native boolean NMTChangeTrackingLevel();
|
||||
public native int NMTGetHashSize();
|
||||
|
||||
// Compiler
|
||||
public native void deoptimizeAll();
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
*/
|
||||
|
||||
public class DoubleTest {
|
||||
private static final String FLAG_NAME = null;
|
||||
private static final String FLAG_NAME = "CompileThresholdScaling";
|
||||
private static final Double[] TESTS = {0d, -0d, -1d, 1d,
|
||||
Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN,
|
||||
Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY};
|
||||
|
||||
@ -280,3 +280,4 @@ b940ca3d2c7e8a279ca850706b89c2ad3a841e82 jdk9-b32
|
||||
b9370464572fc663a38956047aa612d6e7854c3d jdk9-b35
|
||||
61b4c9acaa58e482db6601ec5dc4fc3d2d8dbb55 jdk9-b36
|
||||
48e4ec70cc1c8651e4a0324d91f193c4edd83af9 jdk9-b37
|
||||
6c6b34477e93e6fb350035f73ed7c02266b78380 jdk9-b38
|
||||
|
||||
@ -383,6 +383,8 @@ public class XMLDocumentFragmentScannerImpl
|
||||
|
||||
protected boolean foundBuiltInRefs = false;
|
||||
|
||||
/** Built-in reference character event */
|
||||
protected boolean builtInRefCharacterHandled = false;
|
||||
|
||||
//skip element algorithm
|
||||
static final short MAX_DEPTH_LIMIT = 5 ;
|
||||
@ -1949,7 +1951,10 @@ public class XMLDocumentFragmentScannerImpl
|
||||
fDocumentHandler.startGeneralEntity(entity, null, null, null);
|
||||
}
|
||||
fTempString.setValues(fSingleChar, 0, 1);
|
||||
//fDocumentHandler.characters(fTempString, null);
|
||||
if(!fIsCoalesce){
|
||||
fDocumentHandler.characters(fTempString, null);
|
||||
builtInRefCharacterHandled = true;
|
||||
}
|
||||
|
||||
if (fNotifyBuiltInRefs) {
|
||||
fDocumentHandler.endGeneralEntity(entity, null);
|
||||
@ -3068,7 +3073,12 @@ public class XMLDocumentFragmentScannerImpl
|
||||
//return CHARACTERS
|
||||
if(fScannerState == SCANNER_STATE_BUILT_IN_REFS && !fIsCoalesce){
|
||||
setScannerState(SCANNER_STATE_CONTENT);
|
||||
return XMLEvent.CHARACTERS;
|
||||
if (builtInRefCharacterHandled) {
|
||||
builtInRefCharacterHandled = false;
|
||||
return XMLEvent.ENTITY_REFERENCE;
|
||||
} else {
|
||||
return XMLEvent.CHARACTERS;
|
||||
}
|
||||
}
|
||||
|
||||
//if there was a text declaration, call next() it will be taken care.
|
||||
|
||||
@ -283,3 +283,4 @@ e58d3ea638c3824f01547596b2a98aa5f77c4a5c jdk9-b30
|
||||
afe0c89e2edbdfb1a7ceff3d9b3ff46c4186202f jdk9-b35
|
||||
84803c3be7f79d29c7dc40749d7743675f64107a jdk9-b36
|
||||
90de6ecbff46386a3f9d6f7ca876e7aa6381f50a jdk9-b37
|
||||
dd4ba422dba858b1c3c4b38f49a3e514be4e2790 jdk9-b38
|
||||
|
||||
@ -280,3 +280,4 @@ f0870554049807d3392bd7976ab114f7f2b7bafa jdk9-b27
|
||||
e549291a0227031310fa91c574891f892d27f959 jdk9-b35
|
||||
cdcf2e599e42935c2d1d19a24bb19e808aeb43b5 jdk9-b36
|
||||
27c3345d6dce39a22c262f30bb1f0e0b00c3709e jdk9-b37
|
||||
d2d745313c81d1fc01f426983b9f784ab1f750e8 jdk9-b38
|
||||
|
||||
@ -29,12 +29,10 @@ import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.CodeSource;
|
||||
import java.security.Policy;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
@ -54,7 +52,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import sun.misc.CompoundEnumeration;
|
||||
import sun.misc.Resource;
|
||||
import sun.misc.URLClassPath;
|
||||
import sun.misc.VM;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
@ -268,8 +265,8 @@ public abstract class ClassLoader {
|
||||
|
||||
// The packages defined in this class loader. Each package name is mapped
|
||||
// to its corresponding Package object.
|
||||
// @GuardedBy("itself")
|
||||
private final HashMap<String, Package> packages = new HashMap<>();
|
||||
private final ConcurrentHashMap<String, Package> packages
|
||||
= new ConcurrentHashMap<>();
|
||||
|
||||
private static Void checkCreateClassLoader() {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
@ -1575,17 +1572,17 @@ public abstract class ClassLoader {
|
||||
String implVendor, URL sealBase)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
synchronized (packages) {
|
||||
Package pkg = getPackage(name);
|
||||
if (pkg != null) {
|
||||
throw new IllegalArgumentException(name);
|
||||
}
|
||||
pkg = new Package(name, specTitle, specVersion, specVendor,
|
||||
implTitle, implVersion, implVendor,
|
||||
sealBase, this);
|
||||
packages.put(name, pkg);
|
||||
return pkg;
|
||||
Package pkg = getPackage(name);
|
||||
if (pkg != null) {
|
||||
throw new IllegalArgumentException(name);
|
||||
}
|
||||
pkg = new Package(name, specTitle, specVersion, specVendor,
|
||||
implTitle, implVersion, implVendor,
|
||||
sealBase, this);
|
||||
if (packages.putIfAbsent(name, pkg) != null) {
|
||||
throw new IllegalArgumentException(name);
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1601,26 +1598,13 @@ public abstract class ClassLoader {
|
||||
* @since 1.2
|
||||
*/
|
||||
protected Package getPackage(String name) {
|
||||
Package pkg;
|
||||
synchronized (packages) {
|
||||
pkg = packages.get(name);
|
||||
}
|
||||
Package pkg = packages.get(name);
|
||||
if (pkg == null) {
|
||||
if (parent != null) {
|
||||
pkg = parent.getPackage(name);
|
||||
} else {
|
||||
pkg = Package.getSystemPackage(name);
|
||||
}
|
||||
if (pkg != null) {
|
||||
synchronized (packages) {
|
||||
Package pkg2 = packages.get(name);
|
||||
if (pkg2 == null) {
|
||||
packages.put(name, pkg);
|
||||
} else {
|
||||
pkg = pkg2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
@ -1635,22 +1619,18 @@ public abstract class ClassLoader {
|
||||
* @since 1.2
|
||||
*/
|
||||
protected Package[] getPackages() {
|
||||
Map<String, Package> map;
|
||||
synchronized (packages) {
|
||||
map = new HashMap<>(packages);
|
||||
}
|
||||
Package[] pkgs;
|
||||
if (parent != null) {
|
||||
pkgs = parent.getPackages();
|
||||
} else {
|
||||
pkgs = Package.getSystemPackages();
|
||||
}
|
||||
|
||||
Map<String, Package> map = packages;
|
||||
if (pkgs != null) {
|
||||
map = new HashMap<>(packages);
|
||||
for (Package pkg : pkgs) {
|
||||
String pkgName = pkg.getName();
|
||||
if (map.get(pkgName) == null) {
|
||||
map.put(pkgName, pkg);
|
||||
}
|
||||
map.putIfAbsent(pkg.getName(), pkg);
|
||||
}
|
||||
}
|
||||
return map.values().toArray(new Package[map.size()]);
|
||||
|
||||
@ -26,27 +26,21 @@
|
||||
package java.lang;
|
||||
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.Attributes.Name;
|
||||
import java.util.jar.JarException;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import sun.net.www.ParseUtil;
|
||||
import sun.reflect.CallerSensitive;
|
||||
@ -538,17 +532,15 @@ public class Package implements java.lang.reflect.AnnotatedElement {
|
||||
* Returns the loaded system package for the specified name.
|
||||
*/
|
||||
static Package getSystemPackage(String name) {
|
||||
synchronized (pkgs) {
|
||||
Package pkg = pkgs.get(name);
|
||||
if (pkg == null) {
|
||||
name = name.replace('.', '/').concat("/");
|
||||
String fn = getSystemPackage0(name);
|
||||
if (fn != null) {
|
||||
pkg = defineSystemPackage(name, fn);
|
||||
}
|
||||
Package pkg = pkgs.get(name);
|
||||
if (pkg == null) {
|
||||
name = name.replace('.', '/').concat("/");
|
||||
String fn = getSystemPackage0(name);
|
||||
if (fn != null) {
|
||||
pkg = defineSystemPackage(name, fn);
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -557,74 +549,98 @@ public class Package implements java.lang.reflect.AnnotatedElement {
|
||||
static Package[] getSystemPackages() {
|
||||
// First, update the system package map with new package names
|
||||
String[] names = getSystemPackages0();
|
||||
synchronized (pkgs) {
|
||||
for (String name : names) {
|
||||
for (String name : names) {
|
||||
if (!pkgs.containsKey(name)) {
|
||||
defineSystemPackage(name, getSystemPackage0(name));
|
||||
}
|
||||
return pkgs.values().toArray(new Package[pkgs.size()]);
|
||||
}
|
||||
return pkgs.values().toArray(new Package[pkgs.size()]);
|
||||
}
|
||||
|
||||
private static Package defineSystemPackage(final String iname,
|
||||
final String fn)
|
||||
{
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Package>() {
|
||||
public Package run() {
|
||||
String name = iname;
|
||||
// Get the cached code source url for the file name
|
||||
URL url = urls.get(fn);
|
||||
if (url == null) {
|
||||
// URL not found, so create one
|
||||
File file = new File(fn);
|
||||
try {
|
||||
url = ParseUtil.fileToEncodedURL(file);
|
||||
} catch (MalformedURLException e) {
|
||||
}
|
||||
if (url != null) {
|
||||
urls.put(fn, url);
|
||||
// If loading a JAR file, then also cache the manifest
|
||||
if (file.isFile()) {
|
||||
mans.put(fn, loadManifest(fn));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Convert to "."-separated package name
|
||||
name = name.substring(0, name.length() - 1).replace('/', '.');
|
||||
Package pkg;
|
||||
Manifest man = mans.get(fn);
|
||||
if (man != null) {
|
||||
pkg = new Package(name, man, url, null);
|
||||
} else {
|
||||
pkg = new Package(name, null, null, null,
|
||||
null, null, null, null, null);
|
||||
}
|
||||
pkgs.put(name, pkg);
|
||||
return pkg;
|
||||
}
|
||||
});
|
||||
// Convert to "."-separated package name
|
||||
String name = iname.substring(0, iname.length() - 1).replace('/', '.');
|
||||
// Creates a cached manifest for the file name, allowing
|
||||
// only-once, lazy reads of manifest from jar files
|
||||
CachedManifest cachedManifest = createCachedManifest(fn);
|
||||
pkgs.putIfAbsent(name, new Package(name, cachedManifest.getManifest(),
|
||||
cachedManifest.getURL(), null));
|
||||
// Ensure we only expose one Package object
|
||||
return pkgs.get(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the Manifest for the specified JAR file name.
|
||||
*/
|
||||
private static Manifest loadManifest(String fn) {
|
||||
try (FileInputStream fis = new FileInputStream(fn);
|
||||
JarInputStream jis = new JarInputStream(fis, false))
|
||||
{
|
||||
return jis.getManifest();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
private static CachedManifest createCachedManifest(String fn) {
|
||||
if (!manifests.containsKey(fn)) {
|
||||
manifests.putIfAbsent(fn, new CachedManifest(fn));
|
||||
}
|
||||
return manifests.get(fn);
|
||||
}
|
||||
|
||||
// The map of loaded system packages
|
||||
private static Map<String, Package> pkgs = new HashMap<>(31);
|
||||
private static final ConcurrentHashMap<String, Package> pkgs
|
||||
= new ConcurrentHashMap<>();
|
||||
|
||||
// Maps each directory or zip file name to its corresponding url
|
||||
private static Map<String, URL> urls = new HashMap<>(10);
|
||||
// Maps each directory or zip file name to its corresponding manifest, if
|
||||
// it exists
|
||||
private static final ConcurrentHashMap<String, CachedManifest> manifests
|
||||
= new ConcurrentHashMap<>();
|
||||
|
||||
// Maps each code source url for a jar file to its manifest
|
||||
private static Map<String, Manifest> mans = new HashMap<>(10);
|
||||
private static class CachedManifest {
|
||||
private static final Manifest EMPTY_MANIFEST = new Manifest();
|
||||
private final String fileName;
|
||||
private final URL url;
|
||||
private volatile Manifest manifest;
|
||||
|
||||
CachedManifest(final String fileName) {
|
||||
this.fileName = fileName;
|
||||
this.url = AccessController.doPrivileged(new PrivilegedAction<URL>() {
|
||||
public URL run() {
|
||||
final File file = new File(fileName);
|
||||
if (file.isFile()) {
|
||||
try {
|
||||
return ParseUtil.fileToEncodedURL(file);
|
||||
} catch (MalformedURLException e) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public URL getURL() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public Manifest getManifest() {
|
||||
if (url == null) {
|
||||
return EMPTY_MANIFEST;
|
||||
}
|
||||
Manifest m = manifest;
|
||||
if (m != null) {
|
||||
return m;
|
||||
}
|
||||
synchronized (this) {
|
||||
m = manifest;
|
||||
if (m != null) {
|
||||
return m;
|
||||
}
|
||||
m = AccessController.doPrivileged(new PrivilegedAction<Manifest>() {
|
||||
public Manifest run() {
|
||||
try (FileInputStream fis = new FileInputStream(fileName);
|
||||
JarInputStream jis = new JarInputStream(fis, false)) {
|
||||
return jis.getManifest();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
manifest = m = (m == null ? EMPTY_MANIFEST : m);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
private static native String getSystemPackage0(String name);
|
||||
private static native String[] getSystemPackages0();
|
||||
|
||||
@ -1388,16 +1388,26 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
Object a4, Object a5, Object a6, Object a7,
|
||||
Object a8, Object a9)
|
||||
{ return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
|
||||
|
||||
private static final int ARRAYS_COUNT = 11;
|
||||
|
||||
private static MethodHandle[] makeArrays() {
|
||||
ArrayList<MethodHandle> mhs = new ArrayList<>();
|
||||
for (;;) {
|
||||
MethodHandle mh = findCollector("array", mhs.size(), Object[].class);
|
||||
if (mh == null) break;
|
||||
MethodHandle[] mhs = new MethodHandle[MAX_ARITY + 1];
|
||||
for (int i = 0; i < ARRAYS_COUNT; i++) {
|
||||
MethodHandle mh = findCollector("array", i, Object[].class);
|
||||
mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
|
||||
mhs.add(mh);
|
||||
mhs[i] = mh;
|
||||
}
|
||||
assert(mhs.size() == 11); // current number of methods
|
||||
return mhs.toArray(new MethodHandle[MAX_ARITY+1]);
|
||||
assert(assertArrayMethodCount(mhs));
|
||||
return mhs;
|
||||
}
|
||||
|
||||
private static boolean assertArrayMethodCount(MethodHandle[] mhs) {
|
||||
assert(findCollector("array", ARRAYS_COUNT, Object[].class) == null);
|
||||
for (int i = 0; i < ARRAYS_COUNT; i++) {
|
||||
assert(mhs[i] != null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// filling versions of the above:
|
||||
@ -1449,15 +1459,22 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
private static final int FILL_ARRAYS_COUNT = 11; // current number of fillArray methods
|
||||
|
||||
private static MethodHandle[] makeFillArrays() {
|
||||
ArrayList<MethodHandle> mhs = new ArrayList<>();
|
||||
mhs.add(null); // there is no empty fill; at least a0 is required
|
||||
for (;;) {
|
||||
MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
|
||||
if (mh == null) break;
|
||||
mhs.add(mh);
|
||||
MethodHandle[] mhs = new MethodHandle[FILL_ARRAYS_COUNT];
|
||||
mhs[0] = null; // there is no empty fill; at least a0 is required
|
||||
for (int i = 1; i < FILL_ARRAYS_COUNT; i++) {
|
||||
MethodHandle mh = findCollector("fillArray", i, Object[].class, Integer.class, Object[].class);
|
||||
mhs[i] = mh;
|
||||
}
|
||||
assert(mhs.size() == FILL_ARRAYS_COUNT);
|
||||
return mhs.toArray(new MethodHandle[0]);
|
||||
assert(assertFillArrayMethodCount(mhs));
|
||||
return mhs;
|
||||
}
|
||||
|
||||
private static boolean assertFillArrayMethodCount(MethodHandle[] mhs) {
|
||||
assert(findCollector("fillArray", FILL_ARRAYS_COUNT, Object[].class, Integer.class, Object[].class) == null);
|
||||
for (int i = 1; i < FILL_ARRAYS_COUNT; i++) {
|
||||
assert(mhs[i] != null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Object copyAsPrimitiveArray(Wrapper w, Object... boxes) {
|
||||
@ -1472,9 +1489,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
|
||||
static MethodHandle varargsArray(int nargs) {
|
||||
MethodHandle mh = Lazy.ARRAYS[nargs];
|
||||
if (mh != null) return mh;
|
||||
mh = findCollector("array", nargs, Object[].class);
|
||||
if (mh != null) mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
|
||||
if (mh != null) return Lazy.ARRAYS[nargs] = mh;
|
||||
mh = buildVarargsArray(Lazy.MH_fillNewArray, Lazy.MH_arrayIdentity, nargs);
|
||||
assert(assertCorrectArity(mh, nargs));
|
||||
mh = makeIntrinsic(mh, Intrinsic.NEW_ARRAY);
|
||||
|
||||
@ -122,18 +122,18 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
ThreadGroup tg = Thread.currentThread().getThreadGroup();
|
||||
for (ThreadGroup tgn = tg;
|
||||
tgn != null;
|
||||
tg = tgn, tgn = tg.getParent());
|
||||
Thread sft = new Thread(tg, proc, "Secondary finalizer");
|
||||
sft.start();
|
||||
try {
|
||||
sft.join();
|
||||
} catch (InterruptedException x) {
|
||||
/* Ignore */
|
||||
}
|
||||
return null;
|
||||
ThreadGroup tg = Thread.currentThread().getThreadGroup();
|
||||
for (ThreadGroup tgn = tg;
|
||||
tgn != null;
|
||||
tg = tgn, tgn = tg.getParent());
|
||||
Thread sft = new Thread(tg, proc, "Secondary finalizer");
|
||||
sft.start();
|
||||
try {
|
||||
sft.join();
|
||||
} catch (InterruptedException x) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
return null;
|
||||
}});
|
||||
}
|
||||
|
||||
@ -146,6 +146,7 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must
|
||||
forkSecondaryFinalizer(new Runnable() {
|
||||
private volatile boolean running;
|
||||
public void run() {
|
||||
// in case of recursive call to run()
|
||||
if (running)
|
||||
return;
|
||||
final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
|
||||
@ -168,6 +169,7 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must
|
||||
forkSecondaryFinalizer(new Runnable() {
|
||||
private volatile boolean running;
|
||||
public void run() {
|
||||
// in case of recursive call to run()
|
||||
if (running)
|
||||
return;
|
||||
final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
|
||||
@ -189,6 +191,7 @@ final class Finalizer extends FinalReference<Object> { /* Package-private; must
|
||||
super(g, "Finalizer");
|
||||
}
|
||||
public void run() {
|
||||
// in case of recursive call to run()
|
||||
if (running)
|
||||
return;
|
||||
|
||||
|
||||
@ -446,6 +446,7 @@ public abstract class SocketImpl implements SocketOptions {
|
||||
|
||||
serverSocketOptions.add(StandardSocketOptions.SO_RCVBUF);
|
||||
serverSocketOptions.add(StandardSocketOptions.SO_REUSEADDR);
|
||||
serverSocketOptions.add(StandardSocketOptions.IP_TOS);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -303,7 +303,7 @@ public final class Files {
|
||||
* is a {@link java.nio.channels.FileChannel}.
|
||||
*
|
||||
* <p> <b>Usage Examples:</b>
|
||||
* <pre>
|
||||
* <pre>{@code
|
||||
* Path path = ...
|
||||
*
|
||||
* // open file for reading
|
||||
@ -314,9 +314,10 @@ public final class Files {
|
||||
* WritableByteChannel wbc = Files.newByteChannel(path, EnumSet.of(CREATE,APPEND));
|
||||
*
|
||||
* // create file with initial permissions, opening it for both reading and writing
|
||||
* {@code FileAttribute<Set<PosixFilePermission>> perms = ...}
|
||||
* SeekableByteChannel sbc = Files.newByteChannel(path, EnumSet.of(CREATE_NEW,READ,WRITE), perms);
|
||||
* </pre>
|
||||
* FileAttribute<Set<PosixFilePermission>> perms = ...
|
||||
* SeekableByteChannel sbc =
|
||||
* Files.newByteChannel(path, EnumSet.of(CREATE_NEW,READ,WRITE), perms);
|
||||
* }</pre>
|
||||
*
|
||||
* @param path
|
||||
* the path to the file to open or create
|
||||
@ -1702,7 +1703,8 @@ public final class Files {
|
||||
* Alternatively, suppose we want to read file's POSIX attributes without
|
||||
* following symbolic links:
|
||||
* <pre>
|
||||
* PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class, NOFOLLOW_LINKS);
|
||||
* PosixFileAttributes attrs =
|
||||
* Files.readAttributes(path, PosixFileAttributes.class, NOFOLLOW_LINKS);
|
||||
* </pre>
|
||||
*
|
||||
* @param <A>
|
||||
@ -2840,6 +2842,8 @@ public final class Files {
|
||||
* @return a new buffered writer, with default buffer size, to write text
|
||||
* to the file
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code options} contains an invalid combination of options
|
||||
* @throws IOException
|
||||
* if an I/O error occurs opening or creating the file
|
||||
* @throws UnsupportedOperationException
|
||||
@ -2880,6 +2884,8 @@ public final class Files {
|
||||
* @return a new buffered writer, with default buffer size, to write text
|
||||
* to the file
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code options} contains an invalid combination of options
|
||||
* @throws IOException
|
||||
* if an I/O error occurs opening or creating the file
|
||||
* @throws UnsupportedOperationException
|
||||
@ -2891,7 +2897,9 @@ public final class Files {
|
||||
*
|
||||
* @since 1.8
|
||||
*/
|
||||
public static BufferedWriter newBufferedWriter(Path path, OpenOption... options) throws IOException {
|
||||
public static BufferedWriter newBufferedWriter(Path path, OpenOption... options)
|
||||
throws IOException
|
||||
{
|
||||
return newBufferedWriter(path, StandardCharsets.UTF_8, options);
|
||||
}
|
||||
|
||||
@ -3273,6 +3281,8 @@ public final class Files {
|
||||
*
|
||||
* @return the path
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code options} contains an invalid combination of options
|
||||
* @throws IOException
|
||||
* if an I/O error occurs writing to or creating the file
|
||||
* @throws UnsupportedOperationException
|
||||
@ -3330,6 +3340,8 @@ public final class Files {
|
||||
*
|
||||
* @return the path
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code options} contains an invalid combination of options
|
||||
* @throws IOException
|
||||
* if an I/O error occurs writing to or creating the file, or the
|
||||
* text cannot be encoded using the specified charset
|
||||
@ -3376,6 +3388,8 @@ public final class Files {
|
||||
*
|
||||
* @return the path
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code options} contains an invalid combination of options
|
||||
* @throws IOException
|
||||
* if an I/O error occurs writing to or creating the file, or the
|
||||
* text cannot be encoded as {@code UTF-8}
|
||||
@ -3452,7 +3466,7 @@ public final class Files {
|
||||
final Iterator<Path> delegate = ds.iterator();
|
||||
|
||||
// Re-wrap DirectoryIteratorException to UncheckedIOException
|
||||
Iterator<Path> it = new Iterator<Path>() {
|
||||
Iterator<Path> iterator = new Iterator<Path>() {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
try {
|
||||
@ -3471,7 +3485,9 @@ public final class Files {
|
||||
}
|
||||
};
|
||||
|
||||
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false)
|
||||
Spliterator<Path> spliterator =
|
||||
Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT);
|
||||
return StreamSupport.stream(spliterator, false)
|
||||
.onClose(asUncheckedRunnable(ds));
|
||||
} catch (Error|RuntimeException e) {
|
||||
try {
|
||||
@ -3572,7 +3588,9 @@ public final class Files {
|
||||
{
|
||||
FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
|
||||
try {
|
||||
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
|
||||
Spliterator<FileTreeWalker.Event> spliterator =
|
||||
Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT);
|
||||
return StreamSupport.stream(spliterator, false)
|
||||
.onClose(iterator::close)
|
||||
.map(entry -> entry.file());
|
||||
} catch (Error|RuntimeException e) {
|
||||
@ -3685,7 +3703,9 @@ public final class Files {
|
||||
{
|
||||
FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
|
||||
try {
|
||||
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
|
||||
Spliterator<FileTreeWalker.Event> spliterator =
|
||||
Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT);
|
||||
return StreamSupport.stream(spliterator, false)
|
||||
.onClose(iterator::close)
|
||||
.filter(entry -> matcher.test(entry.file(), entry.attributes()))
|
||||
.map(entry -> entry.file());
|
||||
|
||||
@ -86,8 +86,8 @@
|
||||
* <p> Unless otherwise noted, passing a {@code null} argument to a constructor
|
||||
* or method of any class or interface in this package will cause a {@link
|
||||
* java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
|
||||
* invoking a method with a collection containing a {@code null} element will
|
||||
* cause a {@code NullPointerException}, unless otherwise specified. </p>
|
||||
* invoking a method with an array or collection containing a {@code null} element
|
||||
* will cause a {@code NullPointerException}, unless otherwise specified. </p>
|
||||
*
|
||||
* <p> Unless otherwise noted, methods that attempt to access the file system
|
||||
* will throw {@link java.nio.file.ClosedFileSystemException} when invoked on
|
||||
|
||||
@ -276,6 +276,7 @@ public class Sockets {
|
||||
set = new HashSet<>();
|
||||
set.add(StandardSocketOptions.SO_RCVBUF);
|
||||
set.add(StandardSocketOptions.SO_REUSEADDR);
|
||||
set.add(StandardSocketOptions.IP_TOS);
|
||||
set = Collections.unmodifiableSet(set);
|
||||
options.put(ServerSocket.class, set);
|
||||
|
||||
|
||||
@ -1608,7 +1608,7 @@ public final class Main {
|
||||
private static String getCompatibleSigAlgName(String keyAlgName)
|
||||
throws Exception {
|
||||
if ("DSA".equalsIgnoreCase(keyAlgName)) {
|
||||
return "SHA1WithDSA";
|
||||
return "SHA256WithDSA";
|
||||
} else if ("RSA".equalsIgnoreCase(keyAlgName)) {
|
||||
return "SHA256WithRSA";
|
||||
} else if ("EC".equalsIgnoreCase(keyAlgName)) {
|
||||
@ -1628,10 +1628,8 @@ public final class Main {
|
||||
if (keysize == -1) {
|
||||
if ("EC".equalsIgnoreCase(keyAlgName)) {
|
||||
keysize = 256;
|
||||
} else if ("RSA".equalsIgnoreCase(keyAlgName)) {
|
||||
keysize = 2048;
|
||||
} else {
|
||||
keysize = 1024;
|
||||
keysize = 2048; // RSA and DSA
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -205,28 +205,4 @@ public class JmxProperties {
|
||||
*/
|
||||
public static final Logger MISC_LOGGER =
|
||||
Logger.getLogger(MISC_LOGGER_NAME);
|
||||
|
||||
/**
|
||||
* Logger name for SNMP.
|
||||
*/
|
||||
public static final String SNMP_LOGGER_NAME =
|
||||
"javax.management.snmp";
|
||||
|
||||
/**
|
||||
* Logger for SNMP.
|
||||
*/
|
||||
public static final Logger SNMP_LOGGER =
|
||||
Logger.getLogger(SNMP_LOGGER_NAME);
|
||||
|
||||
/**
|
||||
* Logger name for SNMP Adaptor.
|
||||
*/
|
||||
public static final String SNMP_ADAPTOR_LOGGER_NAME =
|
||||
"javax.management.snmp.daemon";
|
||||
|
||||
/**
|
||||
* Logger for SNMP Adaptor.
|
||||
*/
|
||||
public static final Logger SNMP_ADAPTOR_LOGGER =
|
||||
Logger.getLogger(SNMP_ADAPTOR_LOGGER_NAME);
|
||||
}
|
||||
|
||||
@ -2358,7 +2358,7 @@ class SignatureFile {
|
||||
if (sigalg == null) {
|
||||
|
||||
if (keyAlgorithm.equalsIgnoreCase("DSA"))
|
||||
signatureAlgorithm = "SHA1withDSA";
|
||||
signatureAlgorithm = "SHA256withDSA";
|
||||
else if (keyAlgorithm.equalsIgnoreCase("RSA"))
|
||||
signatureAlgorithm = "SHA256withRSA";
|
||||
else if (keyAlgorithm.equalsIgnoreCase("EC"))
|
||||
|
||||
@ -138,9 +138,6 @@ com/sun/management/GarbageCollectorMXBean/GarbageCollectionNotificationTest.java
|
||||
# 8058492
|
||||
java/lang/management/ThreadMXBean/FindDeadlocks.java generic-all
|
||||
|
||||
# 8058506
|
||||
java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_jmx
|
||||
@ -285,6 +282,9 @@ com/sun/jdi/JdbReadTwiceTest.sh generic-all
|
||||
# 8058616
|
||||
com/sun/jdi/RedefinePop.sh generic-all
|
||||
|
||||
# 8061114
|
||||
com/sun/jdi/Redefine-g.sh generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
# jdk_util
|
||||
@ -318,4 +318,7 @@ sun/tools/jps/TestJpsJarRelative.java generic-all
|
||||
# 8057732
|
||||
sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java generic-all
|
||||
|
||||
# 8060736
|
||||
sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all
|
||||
|
||||
############################################################################
|
||||
|
||||
249
jdk/test/java/lang/ClassLoader/GetSystemPackage.java
Normal file
249
jdk/test/java/lang/ClassLoader/GetSystemPackage.java
Normal file
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8060130
|
||||
* @library /lib/testlibrary
|
||||
* @build package2.Class2 GetSystemPackage jdk.testlibrary.*
|
||||
* @summary Test if getSystemPackage() return consistent values for cases
|
||||
* where a manifest is provided or not and ensure only jars on
|
||||
* bootclasspath gets resolved via Package.getSystemPackage
|
||||
* @run main GetSystemPackage
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import jdk.testlibrary.ProcessTools;
|
||||
|
||||
public class GetSystemPackage {
|
||||
|
||||
static final String testClassesDir = System.getProperty("test.classes", ".");
|
||||
static final File tmpFolder = new File(testClassesDir);
|
||||
static final String manifestTitle = "Special JAR";
|
||||
|
||||
public static void main(String ... args) throws Exception {
|
||||
if (args.length == 0) {
|
||||
buildJarsAndInitiateSystemPackageTest();
|
||||
return;
|
||||
}
|
||||
switch (args[0]) {
|
||||
case "system-manifest":
|
||||
verifyPackage(true, true);
|
||||
break;
|
||||
case "system-no-manifest":
|
||||
verifyPackage(false, true);
|
||||
break;
|
||||
case "non-system-manifest":
|
||||
verifyPackage(true, false);
|
||||
break;
|
||||
case "non-system-no-manifest":
|
||||
default:
|
||||
verifyPackage(false, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildJarsAndInitiateSystemPackageTest()
|
||||
throws Exception
|
||||
{
|
||||
Manifest m = new Manifest();
|
||||
// not setting MANIFEST_VERSION prevents META-INF/MANIFEST.MF from
|
||||
// getting written
|
||||
m.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
m.getMainAttributes().put(Attributes.Name.SPECIFICATION_TITLE,
|
||||
manifestTitle);
|
||||
|
||||
buildJar("manifest.jar", m);
|
||||
buildJar("no-manifest.jar", null);
|
||||
|
||||
runSubProcess("System package with manifest improperly resolved.",
|
||||
"-Xbootclasspath/p:" + testClassesDir + "/manifest.jar",
|
||||
"GetSystemPackage", "system-manifest");
|
||||
|
||||
runSubProcess("System package from directory improperly resolved.",
|
||||
"-Xbootclasspath/p:" + testClassesDir, "GetSystemPackage",
|
||||
"system-no-manifest");
|
||||
|
||||
runSubProcess("System package with no manifest improperly resolved",
|
||||
"-Xbootclasspath/p:" + testClassesDir + "/no-manifest.jar",
|
||||
"GetSystemPackage", "system-no-manifest");
|
||||
|
||||
runSubProcess("Classpath package with manifest improperly resolved",
|
||||
"-cp", testClassesDir + "/manifest.jar", "GetSystemPackage",
|
||||
"non-system-manifest");
|
||||
|
||||
runSubProcess("Classpath package with no manifest improperly resolved",
|
||||
"-cp", testClassesDir + "/no-manifest.jar", "GetSystemPackage",
|
||||
"non-system-no-manifest");
|
||||
|
||||
}
|
||||
|
||||
private static void buildJar(String name, Manifest man) throws Exception {
|
||||
JarBuilder jar = new JarBuilder(tmpFolder, name, man);
|
||||
jar.addClassFile("package2/Class2.class",
|
||||
testClassesDir + "/package2/Class2.class");
|
||||
jar.addClassFile("GetSystemPackage.class",
|
||||
testClassesDir + "/GetSystemPackage.class");
|
||||
jar.addClassFile("GetSystemPackageClassLoader.class",
|
||||
testClassesDir + "/GetSystemPackageClassLoader.class");
|
||||
jar.build();
|
||||
}
|
||||
|
||||
private static void runSubProcess(String messageOnError, String ... args)
|
||||
throws Exception
|
||||
{
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
|
||||
int res = pb.directory(tmpFolder).inheritIO().start().waitFor();
|
||||
if (res != 0) {
|
||||
throw new RuntimeException(messageOnError);
|
||||
}
|
||||
}
|
||||
|
||||
private static void verifyPackage(boolean hasManifest,
|
||||
boolean isSystemPackage) throws Exception
|
||||
{
|
||||
Class c = Class.forName("package2.Class2");
|
||||
Package pkg = c.getPackage();
|
||||
if (pkg == null || pkg != Package.getPackage("package2") ||
|
||||
!"package2".equals(pkg.getName())) {
|
||||
fail("package2 not found via Package.getPackage()");
|
||||
}
|
||||
|
||||
String specificationTitle = pkg.getSpecificationTitle();
|
||||
if (!"package2".equals(pkg.getName())) {
|
||||
fail("Invalid package for Class2");
|
||||
}
|
||||
|
||||
if (hasManifest && (specificationTitle == null
|
||||
|| !manifestTitle.equals(specificationTitle))) {
|
||||
fail("Invalid manifest for package " + pkg.getName());
|
||||
}
|
||||
if (!hasManifest && specificationTitle != null) {
|
||||
fail("Invalid manifest for package " + pkg.getName() + ": was " +
|
||||
specificationTitle + " expected: null");
|
||||
}
|
||||
|
||||
// force the use of a classloader with no parent, then retrieve the
|
||||
// package in a way that bypasses the classloader pkg maps
|
||||
GetSystemPackageClassLoader classLoader =
|
||||
new GetSystemPackageClassLoader();
|
||||
Package systemPkg = classLoader.getSystemPackage("package2");
|
||||
|
||||
if (findPackage("java.lang") == null) {
|
||||
fail("java.lang not found via Package.getPackages()");
|
||||
}
|
||||
Package foundPackage = findPackage("package2");
|
||||
if (isSystemPackage) {
|
||||
if (systemPkg == null) {
|
||||
fail("System package could not be found via getSystemPackage");
|
||||
}
|
||||
if (foundPackage != systemPkg || systemPkg != pkg) {
|
||||
fail("Inconsistent package found via Package.getPackages()");
|
||||
}
|
||||
} else {
|
||||
if (systemPkg != null) {
|
||||
fail("Non-system package could be found via getSystemPackage");
|
||||
}
|
||||
if (foundPackage == null) {
|
||||
fail("Non-system package not found via Package.getPackages()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Package findPackage(String name) {
|
||||
Package[] packages = Package.getPackages();
|
||||
for (Package p : packages) {
|
||||
System.out.println(p);
|
||||
if (p.getName().equals(name)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void fail(String message) {
|
||||
throw new RuntimeException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This classloader bypasses the system classloader to give as direct access
|
||||
* to Package.getSystemPackage() as possible
|
||||
*/
|
||||
class GetSystemPackageClassLoader extends ClassLoader {
|
||||
|
||||
public GetSystemPackageClassLoader() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
public Package getSystemPackage(String name) {
|
||||
return super.getPackage(name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper class for building jar files
|
||||
*/
|
||||
class JarBuilder {
|
||||
|
||||
private JarOutputStream os;
|
||||
|
||||
public JarBuilder(File tmpFolder, String jarName, Manifest manifest)
|
||||
throws FileNotFoundException, IOException
|
||||
{
|
||||
File jarFile = new File(tmpFolder, jarName);
|
||||
if (manifest != null) {
|
||||
this.os = new JarOutputStream(new FileOutputStream(jarFile),
|
||||
manifest);
|
||||
} else {
|
||||
this.os = new JarOutputStream(new FileOutputStream(jarFile));
|
||||
}
|
||||
}
|
||||
|
||||
public void addClassFile(String pathFromRoot, String file)
|
||||
throws IOException
|
||||
{
|
||||
byte[] buf = new byte[1024];
|
||||
try (FileInputStream in = new FileInputStream(file)) {
|
||||
JarEntry entry = new JarEntry(pathFromRoot);
|
||||
os.putNextEntry(entry);
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
os.write(buf, 0, len);
|
||||
}
|
||||
os.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
public void build() throws IOException {
|
||||
os.close();
|
||||
}
|
||||
}
|
||||
@ -23,28 +23,19 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8055289
|
||||
* @library /testlibrary
|
||||
* @build UnsafeMallocLimit
|
||||
* @run main/othervm -Xmx32m -XX:NativeMemoryTracking=summary UnsafeMallocLimit
|
||||
* @bug 4354680
|
||||
* @summary runFinalization() should not clear or ignore interrupt bit
|
||||
* @run main FinInterrupt
|
||||
*/
|
||||
|
||||
import com.oracle.java.testlibrary.*;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
public class UnsafeMallocLimit {
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
if (Platform.is32bit()) {
|
||||
Unsafe unsafe = Utils.getUnsafe();
|
||||
try {
|
||||
unsafe.allocateMemory(1 << 30);
|
||||
throw new RuntimeException("Did not get expected OOME");
|
||||
} catch (OutOfMemoryError e) {
|
||||
// Expected exception
|
||||
}
|
||||
public class FinInterrupt {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Thread.currentThread().interrupt();
|
||||
System.runFinalization();
|
||||
if (Thread.interrupted()) {
|
||||
System.out.println("Passed: interrupt bit was still set.");
|
||||
} else {
|
||||
System.out.println("Test only valid on 32-bit platforms");
|
||||
throw new AssertionError("interrupt bit was cleared");
|
||||
}
|
||||
}
|
||||
}
|
||||
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