--- a/.hgtags-top-repo Thu Feb 12 16:23:24 2015 -0800
+++ b/.hgtags-top-repo Wed Jul 05 20:19:27 2017 +0200
@@ -292,3 +292,4 @@
b6cca3e6175a69f39e5799b7349ddb0176630291 jdk9-b47
0064e246d83f6f9fc245c19b6d05041ecaf4b6d4 jdk9-b48
d91ed1951b948210590ce1394bea5515357246ba jdk9-b49
+d1f37d39ff2421f956a6ddf316cf763807bc3363 jdk9-b50
--- a/README-builds.html Thu Feb 12 16:23:24 2015 -0800
+++ b/README-builds.html Wed Jul 05 20:19:27 2017 +0200
@@ -1463,14 +1463,13 @@
<h4>Building with ccache</h4>
- <p>A simple way to radically speed up compilation of native code
- (typically hotspot and native libraries in JDK) is to install
- ccache. This will cache and reuse prior compilation results, if the
- source code is unchanged. However, ccache versions prior to 3.1.4
- does not work correctly with the precompiled headers used in
- OpenJDK. So if your platform supports ccache at 3.1.4 or later, we
- highly recommend installing it. This is currently only supported on
- linux.</p>
+ <p>The OpenJDK build supports building with ccache
+ when using gcc or clang. Using ccache can
+ radically speed up compilation of native code if
+ you often rebuild the same sources. Your milage
+ may vary however so we recommend evaluating it for
+ yourself. To enable it, make sure it's on the path
+ and configure with <code>--enable-ccache</code>.</p>
<h4>Building on local disk</h4>
--- a/common/autoconf/basics.m4 Thu Feb 12 16:23:24 2015 -0800
+++ b/common/autoconf/basics.m4 Wed Jul 05 20:19:27 2017 +0200
@@ -242,6 +242,9 @@
[
# Save the original command line. This is passed to us by the wrapper configure script.
AC_SUBST(CONFIGURE_COMMAND_LINE)
+ # Save the path variable before it gets changed
+ ORIGINAL_PATH="$PATH"
+ AC_SUBST(ORIGINAL_PATH)
DATE_WHEN_CONFIGURED=`LANG=C date`
AC_SUBST(DATE_WHEN_CONFIGURED)
AC_MSG_NOTICE([Configuration created at $DATE_WHEN_CONFIGURED.])
--- a/common/autoconf/build-performance.m4 Thu Feb 12 16:23:24 2015 -0800
+++ b/common/autoconf/build-performance.m4 Wed Jul 05 20:19:27 2017 +0200
@@ -164,19 +164,26 @@
[enable using ccache to speed up recompilations @<:@disabled@:>@])])
CCACHE=
+ CCACHE_STATUS=
AC_MSG_CHECKING([is ccache enabled])
- ENABLE_CCACHE=$enable_ccache
if test "x$enable_ccache" = xyes; then
- AC_MSG_RESULT([yes])
- OLD_PATH="$PATH"
- if test "x$TOOLCHAIN_PATH" != x; then
- PATH=$TOOLCHAIN_PATH:$PATH
+ if test "x$TOOLCHAIN_TYPE" = "xgcc" -o "x$TOOLCHAIN_TYPE" = "xclang"; then
+ AC_MSG_RESULT([yes])
+ OLD_PATH="$PATH"
+ if test "x$TOOLCHAIN_PATH" != x; then
+ PATH=$TOOLCHAIN_PATH:$PATH
+ fi
+ BASIC_REQUIRE_PROGS(CCACHE, ccache)
+ PATH="$OLD_PATH"
+ CCACHE_VERSION=[`$CCACHE --version | head -n1 | $SED 's/[A-Za-z ]*//'`]
+ CCACHE_STATUS="Active ($CCACHE_VERSION)"
+ else
+ AC_MSG_RESULT([no])
+ AC_MSG_WARN([ccache is not supported with toolchain type $TOOLCHAIN_TYPE])
fi
- BASIC_REQUIRE_PROGS(CCACHE, ccache)
- CCACHE_STATUS="enabled"
- PATH="$OLD_PATH"
elif test "x$enable_ccache" = xno; then
AC_MSG_RESULT([no, explicitly disabled])
+ CCACHE_STATUS="Disabled"
elif test "x$enable_ccache" = x; then
AC_MSG_RESULT([no])
else
@@ -206,35 +213,31 @@
AC_DEFUN([BPERF_SETUP_CCACHE_USAGE],
[
if test "x$CCACHE" != x; then
- # Only use ccache if it is 3.1.4 or later, which supports
- # precompiled headers.
- AC_MSG_CHECKING([if ccache supports precompiled headers])
- HAS_GOOD_CCACHE=`($CCACHE --version | head -n 1 | grep -E 3.1.@<:@456789@:>@) 2> /dev/null`
- if test "x$HAS_GOOD_CCACHE" = x; then
- AC_MSG_RESULT([no, disabling ccache])
- CCACHE=
- CCACHE_STATUS="disabled"
- else
- AC_MSG_RESULT([yes])
+ if test "x$USE_PRECOMPILED_HEADER" = "x1"; then
+ HAS_BAD_CCACHE=[`$ECHO $CCACHE_VERSION | \
+ $GREP -e '^1.*' -e '^2.*' -e '^3\.0.*' -e '^3\.1\.[0123]'`]
+ if test "x$HAS_BAD_CCACHE" != "x"; then
+ AC_MSG_ERROR([Precompiled headers requires ccache 3.1.4 or later, found $CCACHE_VERSION])
+ fi
AC_MSG_CHECKING([if C-compiler supports ccache precompiled headers])
+ CCACHE_PRECOMP_FLAG="-fpch-preprocess"
PUSHED_FLAGS="$CXXFLAGS"
- CXXFLAGS="-fpch-preprocess $CXXFLAGS"
+ CXXFLAGS="$CCACHE_PRECOMP_FLAG $CXXFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], [CC_KNOWS_CCACHE_TRICK=yes], [CC_KNOWS_CCACHE_TRICK=no])
CXXFLAGS="$PUSHED_FLAGS"
if test "x$CC_KNOWS_CCACHE_TRICK" = xyes; then
AC_MSG_RESULT([yes])
+ CFLAGS_CCACHE="$CCACHE_PRECOMP_FLAG"
+ AC_SUBST(CFLAGS_CCACHE)
+ CCACHE_SLOPPINESS=pch_defines,time_macros
else
- AC_MSG_RESULT([no, disabling ccaching of precompiled headers])
- CCACHE=
- CCACHE_STATUS="disabled"
+ AC_MSG_RESULT([no])
+ AC_MSG_ERROR([Cannot use ccache with precompiled headers without compiler support for $CCACHE_PRECOMP_FLAG])
fi
fi
- fi
- if test "x$CCACHE" != x; then
- CCACHE_SLOPPINESS=time_macros
- CCACHE="CCACHE_COMPRESS=1 $SET_CCACHE_DIR CCACHE_SLOPPINESS=$CCACHE_SLOPPINESS $CCACHE"
- CCACHE_FLAGS=-fpch-preprocess
+ CCACHE="CCACHE_COMPRESS=1 $SET_CCACHE_DIR \
+ CCACHE_SLOPPINESS=$CCACHE_SLOPPINESS CCACHE_BASEDIR=$TOPDIR $CCACHE"
if test "x$SET_CCACHE_DIR" != x; then
mkdir -p $CCACHE_DIR > /dev/null 2>&1
--- a/common/autoconf/configure Thu Feb 12 16:23:24 2015 -0800
+++ b/common/autoconf/configure Wed Jul 05 20:19:27 2017 +0200
@@ -40,8 +40,9 @@
echo "Error: This script must be run using bash." 1>&2
exit 1
fi
-# Force autoconf to use bash
+# Force autoconf to use bash. This also means we must disable autoconf re-exec.
export CONFIG_SHELL=$BASH
+export _as_can_reexec=no
conf_script_dir="$TOPDIR/common/autoconf"
--- a/common/autoconf/generated-configure.sh Thu Feb 12 16:23:24 2015 -0800
+++ b/common/autoconf/generated-configure.sh Wed Jul 05 20:19:27 2017 +0200
@@ -629,6 +629,7 @@
ac_subst_vars='LTLIBOBJS
LIBOBJS
+CFLAGS_CCACHE
CCACHE
USE_PRECOMPILED_HEADER
SJAVAC_SERVER_DIR
@@ -991,6 +992,7 @@
BASH
BASENAME
DATE_WHEN_CONFIGURED
+ORIGINAL_PATH
CONFIGURE_COMMAND_LINE
target_alias
host_alias
@@ -4333,7 +4335,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1421247827
+DATE_WHEN_GENERATED=1423567509
###############################################################################
#
@@ -4366,6 +4368,9 @@
# Save the original command line. This is passed to us by the wrapper configure script.
+ # Save the path variable before it gets changed
+ ORIGINAL_PATH="$PATH"
+
DATE_WHEN_CONFIGURED=`LANG=C date`
{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuration created at $DATE_WHEN_CONFIGURED." >&5
@@ -27438,8 +27443,8 @@
# The trailing space for everyone except PATH is no typo, but is needed due
# to trailing \ in the Windows paths. These will be stripped later.
$ECHO "$WINPATH_BASH -c 'echo VS_PATH="'\"$PATH\" > set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
- $ECHO "$WINPATH_BASH -c 'echo VS_INCLUDE="'\"$INCLUDE \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
- $ECHO "$WINPATH_BASH -c 'echo VS_LIB="'\"$LIB \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
+ $ECHO "$WINPATH_BASH -c 'echo VS_INCLUDE="'\"$INCLUDE\;$include \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
+ $ECHO "$WINPATH_BASH -c 'echo VS_LIB="'\"$LIB\;$lib \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
$ECHO "$WINPATH_BASH -c 'echo VCINSTALLDIR="'\"$VCINSTALLDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
$ECHO "$WINPATH_BASH -c 'echo WindowsSdkDir="'\"$WindowsSdkDir \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
$ECHO "$WINPATH_BASH -c 'echo WINDOWSSDKDIR="'\"$WINDOWSSDKDIR \" >> set-vs-env.sh' >> $EXTRACT_VC_ENV_BAT_FILE
@@ -27486,9 +27491,9 @@
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
$as_echo "ok" >&6; }
- # Remove any trailing "\" and " " from the variables.
- VS_INCLUDE=`$ECHO "$VS_INCLUDE" | $SED 's/\\\\* *$//'`
- VS_LIB=`$ECHO "$VS_LIB" | $SED 's/\\\\* *$//'`
+ # Remove any trailing "\" ";" and " " from the variables.
+ VS_INCLUDE=`$ECHO "$VS_INCLUDE" | $SED -e 's/\\\\*;* *$//'`
+ VS_LIB=`$ECHO "$VS_LIB" | $SED 's/\\\\*;* *$//'`
VCINSTALLDIR=`$ECHO "$VCINSTALLDIR" | $SED 's/\\\\* *$//'`
WindowsSDKDir=`$ECHO "$WindowsSDKDir" | $SED 's/\\\\* *$//'`
WINDOWSSDKDIR=`$ECHO "$WINDOWSSDKDIR" | $SED 's/\\\\* *$//'`
@@ -27499,6 +27504,268 @@
+
+ # Convert VS_INCLUDE into SYSROOT_CFLAGS
+ OLDIFS="$IFS"
+ IFS=";"
+ for i in $VS_INCLUDE; do
+ ipath=$i
+ IFS="$OLDIFS"
+
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+
+ # Input might be given as Windows format, start by converting to
+ # unix format.
+ path="$ipath"
+ new_path=`$CYGPATH -u "$path"`
+
+ # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
+ # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
+ # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
+ # "foo.exe" is OK but "foo" is an error.
+ #
+ # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # It is also a way to make sure we got the proper file name for the real test later on.
+ test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
+ if test "x$test_shortpath" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of ipath, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of ipath, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Cannot locate the the path of ipath" "$LINENO" 5
+ fi
+
+ # Call helper function which possibly converts this using DOS-style short mode.
+ # If so, the updated path is stored in $new_path.
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ shortmode_path=`$CYGPATH -s -m -a "$input_path"`
+ path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
+ if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
+ # Going to short mode and back again did indeed matter. Since short mode is
+ # case insensitive, let's make it lowercase to improve readability.
+ shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Now convert it back to Unix-stile (cygpath)
+ input_path=`$CYGPATH -u "$shortmode_path"`
+ new_path="$input_path"
+ fi
+ fi
+
+ test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
+ if test "x$test_cygdrive_prefix" = x; then
+ # As a simple fix, exclude /usr/bin since it's not a real path.
+ if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
+ # The path is in a Cygwin special directory (e.g. /home). We need this converted to
+ # a path prefixed by /cygdrive for fixpath to work.
+ new_path="$CYGWIN_ROOT_PATH$input_path"
+ fi
+ fi
+
+
+ if test "x$path" != "x$new_path"; then
+ ipath="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting ipath to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting ipath to \"$new_path\"" >&6;}
+ fi
+
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+
+ path="$ipath"
+ has_colon=`$ECHO $path | $GREP ^.:`
+ new_path="$path"
+ if test "x$has_colon" = x; then
+ # Not in mixed or Windows style, start by that.
+ new_path=`cmd //c echo $path`
+ fi
+
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ fi
+
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+ if test "x$path" != "x$new_path"; then
+ ipath="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting ipath to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting ipath to \"$new_path\"" >&6;}
+ fi
+
+ # Save the first 10 bytes of this path to the storage, so fixpath can work.
+ all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
+
+ else
+ # We're on a unix platform. Hooray! :)
+ path="$ipath"
+ has_space=`$ECHO "$path" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of ipath, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of ipath, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
+ fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of ipath, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ ipath="`cd "$path"; $THEPWDCMD -L`"
+ fi
+
+ IFS=";"
+ SYSROOT_CFLAGS="$SYSROOT_CFLAGS -I$ipath"
+ done
+ # Convert VS_LIB into SYSROOT_LDFLAGS
+ for i in $VS_LIB; do
+ libpath=$i
+ IFS="$OLDIFS"
+
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+
+ # Input might be given as Windows format, start by converting to
+ # unix format.
+ path="$libpath"
+ new_path=`$CYGPATH -u "$path"`
+
+ # Cygwin tries to hide some aspects of the Windows file system, such that binaries are
+ # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered
+ # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then
+ # "foo.exe" is OK but "foo" is an error.
+ #
+ # This test is therefore slightly more accurate than "test -f" to check for file precense.
+ # It is also a way to make sure we got the proper file name for the real test later on.
+ test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null`
+ if test "x$test_shortpath" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of libpath, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of libpath, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Cannot locate the the path of libpath" "$LINENO" 5
+ fi
+
+ # Call helper function which possibly converts this using DOS-style short mode.
+ # If so, the updated path is stored in $new_path.
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ shortmode_path=`$CYGPATH -s -m -a "$input_path"`
+ path_after_shortmode=`$CYGPATH -u "$shortmode_path"`
+ if test "x$path_after_shortmode" != "x$input_to_shortpath"; then
+ # Going to short mode and back again did indeed matter. Since short mode is
+ # case insensitive, let's make it lowercase to improve readability.
+ shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Now convert it back to Unix-stile (cygpath)
+ input_path=`$CYGPATH -u "$shortmode_path"`
+ new_path="$input_path"
+ fi
+ fi
+
+ test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/`
+ if test "x$test_cygdrive_prefix" = x; then
+ # As a simple fix, exclude /usr/bin since it's not a real path.
+ if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then
+ # The path is in a Cygwin special directory (e.g. /home). We need this converted to
+ # a path prefixed by /cygdrive for fixpath to work.
+ new_path="$CYGWIN_ROOT_PATH$input_path"
+ fi
+ fi
+
+
+ if test "x$path" != "x$new_path"; then
+ libpath="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting libpath to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting libpath to \"$new_path\"" >&6;}
+ fi
+
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+
+ path="$libpath"
+ has_colon=`$ECHO $path | $GREP ^.:`
+ new_path="$path"
+ if test "x$has_colon" = x; then
+ # Not in mixed or Windows style, start by that.
+ new_path=`cmd //c echo $path`
+ fi
+
+
+ input_path="$new_path"
+ # Check if we need to convert this using DOS-style short mode. If the path
+ # contains just simple characters, use it. Otherwise (spaces, weird characters),
+ # take no chances and rewrite it.
+ # Note: m4 eats our [], so we need to use [ and ] instead.
+ has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]`
+ if test "x$has_forbidden_chars" != x; then
+ # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \)
+ new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ fi
+
+
+ windows_path="$new_path"
+ if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then
+ unix_path=`$CYGPATH -u "$windows_path"`
+ new_path="$unix_path"
+ elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then
+ unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'`
+ new_path="$unix_path"
+ fi
+
+ if test "x$path" != "x$new_path"; then
+ libpath="$new_path"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting libpath to \"$new_path\"" >&5
+$as_echo "$as_me: Rewriting libpath to \"$new_path\"" >&6;}
+ fi
+
+ # Save the first 10 bytes of this path to the storage, so fixpath can work.
+ all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}")
+
+ else
+ # We're on a unix platform. Hooray! :)
+ path="$libpath"
+ has_space=`$ECHO "$path" | $GREP " "`
+ if test "x$has_space" != x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: The path of libpath, which resolves as \"$path\", is invalid." >&5
+$as_echo "$as_me: The path of libpath, which resolves as \"$path\", is invalid." >&6;}
+ as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5
+ fi
+
+ # Use eval to expand a potential ~
+ eval path="$path"
+ if test ! -f "$path" && test ! -d "$path"; then
+ as_fn_error $? "The path of libpath, which resolves as \"$path\", is not found." "$LINENO" 5
+ fi
+
+ libpath="`cd "$path"; $THEPWDCMD -L`"
+ fi
+
+ IFS=";"
+ SYSROOT_LDFLAGS="$SYSROOT_LDFLAGS -libpath:$libpath"
+ done
+ IFS="$OLDIFS"
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
@@ -50616,16 +50883,17 @@
CCACHE=
+ CCACHE_STATUS=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking is ccache enabled" >&5
$as_echo_n "checking is ccache enabled... " >&6; }
- ENABLE_CCACHE=$enable_ccache
if test "x$enable_ccache" = xyes; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ if test "x$TOOLCHAIN_TYPE" = "xgcc" -o "x$TOOLCHAIN_TYPE" = "xclang"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- OLD_PATH="$PATH"
- if test "x$TOOLCHAIN_PATH" != x; then
- PATH=$TOOLCHAIN_PATH:$PATH
- fi
+ OLD_PATH="$PATH"
+ if test "x$TOOLCHAIN_PATH" != x; then
+ PATH=$TOOLCHAIN_PATH:$PATH
+ fi
@@ -50819,11 +51087,19 @@
fi
- CCACHE_STATUS="enabled"
- PATH="$OLD_PATH"
+ PATH="$OLD_PATH"
+ CCACHE_VERSION=`$CCACHE --version | head -n1 | $SED 's/[A-Za-z ]*//'`
+ CCACHE_STATUS="Active ($CCACHE_VERSION)"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ccache is not supported with toolchain type $TOOLCHAIN_TYPE" >&5
+$as_echo "$as_me: WARNING: ccache is not supported with toolchain type $TOOLCHAIN_TYPE" >&2;}
+ fi
elif test "x$enable_ccache" = xno; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no, explicitly disabled" >&5
$as_echo "no, explicitly disabled" >&6; }
+ CCACHE_STATUS="Disabled"
elif test "x$enable_ccache" = x; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
@@ -50854,23 +51130,17 @@
if test "x$CCACHE" != x; then
if test "x$CCACHE" != x; then
- # Only use ccache if it is 3.1.4 or later, which supports
- # precompiled headers.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ccache supports precompiled headers" >&5
-$as_echo_n "checking if ccache supports precompiled headers... " >&6; }
- HAS_GOOD_CCACHE=`($CCACHE --version | head -n 1 | grep -E 3.1.[456789]) 2> /dev/null`
- if test "x$HAS_GOOD_CCACHE" = x; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, disabling ccache" >&5
-$as_echo "no, disabling ccache" >&6; }
- CCACHE=
- CCACHE_STATUS="disabled"
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+ if test "x$USE_PRECOMPILED_HEADER" = "x1"; then
+ HAS_BAD_CCACHE=`$ECHO $CCACHE_VERSION | \
+ $GREP -e '^1.*' -e '^2.*' -e '^3\.0.*' -e '^3\.1\.[0123]'`
+ if test "x$HAS_BAD_CCACHE" != "x"; then
+ as_fn_error $? "Precompiled headers requires ccache 3.1.4 or later, found $CCACHE_VERSION" "$LINENO" 5
+ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if C-compiler supports ccache precompiled headers" >&5
$as_echo_n "checking if C-compiler supports ccache precompiled headers... " >&6; }
+ CCACHE_PRECOMP_FLAG="-fpch-preprocess"
PUSHED_FLAGS="$CXXFLAGS"
- CXXFLAGS="-fpch-preprocess $CXXFLAGS"
+ CXXFLAGS="$CCACHE_PRECOMP_FLAG $CXXFLAGS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -50892,19 +51162,18 @@
if test "x$CC_KNOWS_CCACHE_TRICK" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, disabling ccaching of precompiled headers" >&5
-$as_echo "no, disabling ccaching of precompiled headers" >&6; }
- CCACHE=
- CCACHE_STATUS="disabled"
- fi
- fi
- fi
-
- if test "x$CCACHE" != x; then
- CCACHE_SLOPPINESS=time_macros
- CCACHE="CCACHE_COMPRESS=1 $SET_CCACHE_DIR CCACHE_SLOPPINESS=$CCACHE_SLOPPINESS $CCACHE"
- CCACHE_FLAGS=-fpch-preprocess
+ CFLAGS_CCACHE="$CCACHE_PRECOMP_FLAG"
+
+ CCACHE_SLOPPINESS=pch_defines,time_macros
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "Cannot use ccache with precompiled headers without compiler support for $CCACHE_PRECOMP_FLAG" "$LINENO" 5
+ fi
+ fi
+
+ CCACHE="CCACHE_COMPRESS=1 $SET_CCACHE_DIR \
+ CCACHE_SLOPPINESS=$CCACHE_SLOPPINESS CCACHE_BASEDIR=$TOPDIR $CCACHE"
if test "x$SET_CCACHE_DIR" != x; then
mkdir -p $CCACHE_DIR > /dev/null 2>&1
--- a/common/autoconf/hotspot-spec.gmk.in Thu Feb 12 16:23:24 2015 -0800
+++ b/common/autoconf/hotspot-spec.gmk.in Wed Jul 05 20:19:27 2017 +0200
@@ -109,8 +109,8 @@
MT:=@HOTSPOT_MT@
RC:=@HOTSPOT_RC@
-EXTRA_CFLAGS=@LEGACY_EXTRA_CFLAGS@
-EXTRA_CXXFLAGS=@LEGACY_EXTRA_CXXFLAGS@
+EXTRA_CFLAGS=@LEGACY_EXTRA_CFLAGS@ $(CFLAGS_CCACHE)
+EXTRA_CXXFLAGS=@LEGACY_EXTRA_CXXFLAGS@ $(CFLAGS_CCACHE)
EXTRA_LDFLAGS=@LEGACY_EXTRA_LDFLAGS@
USE_PRECOMPILED_HEADER=@USE_PRECOMPILED_HEADER@
@@ -132,6 +132,13 @@
ZIP_DEBUGINFO_FILES:=0
endif
+ifeq ($(OPENJDK_TARGET_OS), windows)
+ # On Windows, the Visual Studio toolchain needs the LIB and INCLUDE
+ # environment variables (in Windows path style).
+ export INCLUDE:=@VS_INCLUDE@
+ export LIB:=@VS_LIB@
+endif
+
# Sneak this in via the spec.gmk file, since we don't want to mess around too much with the Hotspot make files.
# This is needed to get the LOG setting to work properly.
include $(SRC_ROOT)/make/common/MakeBase.gmk
--- a/common/autoconf/spec.gmk.in Thu Feb 12 16:23:24 2015 -0800
+++ b/common/autoconf/spec.gmk.in Wed Jul 05 20:19:27 2017 +0200
@@ -129,14 +129,12 @@
# colon or semicolon
PATH_SEP:=@PATH_SEP@
+# Save the original path before replacing it with the Visual Studio tools
+ORIGINAL_PATH:=@ORIGINAL_PATH@
ifeq ($(OPENJDK_TARGET_OS), windows)
- # On Windows, the Visual Studio toolchain needs the LIB and INCLUDE
- # environment variables (in Windows path style), and the PATH needs to
- # be adjusted to include Visual Studio tools (but this needs to be in
- # cygwin/msys style).
+ # On Windows, the Visual Studio toolchain needs the PATH to be adjusted
+ # to include Visual Studio tools (this needs to be in cygwin/msys style).
export PATH:=@VS_PATH@
- export INCLUDE:=@VS_INCLUDE@
- export LIB:=@VS_LIB@
endif
SYSROOT_CFLAGS := @SYSROOT_CFLAGS@
@@ -328,6 +326,8 @@
CFLAGS_WARNINGS_ARE_ERRORS:=@CFLAGS_WARNINGS_ARE_ERRORS@
+CFLAGS_CCACHE:=@CFLAGS_CCACHE@
+
# Tools that potentially need to be cross compilation aware.
CC:=@FIXPATH@ @CCACHE@ @CC@
--- a/common/autoconf/toolchain_windows.m4 Thu Feb 12 16:23:24 2015 -0800
+++ b/common/autoconf/toolchain_windows.m4 Wed Jul 05 20:19:27 2017 +0200
@@ -213,9 +213,9 @@
AC_MSG_ERROR([Your VC command prompt seems broken, INCLUDE and/or LIB is missing.])
else
AC_MSG_RESULT([ok])
- # Remove any trailing "\" and " " from the variables.
- VS_INCLUDE=`$ECHO "$VS_INCLUDE" | $SED 's/\\\\* *$//'`
- VS_LIB=`$ECHO "$VS_LIB" | $SED 's/\\\\* *$//'`
+ # Remove any trailing "\" ";" and " " from the variables.
+ VS_INCLUDE=`$ECHO "$VS_INCLUDE" | $SED -e 's/\\\\*;* *$//'`
+ VS_LIB=`$ECHO "$VS_LIB" | $SED 's/\\\\*;* *$//'`
VCINSTALLDIR=`$ECHO "$VCINSTALLDIR" | $SED 's/\\\\* *$//'`
WindowsSDKDir=`$ECHO "$WindowsSDKDir" | $SED 's/\\\\* *$//'`
WINDOWSSDKDIR=`$ECHO "$WINDOWSSDKDIR" | $SED 's/\\\\* *$//'`
@@ -226,6 +226,26 @@
AC_SUBST(VS_PATH)
AC_SUBST(VS_INCLUDE)
AC_SUBST(VS_LIB)
+
+ # Convert VS_INCLUDE into SYSROOT_CFLAGS
+ OLDIFS="$IFS"
+ IFS=";"
+ for i in $VS_INCLUDE; do
+ ipath=$i
+ IFS="$OLDIFS"
+ BASIC_FIXUP_PATH([ipath])
+ IFS=";"
+ SYSROOT_CFLAGS="$SYSROOT_CFLAGS -I$ipath"
+ done
+ # Convert VS_LIB into SYSROOT_LDFLAGS
+ for i in $VS_LIB; do
+ libpath=$i
+ IFS="$OLDIFS"
+ BASIC_FIXUP_PATH([libpath])
+ IFS=";"
+ SYSROOT_LDFLAGS="$SYSROOT_LDFLAGS -libpath:$libpath"
+ done
+ IFS="$OLDIFS"
fi
else
AC_MSG_RESULT([not found])
--- a/corba/.hgtags Thu Feb 12 16:23:24 2015 -0800
+++ b/corba/.hgtags Wed Jul 05 20:19:27 2017 +0200
@@ -292,3 +292,4 @@
ee8447ca632e1d39180b4767c749db101bff7314 jdk9-b47
a13c49c5f2899b702652a460ed7aa73123e671e6 jdk9-b48
9285d14eb7b6b0815679bae98dd936dbc136218d jdk9-b49
+224f593393e5b01b3c8f1e591b7f4b1790a3737a jdk9-b50
--- a/hotspot/.hgtags Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/.hgtags Wed Jul 05 20:19:27 2017 +0200
@@ -452,3 +452,4 @@
3b241fb72b8925b75941d612db762a6d5da66d02 jdk9-b47
cc775a4a24c7f5d9e624b4205e9fbd48a17331f6 jdk9-b48
360cd1fc42f10941a9fd17cc32d5b85a22d12a0b jdk9-b49
+e0947f58c9c1426aa0d98b98ebb78357b27a7b99 jdk9-b50
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,15 +44,22 @@
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("SymbolTable");
theTableField = type.getAddressField("_the_table");
+ sharedTableField = type.getAddressField("_shared_table");
}
// Fields
private static AddressField theTableField;
+ private static AddressField sharedTableField;
+
+ private CompactHashTable sharedTable;
// Accessors
public static SymbolTable getTheTable() {
Address tmp = theTableField.getValue();
- return (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
+ SymbolTable table = (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
+ Address shared = sharedTableField.getStaticFieldAddress();
+ table.sharedTable = (CompactHashTable)VMObjectFactory.newObject(CompactHashTable.class, shared);
+ return table;
}
public SymbolTable(Address addr) {
@@ -73,8 +80,9 @@
/** Clone of VM's "temporary" probe routine, as the SA currently
does not support mutation so lookup() would have no effect
- anyway. Returns null if the given string is not in the symbol
- table. */
+ anyway. Searches the regular symbol table and the shared symbol
+ table. Null is returned if the given name is not found in both
+ tables. */
public Symbol probe(byte[] name) {
long hashValue = hashSymbol(name);
for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
@@ -85,7 +93,8 @@
}
}
}
- return null;
+
+ return sharedTable.probe(name, hashValue);
}
public interface SymbolVisitor {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.utilities;
+
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class CompactHashTable extends VMObject {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("SymbolCompactHashTable");
+ baseAddressField = type.getAddressField("_base_address");
+ bucketCountField = type.getCIntegerField("_bucket_count");
+ tableEndOffsetField = type.getCIntegerField("_table_end_offset");
+ bucketsField = type.getAddressField("_buckets");
+ uintSize = db.lookupType("juint").getSize();
+ }
+
+ // Fields
+ private static CIntegerField bucketCountField;
+ private static CIntegerField tableEndOffsetField;
+ private static AddressField baseAddressField;
+ private static AddressField bucketsField;
+ private static long uintSize;
+
+ private static int BUCKET_OFFSET_MASK = 0x3FFFFFFF;
+ private static int BUCKET_TYPE_SHIFT = 30;
+ private static int COMPACT_BUCKET_TYPE = 1;
+
+ public CompactHashTable(Address addr) {
+ super(addr);
+ }
+
+ private int bucketCount() {
+ return (int)bucketCountField.getValue(addr);
+ }
+
+ private int tableEndOffset() {
+ return (int)tableEndOffsetField.getValue(addr);
+ }
+
+ private boolean isCompactBucket(int bucket_info) {
+ return (bucket_info >> BUCKET_TYPE_SHIFT) == COMPACT_BUCKET_TYPE;
+ }
+
+ private int bucketOffset(int bucket_info) {
+ return bucket_info & BUCKET_OFFSET_MASK;
+ }
+
+ public Symbol probe(byte[] name, long hash) {
+ long symOffset;
+ Symbol sym;
+ Address baseAddress = baseAddressField.getValue(addr);
+ Address bucket = bucketsField.getValue(addr);
+ Address bucketEnd = bucket;
+ long index = hash % bucketCount();
+ int bucketInfo = (int)bucket.getCIntegerAt(index * uintSize, uintSize, true);
+ int bucketOffset = bucketOffset(bucketInfo);
+ int nextBucketInfo = (int)bucket.getCIntegerAt((index+1) * uintSize, uintSize, true);
+ int nextBucketOffset = bucketOffset(nextBucketInfo);
+
+ bucket = bucket.addOffsetTo(bucketOffset * uintSize);
+
+ if (isCompactBucket(bucketInfo)) {
+ symOffset = bucket.getCIntegerAt(0, uintSize, true);
+ sym = Symbol.create(baseAddress.addOffsetTo(symOffset));
+ if (sym.equals(name)) {
+ return sym;
+ }
+ } else {
+ bucketEnd = bucket.addOffsetTo(nextBucketOffset * uintSize);
+ while (bucket.lessThan(bucketEnd)) {
+ long symHash = bucket.getCIntegerAt(0, uintSize, true);
+ if (symHash == hash) {
+ symOffset = bucket.getCIntegerAt(uintSize, uintSize, true);
+ Address symAddr = baseAddress.addOffsetTo(symOffset);
+ sym = Symbol.create(symAddr);
+ if (sym.equals(name)) {
+ return sym;
+ }
+ }
+ bucket = bucket.addOffsetTo(2 * uintSize);
+ }
+ }
+ return null;
+ }
+}
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -143,7 +143,6 @@
}
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
ShouldNotReachHere();
break;
default:
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -115,7 +115,6 @@
}
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
ShouldNotReachHere();
break;
default :
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -123,7 +123,9 @@
}
intptr_t* sender_sp = NULL;
+ intptr_t* sender_unextended_sp = NULL;
address sender_pc = NULL;
+ intptr_t* saved_fp = NULL;
if (is_interpreted_frame()) {
// fp must be safe
@@ -132,7 +134,12 @@
}
sender_pc = (address) this->fp()[return_addr_offset];
+ // for interpreted frames, the value below is the sender "raw" sp,
+ // which can be different from the sender unextended sp (the sp seen
+ // by the sender) because of current frame local variables
sender_sp = (intptr_t*) addr_at(sender_sp_offset);
+ sender_unextended_sp = (intptr_t*) this->fp()[interpreter_frame_sender_sp_offset];
+ saved_fp = (intptr_t*) this->fp()[link_offset];
} else {
// must be some sort of compiled/runtime frame
@@ -144,8 +151,11 @@
}
sender_sp = _unextended_sp + _cb->frame_size();
+ sender_unextended_sp = sender_sp;
// On Intel the return_address is always the word on the stack
sender_pc = (address) *(sender_sp-1);
+ // Note: frame::sender_sp_offset is only valid for compiled frame
+ saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset);
}
@@ -156,7 +166,6 @@
// only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved ebp
// is really a frame pointer.
- intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) {
@@ -165,7 +174,7 @@
// construct the potential sender
- frame sender(sender_sp, saved_fp, sender_pc);
+ frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
return sender.is_interpreted_frame_valid(thread);
@@ -194,7 +203,6 @@
// Could be the call_stub
if (StubRoutines::returns_to_call_stub(sender_pc)) {
- intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) {
@@ -203,7 +211,7 @@
// construct the potential sender
- frame sender(sender_sp, saved_fp, sender_pc);
+ frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
// Validate the JavaCallWrapper an entry frame must have
address jcw = (address)sender.entry_frame_call_wrapper();
@@ -568,8 +576,11 @@
if (!m->is_valid_method()) return false;
// stack frames shouldn't be much larger than max_stack elements
-
- if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
+ // this test requires the use the unextended_sp which is the sp as seen by
+ // the current frame, and not sp which is the "raw" pc which could point
+ // further because of local variables of the callee method inserted after
+ // method arguments
+ if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
return false;
}
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -185,7 +185,6 @@
}
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
if (val == noreg) {
__ movptr(obj, NULL_WORD);
} else {
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -189,7 +189,6 @@
}
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
if (val == noreg) {
__ store_heap_oop_null(obj);
} else {
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -1432,7 +1432,6 @@
// No pre barriers
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
// No pre barriers
break;
default :
@@ -1454,7 +1453,6 @@
CardTableModRef_post_barrier(addr, new_val);
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
// No post barriers
break;
default :
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,6 +62,7 @@
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
+#include "utilities/resourceHash.hpp"
#if INCLUDE_CDS
#include "classfile/systemDictionaryShared.hpp"
#endif
@@ -693,7 +694,6 @@
}
-
class NameSigHash: public ResourceObj {
public:
Symbol* _name; // name
@@ -1370,6 +1370,33 @@
}
+class LVT_Hash : public AllStatic {
+ public:
+
+ static bool equals(LocalVariableTableElement const& e0, LocalVariableTableElement const& e1) {
+ /*
+ * 3-tuple start_bci/length/slot has to be unique key,
+ * so the following comparison seems to be redundant:
+ * && elem->name_cp_index == entry->_elem->name_cp_index
+ */
+ return (e0.start_bci == e1.start_bci &&
+ e0.length == e1.length &&
+ e0.name_cp_index == e1.name_cp_index &&
+ e0.slot == e1.slot);
+ }
+
+ static unsigned int hash(LocalVariableTableElement const& e0) {
+ unsigned int raw_hash = e0.start_bci;
+
+ raw_hash = e0.length + raw_hash * 37;
+ raw_hash = e0.name_cp_index + raw_hash * 37;
+ raw_hash = e0.slot + raw_hash * 37;
+
+ return raw_hash;
+ }
+};
+
+
// Class file LocalVariableTable elements.
class Classfile_LVT_Element VALUE_OBJ_CLASS_SPEC {
public:
@@ -1380,88 +1407,6 @@
u2 slot;
};
-
-class LVT_Hash: public CHeapObj<mtClass> {
- public:
- LocalVariableTableElement *_elem; // element
- LVT_Hash* _next; // Next entry in hash table
-};
-
-unsigned int hash(LocalVariableTableElement *elem) {
- unsigned int raw_hash = elem->start_bci;
-
- raw_hash = elem->length + raw_hash * 37;
- raw_hash = elem->name_cp_index + raw_hash * 37;
- raw_hash = elem->slot + raw_hash * 37;
-
- return raw_hash % HASH_ROW_SIZE;
-}
-
-void initialize_hashtable(LVT_Hash** table) {
- for (int i = 0; i < HASH_ROW_SIZE; i++) {
- table[i] = NULL;
- }
-}
-
-void clear_hashtable(LVT_Hash** table) {
- for (int i = 0; i < HASH_ROW_SIZE; i++) {
- LVT_Hash* current = table[i];
- LVT_Hash* next;
- while (current != NULL) {
- next = current->_next;
- current->_next = NULL;
- delete(current);
- current = next;
- }
- table[i] = NULL;
- }
-}
-
-LVT_Hash* LVT_lookup(LocalVariableTableElement *elem, int index, LVT_Hash** table) {
- LVT_Hash* entry = table[index];
-
- /*
- * 3-tuple start_bci/length/slot has to be unique key,
- * so the following comparison seems to be redundant:
- * && elem->name_cp_index == entry->_elem->name_cp_index
- */
- while (entry != NULL) {
- if (elem->start_bci == entry->_elem->start_bci
- && elem->length == entry->_elem->length
- && elem->name_cp_index == entry->_elem->name_cp_index
- && elem->slot == entry->_elem->slot
- ) {
- return entry;
- }
- entry = entry->_next;
- }
- return NULL;
-}
-
-// Return false if the local variable is found in table.
-// Return true if no duplicate is found.
-// And local variable is added as a new entry in table.
-bool LVT_put_after_lookup(LocalVariableTableElement *elem, LVT_Hash** table) {
- // First lookup for duplicates
- int index = hash(elem);
- LVT_Hash* entry = LVT_lookup(elem, index, table);
-
- if (entry != NULL) {
- return false;
- }
- // No duplicate is found, allocate a new entry and fill it.
- if ((entry = new LVT_Hash()) == NULL) {
- return false;
- }
- entry->_elem = elem;
-
- // Insert into hash table
- entry->_next = table[index];
- table[index] = entry;
-
- return true;
-}
-
void copy_lvt_element(Classfile_LVT_Element *src, LocalVariableTableElement *lvt) {
lvt->start_bci = Bytes::get_Java_u2((u1*) &src->start_bci);
lvt->length = Bytes::get_Java_u2((u1*) &src->length);
@@ -1861,8 +1806,12 @@
u2** localvariable_type_table_start,
TRAPS) {
- LVT_Hash** lvt_Hash = NEW_RESOURCE_ARRAY(LVT_Hash*, HASH_ROW_SIZE);
- initialize_hashtable(lvt_Hash);
+ ResourceMark rm(THREAD);
+
+ typedef ResourceHashtable<LocalVariableTableElement, LocalVariableTableElement*,
+ &LVT_Hash::hash, &LVT_Hash::equals> LVT_HashTable;
+
+ LVT_HashTable* table = new LVT_HashTable();
// To fill LocalVariableTable in
Classfile_LVT_Element* cf_lvt;
@@ -1872,11 +1821,10 @@
cf_lvt = (Classfile_LVT_Element *) localvariable_table_start[tbl_no];
for (int idx = 0; idx < localvariable_table_length[tbl_no]; idx++, lvt++) {
copy_lvt_element(&cf_lvt[idx], lvt);
- // If no duplicates, add LVT elem in hashtable lvt_Hash.
- if (LVT_put_after_lookup(lvt, lvt_Hash) == false
+ // If no duplicates, add LVT elem in hashtable.
+ if (table->put(*lvt, lvt) == false
&& _need_verify
&& _major_version >= JAVA_1_5_VERSION) {
- clear_hashtable(lvt_Hash);
classfile_parse_error("Duplicated LocalVariableTable attribute "
"entry for '%s' in class file %s",
_cp->symbol_at(lvt->name_cp_index)->as_utf8(),
@@ -1893,29 +1841,25 @@
cf_lvtt = (Classfile_LVT_Element *) localvariable_type_table_start[tbl_no];
for (int idx = 0; idx < localvariable_type_table_length[tbl_no]; idx++) {
copy_lvt_element(&cf_lvtt[idx], &lvtt_elem);
- int index = hash(&lvtt_elem);
- LVT_Hash* entry = LVT_lookup(&lvtt_elem, index, lvt_Hash);
+ LocalVariableTableElement** entry = table->get(lvtt_elem);
if (entry == NULL) {
if (_need_verify) {
- clear_hashtable(lvt_Hash);
classfile_parse_error("LVTT entry for '%s' in class file %s "
"does not match any LVT entry",
_cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
CHECK);
}
- } else if (entry->_elem->signature_cp_index != 0 && _need_verify) {
- clear_hashtable(lvt_Hash);
+ } else if ((*entry)->signature_cp_index != 0 && _need_verify) {
classfile_parse_error("Duplicated LocalVariableTypeTable attribute "
"entry for '%s' in class file %s",
_cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
CHECK);
} else {
// to add generic signatures into LocalVariableTable
- entry->_elem->signature_cp_index = lvtt_elem.descriptor_cp_index;
+ (*entry)->signature_cp_index = lvtt_elem.descriptor_cp_index;
}
}
}
- clear_hashtable(lvt_Hash);
}
--- a/hotspot/src/share/vm/classfile/compactHashtable.hpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/classfile/compactHashtable.hpp Wed Jul 05 20:19:27 2017 +0200
@@ -188,6 +188,7 @@
// dump time.
//
template <class T, class N> class CompactHashtable VALUE_OBJ_CLASS_SPEC {
+ friend class VMStructs;
uintx _base_address;
juint _entry_count;
juint _bucket_count;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -3525,9 +3525,14 @@
size_t card_index;
while (hrrs.has_next(card_index)) {
jbyte* card_ptr = (jbyte*)bs->byte_for_index(card_index);
- if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
- *card_ptr = CardTableModRefBS::dirty_card_val();
- _dcq.enqueue(card_ptr);
+ // The remembered set might contain references to already freed
+ // regions. Filter out such entries to avoid failing card table
+ // verification.
+ if (!g1h->heap_region_containing(bs->addr_for(card_ptr))->is_free()) {
+ if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
+ *card_ptr = CardTableModRefBS::dirty_card_val();
+ _dcq.enqueue(card_ptr);
+ }
}
}
r->rem_set()->clear_locked();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -139,6 +139,8 @@
_survivor_cset_region_length(0),
_old_cset_region_length(0),
+ _sigma(G1ConfidencePercent / 100.0),
+
_collection_set(NULL),
_collection_set_bytes_used_before(0),
@@ -161,17 +163,8 @@
_gc_overhead_perc(0.0) {
- uintx confidence_perc = G1ConfidencePercent;
- // Put an artificial ceiling on this so that it's not set to a silly value.
- if (confidence_perc > 100) {
- confidence_perc = 100;
- warning("G1ConfidencePercent is set to a value that is too large, "
- "it's been updated to %u", confidence_perc);
- }
- // '_sigma' must be initialized before the SurvRateGroups below because they
- // indirecty access '_sigma' trough the 'this' pointer in their constructor.
- _sigma = (double) confidence_perc / 100.0;
-
+ // SurvRateGroups below must be initialized after '_sigma' because they
+ // indirectly access '_sigma' through this object passed to their constructor.
_short_lived_surv_rate_group =
new SurvRateGroup(this, "Short Lived", G1YoungSurvRateNumRegionsSummary);
_survivor_surv_rate_group =
--- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,11 +36,10 @@
if (default_use_cache()) {
_use_cache = true;
- _hot_cache_size = (1 << G1ConcRSLogCacheSize);
+ _hot_cache_size = (size_t)1 << G1ConcRSLogCacheSize;
_hot_cache = NEW_C_HEAP_ARRAY(jbyte*, _hot_cache_size, mtGC);
- _n_hot = 0;
- _hot_cache_idx = 0;
+ reset_hot_cache_internal();
// For refining the cards in the hot cache in parallel
_hot_cache_par_chunk_size = ClaimChunkSize;
@@ -64,26 +63,21 @@
// return it for immediate refining.
return card_ptr;
}
-
// Otherwise, the card is hot.
- jbyte* res = NULL;
- MutexLockerEx x(HotCardCache_lock, Mutex::_no_safepoint_check_flag);
- if (_n_hot == _hot_cache_size) {
- res = _hot_cache[_hot_cache_idx];
- _n_hot--;
- }
+ size_t index = Atomic::add(1, &_hot_cache_idx) - 1;
+ size_t masked_index = index & (_hot_cache_size - 1);
+ jbyte* current_ptr = _hot_cache[masked_index];
- // Now _n_hot < _hot_cache_size, and we can insert at _hot_cache_idx.
- _hot_cache[_hot_cache_idx] = card_ptr;
- _hot_cache_idx++;
-
- if (_hot_cache_idx == _hot_cache_size) {
- // Wrap around
- _hot_cache_idx = 0;
- }
- _n_hot++;
-
- return res;
+ // Try to store the new card pointer into the cache. Compare-and-swap to guard
+ // against the unlikely event of a race resulting in another card pointer to
+ // have already been written to the cache. In this case we will return
+ // card_ptr in favor of the other option, which would be starting over. This
+ // should be OK since card_ptr will likely be the older card already when/if
+ // this ever happens.
+ jbyte* previous_ptr = (jbyte*)Atomic::cmpxchg_ptr(card_ptr,
+ &_hot_cache[masked_index],
+ current_ptr);
+ return (previous_ptr == current_ptr) ? previous_ptr : card_ptr;
}
void G1HotCardCache::drain(uint worker_i,
@@ -96,38 +90,38 @@
assert(_hot_cache != NULL, "Logic");
assert(!use_cache(), "cache should be disabled");
- int start_idx;
-
- while ((start_idx = _hot_cache_par_claimed_idx) < _n_hot) { // read once
- int end_idx = start_idx + _hot_cache_par_chunk_size;
- if (start_idx ==
- Atomic::cmpxchg(end_idx, &_hot_cache_par_claimed_idx, start_idx)) {
- // The current worker has successfully claimed the chunk [start_idx..end_idx)
- end_idx = MIN2(end_idx, _n_hot);
- for (int i = start_idx; i < end_idx; i++) {
- jbyte* card_ptr = _hot_cache[i];
- if (card_ptr != NULL) {
- if (g1rs->refine_card(card_ptr, worker_i, true)) {
- // The part of the heap spanned by the card contains references
- // that point into the current collection set.
- // We need to record the card pointer in the DirtyCardQueueSet
- // that we use for such cards.
- //
- // The only time we care about recording cards that contain
- // references that point into the collection set is during
- // RSet updating while within an evacuation pause.
- // In this case worker_i should be the id of a GC worker thread
- assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
- assert(worker_i < ParallelGCThreads,
- err_msg("incorrect worker id: %u", worker_i));
+ while (_hot_cache_par_claimed_idx < _hot_cache_size) {
+ size_t end_idx = Atomic::add(_hot_cache_par_chunk_size,
+ &_hot_cache_par_claimed_idx);
+ size_t start_idx = end_idx - _hot_cache_par_chunk_size;
+ // The current worker has successfully claimed the chunk [start_idx..end_idx)
+ end_idx = MIN2(end_idx, _hot_cache_size);
+ for (size_t i = start_idx; i < end_idx; i++) {
+ jbyte* card_ptr = _hot_cache[i];
+ if (card_ptr != NULL) {
+ if (g1rs->refine_card(card_ptr, worker_i, true)) {
+ // The part of the heap spanned by the card contains references
+ // that point into the current collection set.
+ // We need to record the card pointer in the DirtyCardQueueSet
+ // that we use for such cards.
+ //
+ // The only time we care about recording cards that contain
+ // references that point into the collection set is during
+ // RSet updating while within an evacuation pause.
+ // In this case worker_i should be the id of a GC worker thread
+ assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
+ assert(worker_i < ParallelGCThreads,
+ err_msg("incorrect worker id: %u", worker_i));
- into_cset_dcq->enqueue(card_ptr);
- }
+ into_cset_dcq->enqueue(card_ptr);
}
+ } else {
+ break;
}
}
}
+
// The existing entries in the hot card cache, which were just refined
// above, are discarded prior to re-enabling the cache near the end of the GC.
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,21 +54,30 @@
// code, increasing throughput.
class G1HotCardCache: public CHeapObj<mtGC> {
- G1CollectedHeap* _g1h;
+
+ G1CollectedHeap* _g1h;
+
+ bool _use_cache;
+
+ G1CardCounts _card_counts;
// The card cache table
- jbyte** _hot_cache;
+ jbyte** _hot_cache;
- int _hot_cache_size;
- int _n_hot;
- int _hot_cache_idx;
+ size_t _hot_cache_size;
+
+ int _hot_cache_par_chunk_size;
- int _hot_cache_par_chunk_size;
- volatile int _hot_cache_par_claimed_idx;
+ // Avoids false sharing when concurrently updating _hot_cache_idx or
+ // _hot_cache_par_claimed_idx. These are never updated at the same time
+ // thus it's not necessary to separate them as well
+ char _pad_before[DEFAULT_CACHE_LINE_SIZE];
- bool _use_cache;
+ volatile size_t _hot_cache_idx;
- G1CardCounts _card_counts;
+ volatile size_t _hot_cache_par_claimed_idx;
+
+ char _pad_after[DEFAULT_CACHE_LINE_SIZE];
// The number of cached cards a thread claims when flushing the cache
static const int ClaimChunkSize = 32;
@@ -113,16 +122,25 @@
void reset_hot_cache() {
assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
assert(Thread::current()->is_VM_thread(), "Current thread should be the VMthread");
- _hot_cache_idx = 0; _n_hot = 0;
+ if (default_use_cache()) {
+ reset_hot_cache_internal();
+ }
}
- bool hot_cache_is_empty() { return _n_hot == 0; }
-
// Zeros the values in the card counts table for entire committed heap
void reset_card_counts();
// Zeros the values in the card counts table for the given region
void reset_card_counts(HeapRegion* hr);
+
+ private:
+ void reset_hot_cache_internal() {
+ assert(_hot_cache != NULL, "Logic");
+ _hot_cache_idx = 0;
+ for (size_t i = 0; i < _hot_cache_size; i++) {
+ _hot_cache[i] = NULL;
+ }
+ }
};
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1HOTCARDCACHE_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,11 +32,8 @@
#include "runtime/orderAccess.inline.hpp"
#include "runtime/thread.inline.hpp"
-G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap) :
- CardTableModRefBS(whole_heap)
-{
- _kind = G1SATBCT;
-}
+G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind) :
+ CardTableModRefBS(whole_heap, kind) { }
void G1SATBCardTableModRefBS::enqueue(oop pre_val) {
// Nulls should have been already filtered.
@@ -132,11 +129,10 @@
G1SATBCardTableLoggingModRefBS::
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap) :
- G1SATBCardTableModRefBS(whole_heap),
+ G1SATBCardTableModRefBS(whole_heap, BarrierSet::G1SATBCTLogging),
_dcqs(JavaThread::dirty_card_queue_set()),
_listener()
{
- _kind = G1SATBCTLogging;
_listener.set_card_table(this);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,9 @@
g1_young_gen = CT_MR_BS_last_reserved << 1
};
+ G1SATBCardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind);
+ ~G1SATBCardTableModRefBS() { }
+
public:
static int g1_young_card_val() { return g1_young_gen; }
@@ -50,8 +53,6 @@
// pre-marking object graph.
static void enqueue(oop pre_val);
- G1SATBCardTableModRefBS(MemRegion whole_heap);
-
bool is_a(BarrierSet::Name bsn) {
return bsn == BarrierSet::G1SATBCT || CardTableModRefBS::is_a(bsn);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -420,7 +420,7 @@
oop obj;
HeapWord* next = cur;
- while (next <= start) {
+ do {
cur = next;
obj = oop(cur);
if (obj->klass_or_null() == NULL) {
@@ -429,45 +429,38 @@
}
// Otherwise...
next = cur + block_size(cur);
- }
+ } while (next <= start);
// If we finish the above loop...We have a parseable object that
// begins on or before the start of the memory region, and ends
// inside or spans the entire region.
-
- assert(obj == oop(cur), "sanity");
assert(cur <= start, "Loop postcondition");
assert(obj->klass_or_null() != NULL, "Loop postcondition");
- assert((cur + block_size(cur)) > start, "Loop postcondition");
- if (!g1h->is_obj_dead(obj)) {
- obj->oop_iterate(cl, mr);
- }
-
- while (cur < end) {
+ do {
obj = oop(cur);
+ assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant");
if (obj->klass_or_null() == NULL) {
// Ran into an unparseable point.
return cur;
- };
+ }
- // Otherwise:
- next = cur + block_size(cur);
+ // Advance the current pointer. "obj" still points to the object to iterate.
+ cur = cur + block_size(cur);
if (!g1h->is_obj_dead(obj)) {
- if (next < end || !obj->is_objArray()) {
- // This object either does not span the MemRegion
- // boundary, or if it does it's not an array.
- // Apply closure to whole object.
+ // Non-objArrays are sometimes marked imprecise at the object start. We
+ // always need to iterate over them in full.
+ // We only iterate over object arrays in full if they are completely contained
+ // in the memory region.
+ if (!obj->is_objArray() || (((HeapWord*)obj) >= start && cur <= end)) {
obj->oop_iterate(cl);
} else {
- // This obj is an array that spans the boundary.
- // Stop at the boundary.
obj->oop_iterate(cl, mr);
}
}
- cur = next;
- }
+ } while (cur < end);
+
return NULL;
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,7 +54,7 @@
};
CardTableExtension(MemRegion whole_heap) :
- CardTableModRefBS(whole_heap) { }
+ CardTableModRefBS(whole_heap, BarrierSet::CardTableModRef) { }
// Too risky for the 4/10/02 putback
// BarrierSet::Name kind() { return BarrierSet::CardTableExtension; }
--- a/hotspot/src/share/vm/gc_interface/gcCause.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -103,6 +103,9 @@
case _last_ditch_collection:
return "Last ditch collection";
+ case _dcmd_gc_run:
+ return "Diagnostic Command";
+
case _last_gc_cause:
return "ILLEGAL VALUE - last gc cause - ILLEGAL VALUE";
--- a/hotspot/src/share/vm/gc_interface/gcCause.hpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp Wed Jul 05 20:19:27 2017 +0200
@@ -74,6 +74,9 @@
_g1_humongous_allocation,
_last_ditch_collection,
+
+ _dcmd_gc_run,
+
_last_gc_cause
};
--- a/hotspot/src/share/vm/memory/barrierSet.hpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/memory/barrierSet.hpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,9 +39,7 @@
CardTableModRef,
CardTableExtension,
G1SATBCT,
- G1SATBCTLogging,
- Other,
- Uninit
+ G1SATBCTLogging
};
enum Flags {
@@ -57,9 +55,11 @@
static const int _max_covered_regions = 2;
Name _kind;
+ BarrierSet(Name kind) : _kind(kind) { }
+ ~BarrierSet() { }
+
public:
- BarrierSet() { _kind = Uninit; }
// To get around prohibition on RTTI.
BarrierSet::Name kind() { return _kind; }
virtual bool is_a(BarrierSet::Name bsn) = 0;
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -53,8 +53,8 @@
return align_size_up(_guard_index + 1, MAX2(_page_size, granularity));
}
-CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap) :
- ModRefBarrierSet(),
+CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind) :
+ ModRefBarrierSet(kind),
_whole_heap(whole_heap),
_guard_index(0),
_guard_region(),
@@ -72,8 +72,6 @@
_lowest_non_clean_base_chunk_index(NULL),
_last_LNC_resizing_collection(NULL)
{
- _kind = BarrierSet::CardTableModRef;
-
assert((uintptr_t(_whole_heap.start()) & (card_size - 1)) == 0, "heap must start at card boundary");
assert((uintptr_t(_whole_heap.end()) & (card_size - 1)) == 0, "heap must end at card boundary");
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -284,20 +284,22 @@
return bsn == BarrierSet::CardTableModRef || ModRefBarrierSet::is_a(bsn);
}
- CardTableModRefBS(MemRegion whole_heap);
- ~CardTableModRefBS();
-
virtual void initialize();
// *** Barrier set functions.
bool has_write_ref_pre_barrier() { return false; }
+protected:
+
+ CardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind);
+ ~CardTableModRefBS();
+
// Record a reference update. Note that these versions are precise!
// The scanning code has to handle the fact that the write barrier may be
// either precise or imprecise. We make non-virtual inline variants of
// these functions here for performance.
-protected:
+
void write_ref_field_work(oop obj, size_t offset, oop newVal);
virtual void write_ref_field_work(void* field, oop newVal, bool release = false);
public:
@@ -478,7 +480,7 @@
bool card_may_have_been_dirty(jbyte cv);
public:
CardTableModRefBSForCTRS(MemRegion whole_heap) :
- CardTableModRefBS(whole_heap) {}
+ CardTableModRefBS(whole_heap, BarrierSet::CardTableModRef) {}
void set_CTRS(CardTableRS* rs) { _rs = rs; }
};
--- a/hotspot/src/share/vm/memory/modRefBarrierSet.hpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/memory/modRefBarrierSet.hpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,8 +37,6 @@
class ModRefBarrierSet: public BarrierSet {
public:
- ModRefBarrierSet() { _kind = BarrierSet::ModRef; }
-
bool is_a(BarrierSet::Name bsn) {
return bsn == BarrierSet::ModRef;
}
@@ -59,7 +57,12 @@
void read_ref_field(void* field) {}
void read_prim_field(HeapWord* field, size_t bytes) {}
+
protected:
+
+ ModRefBarrierSet(BarrierSet::Name kind) : BarrierSet(kind) { }
+ ~ModRefBarrierSet() { }
+
virtual void write_ref_field_work(void* field, oop new_val, bool release = false) = 0;
public:
void write_prim_field(HeapWord* field, size_t bytes,
--- a/hotspot/src/share/vm/opto/graphKit.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -1528,7 +1528,6 @@
case BarrierSet::ModRef:
break;
- case BarrierSet::Other:
default :
ShouldNotReachHere();
@@ -1547,7 +1546,6 @@
case BarrierSet::ModRef:
return true; // There is no pre-barrier
- case BarrierSet::Other:
default :
ShouldNotReachHere();
}
@@ -1578,7 +1576,6 @@
case BarrierSet::ModRef:
break;
- case BarrierSet::Other:
default :
ShouldNotReachHere();
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -57,18 +57,6 @@
#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
-// were explicitly requested on the command-line
-#define UNSUPPORTED_OPTION(opt, description) \
-do { \
- if (opt) { \
- if (FLAG_IS_CMDLINE(opt)) { \
- warning(description " is disabled in this release."); \
- } \
- FLAG_SET_DEFAULT(opt, false); \
- } \
-} while(0)
-
#define UNSUPPORTED_GC_OPTION(gc) \
do { \
if (gc) { \
@@ -2316,6 +2304,7 @@
status = status && verify_percentage(G1MaxNewSizePercent, "G1MaxNewSizePercent");
status = status && verify_interval(G1NewSizePercent, 0, G1MaxNewSizePercent, "G1NewSizePercent");
+ status = status && verify_percentage(G1ConfidencePercent, "G1ConfidencePercent");
status = status && verify_percentage(InitiatingHeapOccupancyPercent,
"InitiatingHeapOccupancyPercent");
status = status && verify_min_value(G1RefProcDrainInterval, 1,
@@ -3853,6 +3842,8 @@
#endif
#endif
+ ArgumentsExt::report_unsupported_options();
+
#ifndef PRODUCT
if (TraceBytecodesAt != 0) {
TraceBytecodes = true;
--- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Wed Jul 05 20:19:27 2017 +0200
@@ -632,4 +632,16 @@
return check_gc_consistency_user();
}
+// Disable options not supported in this release, with a warning if they
+// were explicitly requested on the command-line
+#define UNSUPPORTED_OPTION(opt, description) \
+do { \
+ if (opt) { \
+ if (FLAG_IS_CMDLINE(opt)) { \
+ warning(description " is disabled in this release."); \
+ } \
+ FLAG_SET_DEFAULT(opt, false); \
+ } \
+} while(0)
+
#endif // SHARE_VM_RUNTIME_ARGUMENTS_HPP
--- a/hotspot/src/share/vm/runtime/arguments_ext.hpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/runtime/arguments_ext.hpp Wed Jul 05 20:19:27 2017 +0200
@@ -37,6 +37,7 @@
// no additional parsing needed in Arguments::parse() for the option.
// Otherwise returns false.
static inline bool process_options(const JavaVMOption *option) { return false; }
+ static inline void report_unsupported_options() { }
};
void ArgumentsExt::select_gc_ergonomically() {
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -120,7 +120,6 @@
Mutex* OldSets_lock = NULL;
Monitor* RootRegionScan_lock = NULL;
Mutex* MMUTracker_lock = NULL;
-Mutex* HotCardCache_lock = NULL;
Monitor* GCTaskManager_lock = NULL;
@@ -199,7 +198,6 @@
def(OldSets_lock , Mutex , leaf , true, Monitor::_safepoint_check_never);
def(RootRegionScan_lock , Monitor, leaf , true, Monitor::_safepoint_check_never);
def(MMUTracker_lock , Mutex , leaf , true, Monitor::_safepoint_check_never);
- def(HotCardCache_lock , Mutex , special , true, Monitor::_safepoint_check_never);
def(EvacFailureStack_lock , Mutex , nonleaf , true, Monitor::_safepoint_check_never);
def(StringDedupQueue_lock , Monitor, leaf, true, Monitor::_safepoint_check_never);
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -122,7 +122,6 @@
extern Monitor* RootRegionScan_lock; // used to notify that the CM threads have finished scanning the IM snapshot regions
extern Mutex* MMUTracker_lock; // protects the MMU
// tracker data structures
-extern Mutex* HotCardCache_lock; // protects the hot card cache
extern Mutex* Management_lock; // a lock used to serialize JVM management
extern Monitor* Service_lock; // a lock used for service thread operation
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
#include "classfile/javaClasses.hpp"
#include "classfile/loaderConstraints.hpp"
#include "classfile/placeholders.hpp"
+#include "classfile/compactHashtable.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "ci/ciField.hpp"
@@ -243,6 +244,7 @@
typedef Hashtable<Klass*, mtClass> KlassHashtable;
typedef HashtableEntry<Klass*, mtClass> KlassHashtableEntry;
typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
+typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
//--------------------------------------------------------------------------------
// VM_STRUCTS
@@ -624,6 +626,7 @@
/***************/ \
\
static_field(SymbolTable, _the_table, SymbolTable*) \
+ static_field(SymbolTable, _shared_table, SymbolCompactHashTable) \
\
/***************/ \
/* StringTable */ \
@@ -632,6 +635,16 @@
static_field(StringTable, _the_table, StringTable*) \
\
/********************/ \
+ /* CompactHashTable */ \
+ /********************/ \
+ \
+ nonstatic_field(SymbolCompactHashTable, _base_address, uintx) \
+ nonstatic_field(SymbolCompactHashTable, _entry_count, juint) \
+ nonstatic_field(SymbolCompactHashTable, _bucket_count, juint) \
+ nonstatic_field(SymbolCompactHashTable, _table_end_offset, juint) \
+ nonstatic_field(SymbolCompactHashTable, _buckets, juint*) \
+ \
+ /********************/ \
/* SystemDictionary */ \
/********************/ \
\
@@ -1580,6 +1593,8 @@
declare_type(ResourceArea, Arena) \
declare_toplevel_type(Chunk) \
\
+ declare_toplevel_type(SymbolCompactHashTable) \
+ \
/***********************************************************/ \
/* Thread hierarchy (needed for run-time type information) */ \
/***********************************************************/ \
@@ -2213,7 +2228,6 @@
declare_constant(BarrierSet::CardTableExtension) \
declare_constant(BarrierSet::G1SATBCT) \
declare_constant(BarrierSet::G1SATBCTLogging) \
- declare_constant(BarrierSet::Other) \
\
declare_constant(BlockOffsetSharedArray::LogN) \
declare_constant(BlockOffsetSharedArray::LogN_words) \
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Wed Jul 05 20:19:27 2017 +0200
@@ -267,7 +267,7 @@
void SystemGCDCmd::execute(DCmdSource source, TRAPS) {
if (!DisableExplicitGC) {
- Universe::heap()->collect(GCCause::_java_lang_system_gc);
+ Universe::heap()->collect(GCCause::_dcmd_gc_run);
} else {
output()->print_cr("Explicit GC is disabled, no GC has been performed.");
}
--- a/hotspot/test/TEST.groups Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/test/TEST.groups Wed Jul 05 20:19:27 2017 +0200
@@ -97,7 +97,7 @@
runtime/XCheckJniJsig/XCheckJSig.java \
serviceability/attach/AttachWithStalePidFile.java \
serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \
- serviceability/dcmd/DynLibDcmdTest.java
+ serviceability/dcmd/vm/DynLibsTest.java
# JRE adds further tests to compact3
@@ -145,7 +145,8 @@
gc/survivorAlignment \
runtime/InternalApi/ThreadCpuTimesDeadlock.java \
serviceability/threads/TestFalseDeadLock.java \
- compiler/codecache/jmx
+ compiler/codecache/jmx \
+ serviceability/dcmd
# Compact 2 adds full VM tests
compact2 = \
@@ -224,6 +225,7 @@
gc/arguments/TestAlignmentToUseLargePages.java \
gc/arguments/TestG1HeapRegionSize.java \
gc/arguments/TestG1HeapSizeFlags.java \
+ gc/arguments/TestG1PercentageOptions.java \
gc/arguments/TestMaxHeapSizeTools.java \
gc/arguments/TestMaxNewSize.java \
gc/arguments/TestParallelGCThreads.java \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/arguments/TestG1PercentageOptions.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+/*
+ * @test TestG1PercentageOptions
+ * @key gc
+ * @bug 8068942
+ * @summary Test argument processing of various percentage options
+ * @library /testlibrary
+ * @run driver TestG1PercentageOptions
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class TestG1PercentageOptions {
+
+ private static final class OptionDescription {
+ public final String name;
+ public final String[] valid;
+ public final String[] invalid;
+
+ OptionDescription(String name_, String[] valid_, String[] invalid_) {
+ name = name_;
+ valid = valid_;
+ invalid = invalid_;
+ }
+ }
+
+ private static final String[] defaultValid = new String[] {
+ "0", "1", "50", "95", "100" };
+ private static final String[] defaultInvalid = new String[] {
+ "-10", "110", "bad" };
+
+ // All of the G1 product arguments that are percentages.
+ private static final OptionDescription[] percentOptions = new OptionDescription[] {
+ new OptionDescription("G1ConfidencePercent", defaultValid, defaultInvalid)
+ // Other percentage options are not yet validated by argument processing.
+ };
+
+ private static void check(String flag, boolean is_valid) throws Exception {
+ String[] flags = new String[] { "-XX:+UseG1GC", flag, "-version" };
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ if (is_valid) {
+ output.shouldHaveExitValue(0);
+ } else {
+ output.shouldHaveExitValue(1);
+ }
+ }
+
+ private static
+ void check(String name, String value, boolean is_valid) throws Exception {
+ check("-XX:" + name + "=" + value, is_valid);
+ }
+
+ public static void main(String args[]) throws Exception {
+ for (OptionDescription option : percentOptions) {
+ for (String value : option.valid) {
+ check(option.name, value, true);
+ }
+ for (String value : option.invalid) {
+ check(option.name, value, false);
+ }
+ check("-XX:" + option.name, false);
+ check("-XX:+" + option.name, false);
+ check("-XX:-" + option.name, false);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/LocalVariableTable/DuplicateLVT.cod Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// This creates a duplicate LVT entry
+
+class DuplicateLVT {
+ 0xCAFEBABE;
+ 0; // minor version
+ 52; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Method #34 #68; // #1
+ double 0x3FF199999999999A;; // #2
+ float 0x3F99999A; // #4
+ long 0xFFFFFFFFCAFEBABE;; // #5
+ class #69; // #7
+ Method #7 #68; // #8
+ String #70; // #9
+ Method #7 #71; // #10
+ Field #72 #73; // #11
+ class #74; // #12
+ Method #12 #68; // #13
+ String #75; // #14
+ Method #12 #76; // #15
+ Method #12 #77; // #16
+ Method #12 #78; // #17
+ Method #79 #80; // #18
+ String #81; // #19
+ Method #12 #82; // #20
+ String #83; // #21
+ Method #12 #84; // #22
+ String #85; // #23
+ Method #12 #86; // #24
+ String #87; // #25
+ Method #12 #88; // #26
+ String #89; // #27
+ String #90; // #28
+ Method #12 #91; // #29
+ String #92; // #30
+ String #93; // #31
+ Method #12 #94; // #32
+ class #95; // #33
+ class #96; // #34
+ Utf8 "<init>"; // #35
+ Utf8 "()V"; // #36
+ Utf8 "Code"; // #37
+ Utf8 "LineNumberTable"; // #38
+ Utf8 "LocalVariableTable"; // #39
+ Utf8 "this"; // #40
+ Utf8 "LDuplicateLVT;"; // #41
+ Utf8 "main"; // #42
+ Utf8 "([Ljava/lang/String;)V"; // #43
+ Utf8 "args"; // #44
+ Utf8 "[Ljava/lang/String;"; // #45
+ Utf8 "b"; // #46
+ Utf8 "Z"; // #47
+ Utf8 "by"; // #48
+ Utf8 "B"; // #49
+ Utf8 "c"; // #50
+ Utf8 "C"; // #51
+ Utf8 "d"; // #52
+ Utf8 "D"; // #53
+ Utf8 "f"; // #54
+ Utf8 "F"; // #55
+ Utf8 "i"; // #56
+ Utf8 "I"; // #57
+ Utf8 "l"; // #58
+ Utf8 "J"; // #59
+ Utf8 "s"; // #60
+ Utf8 "S"; // #61
+ Utf8 "list"; // #62
+ Utf8 "Ljava/util/ArrayList;"; // #63
+ Utf8 "LocalVariableTypeTable"; // #64
+ Utf8 "Ljava/util/ArrayList<Ljava/lang/String;>;"; // #65
+ Utf8 "SourceFile"; // #66
+ Utf8 "DuplicateLVT.java"; // #67
+ NameAndType #35 #36; // #68
+ Utf8 "java/util/ArrayList"; // #69
+ Utf8 "me"; // #70
+ NameAndType #97 #98; // #71
+ class #99; // #72
+ NameAndType #100 #101; // #73
+ Utf8 "java/lang/StringBuilder"; // #74
+ Utf8 "b="; // #75
+ NameAndType #102 #103; // #76
+ NameAndType #102 #104; // #77
+ NameAndType #105 #106; // #78
+ class #107; // #79
+ NameAndType #108 #109; // #80
+ Utf8 "by="; // #81
+ NameAndType #102 #110; // #82
+ Utf8 "c="; // #83
+ NameAndType #102 #111; // #84
+ Utf8 "d="; // #85
+ NameAndType #102 #112; // #86
+ Utf8 "f="; // #87
+ NameAndType #102 #113; // #88
+ Utf8 "i="; // #89
+ Utf8 "l="; // #90
+ NameAndType #102 #114; // #91
+ Utf8 "s="; // #92
+ Utf8 "ArrayList<String>="; // #93
+ NameAndType #102 #115; // #94
+ Utf8 "DuplicateLVT"; // #95
+ Utf8 "java/lang/Object"; // #96
+ Utf8 "add"; // #97
+ Utf8 "(Ljava/lang/Object;)Z"; // #98
+ Utf8 "java/lang/System"; // #99
+ Utf8 "out"; // #100
+ Utf8 "Ljava/io/PrintStream;"; // #101
+ Utf8 "append"; // #102
+ Utf8 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; // #103
+ Utf8 "(Z)Ljava/lang/StringBuilder;"; // #104
+ Utf8 "toString"; // #105
+ Utf8 "()Ljava/lang/String;"; // #106
+ Utf8 "java/io/PrintStream"; // #107
+ Utf8 "println"; // #108
+ Utf8 "(Ljava/lang/String;)V"; // #109
+ Utf8 "(I)Ljava/lang/StringBuilder;"; // #110
+ Utf8 "(C)Ljava/lang/StringBuilder;"; // #111
+ Utf8 "(D)Ljava/lang/StringBuilder;"; // #112
+ Utf8 "(F)Ljava/lang/StringBuilder;"; // #113
+ Utf8 "(J)Ljava/lang/StringBuilder;"; // #114
+ Utf8 "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; // #115
+ } // Constant Pool
+
+ 0x0021; // access
+ #33;// this_cpx
+ #34;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // fields
+ } // fields
+
+ [] { // methods
+ { // Member
+ 0x0001; // access
+ #35; // name_cpx
+ #36; // sig_cpx
+ [] { // Attributes
+ Attr(#37) { // Code
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0x2AB70001B1;
+ };
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ Attr(#38) { // LineNumberTable
+ [] { // LineNumberTable
+ 0 26;
+ }
+ } // end LineNumberTable
+ ;
+ Attr(#39) { // LocalVariableTable
+ [] { // LocalVariableTable
+ 0 5 40 41 0;
+ }
+ } // end LocalVariableTable
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #42; // name_cpx
+ #43; // sig_cpx
+ [] { // Attributes
+ Attr(#37) { // Code
+ 4; // max_stack
+ 12; // max_locals
+ Bytes[]{
+ 0x043C10423D10583E;
+ 0x1400023904120438;
+ 0x06102A3607140005;
+ 0x37081058360ABB00;
+ 0x0759B700083A0B19;
+ 0x0B1209B6000A57B2;
+ 0x000BBB000C59B700;
+ 0x0D120EB6000F1BB6;
+ 0x0010B60011B60012;
+ 0xB2000BBB000C59B7;
+ 0x000D1213B6000F1C;
+ 0xB60014B60011B600;
+ 0x12B2000BBB000C59;
+ 0xB7000D1215B6000F;
+ 0x1DB60016B60011B6;
+ 0x0012B2000BBB000C;
+ 0x59B7000D1217B600;
+ 0x0F1804B60018B600;
+ 0x11B60012B2000BBB;
+ 0x000C59B7000D1219;
+ 0xB6000F1706B6001A;
+ 0xB60011B60012B200;
+ 0x0BBB000C59B7000D;
+ 0x121BB6000F1507B6;
+ 0x0014B60011B60012;
+ 0xB2000BBB000C59B7;
+ 0x000D121CB6000F16;
+ 0x08B6001DB60011B6;
+ 0x0012B2000BBB000C;
+ 0x59B7000D121EB600;
+ 0x0F150AB60014B600;
+ 0x11B60012B2000BBB;
+ 0x000C59B7000D121F;
+ 0xB6000F190BB60020;
+ 0xB60011B60012B1;
+ };
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ Attr(#38) { // LineNumberTable
+ [] { // LineNumberTable
+ 0 28;
+ 2 29;
+ 5 30;
+ 8 31;
+ 13 32;
+ 17 33;
+ 21 34;
+ 26 35;
+ 30 36;
+ 39 37;
+ 47 39;
+ 72 40;
+ 97 41;
+ 122 42;
+ 148 43;
+ 174 44;
+ 200 45;
+ 226 46;
+ 252 47;
+ 278 48;
+ }
+ } // end LineNumberTable
+ ;
+ Attr(#39) { // LocalVariableTable
+ [] { // LocalVariableTable
+ 0 279 44 45 0;
+ 2 277 46 47 1;
+ 5 274 48 49 2;
+ 5 274 48 49 2;
+ 8 271 50 51 3;
+ 13 266 52 53 4;
+ 17 262 54 55 6;
+ 21 258 56 57 7;
+ 26 253 58 59 8;
+ 30 249 60 61 10;
+ 39 240 62 63 11;
+ }
+ } // end LocalVariableTable
+ ;
+ Attr(#64) { // LocalVariableTypeTable
+ [] { // LocalVariableTypeTable
+ 39 240 62 65 11;
+ }
+ } // end LocalVariableTypeTable
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [] { // Attributes
+ Attr(#66) { // SourceFile
+ #67;
+ } // end SourceFile
+ } // Attributes
+} // end class DuplicateLVT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/LocalVariableTable/DuplicateLVTT.cod Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// There's a duplicate LVTT entry below.
+
+class DuplicateLVTT {
+ 0xCAFEBABE;
+ 0; // minor version
+ 52; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Method #34 #68; // #1
+ double 0x3FF199999999999A;; // #2
+ float 0x3F99999A; // #4
+ long 0xFFFFFFFFCAFEBABE;; // #5
+ class #69; // #7
+ Method #7 #68; // #8
+ String #70; // #9
+ Method #7 #71; // #10
+ Field #72 #73; // #11
+ class #74; // #12
+ Method #12 #68; // #13
+ String #75; // #14
+ Method #12 #76; // #15
+ Method #12 #77; // #16
+ Method #12 #78; // #17
+ Method #79 #80; // #18
+ String #81; // #19
+ Method #12 #82; // #20
+ String #83; // #21
+ Method #12 #84; // #22
+ String #85; // #23
+ Method #12 #86; // #24
+ String #87; // #25
+ Method #12 #88; // #26
+ String #89; // #27
+ String #90; // #28
+ Method #12 #91; // #29
+ String #92; // #30
+ String #93; // #31
+ Method #12 #94; // #32
+ class #95; // #33
+ class #96; // #34
+ Utf8 "<init>"; // #35
+ Utf8 "()V"; // #36
+ Utf8 "Code"; // #37
+ Utf8 "LineNumberTable"; // #38
+ Utf8 "LocalVariableTable"; // #39
+ Utf8 "this"; // #40
+ Utf8 "LDuplicateLVTT;"; // #41
+ Utf8 "main"; // #42
+ Utf8 "([Ljava/lang/String;)V"; // #43
+ Utf8 "args"; // #44
+ Utf8 "[Ljava/lang/String;"; // #45
+ Utf8 "b"; // #46
+ Utf8 "Z"; // #47
+ Utf8 "by"; // #48
+ Utf8 "B"; // #49
+ Utf8 "c"; // #50
+ Utf8 "C"; // #51
+ Utf8 "d"; // #52
+ Utf8 "D"; // #53
+ Utf8 "f"; // #54
+ Utf8 "F"; // #55
+ Utf8 "i"; // #56
+ Utf8 "I"; // #57
+ Utf8 "l"; // #58
+ Utf8 "J"; // #59
+ Utf8 "s"; // #60
+ Utf8 "S"; // #61
+ Utf8 "list"; // #62
+ Utf8 "Ljava/util/ArrayList;"; // #63
+ Utf8 "LocalVariableTypeTable"; // #64
+ Utf8 "Ljava/util/ArrayList<Ljava/lang/String;>;"; // #65
+ Utf8 "SourceFile"; // #66
+ Utf8 "DuplicateLVTT.java"; // #67
+ NameAndType #35 #36; // #68
+ Utf8 "java/util/ArrayList"; // #69
+ Utf8 "me"; // #70
+ NameAndType #97 #98; // #71
+ class #99; // #72
+ NameAndType #100 #101; // #73
+ Utf8 "java/lang/StringBuilder"; // #74
+ Utf8 "b="; // #75
+ NameAndType #102 #103; // #76
+ NameAndType #102 #104; // #77
+ NameAndType #105 #106; // #78
+ class #107; // #79
+ NameAndType #108 #109; // #80
+ Utf8 "by="; // #81
+ NameAndType #102 #110; // #82
+ Utf8 "c="; // #83
+ NameAndType #102 #111; // #84
+ Utf8 "d="; // #85
+ NameAndType #102 #112; // #86
+ Utf8 "f="; // #87
+ NameAndType #102 #113; // #88
+ Utf8 "i="; // #89
+ Utf8 "l="; // #90
+ NameAndType #102 #114; // #91
+ Utf8 "s="; // #92
+ Utf8 "ArrayList<String>="; // #93
+ NameAndType #102 #115; // #94
+ Utf8 "DuplicateLVTT"; // #95
+ Utf8 "java/lang/Object"; // #96
+ Utf8 "add"; // #97
+ Utf8 "(Ljava/lang/Object;)Z"; // #98
+ Utf8 "java/lang/System"; // #99
+ Utf8 "out"; // #100
+ Utf8 "Ljava/io/PrintStream;"; // #101
+ Utf8 "append"; // #102
+ Utf8 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; // #103
+ Utf8 "(Z)Ljava/lang/StringBuilder;"; // #104
+ Utf8 "toString"; // #105
+ Utf8 "()Ljava/lang/String;"; // #106
+ Utf8 "java/io/PrintStream"; // #107
+ Utf8 "println"; // #108
+ Utf8 "(Ljava/lang/String;)V"; // #109
+ Utf8 "(I)Ljava/lang/StringBuilder;"; // #110
+ Utf8 "(C)Ljava/lang/StringBuilder;"; // #111
+ Utf8 "(D)Ljava/lang/StringBuilder;"; // #112
+ Utf8 "(F)Ljava/lang/StringBuilder;"; // #113
+ Utf8 "(J)Ljava/lang/StringBuilder;"; // #114
+ Utf8 "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; // #115
+ } // Constant Pool
+
+ 0x0021; // access
+ #33;// this_cpx
+ #34;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // fields
+ } // fields
+
+ [] { // methods
+ { // Member
+ 0x0001; // access
+ #35; // name_cpx
+ #36; // sig_cpx
+ [] { // Attributes
+ Attr(#37) { // Code
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0x2AB70001B1;
+ };
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ Attr(#38) { // LineNumberTable
+ [] { // LineNumberTable
+ 0 26;
+ }
+ } // end LineNumberTable
+ ;
+ Attr(#39) { // LocalVariableTable
+ [] { // LocalVariableTable
+ 0 5 40 41 0;
+ }
+ } // end LocalVariableTable
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #42; // name_cpx
+ #43; // sig_cpx
+ [] { // Attributes
+ Attr(#37) { // Code
+ 4; // max_stack
+ 12; // max_locals
+ Bytes[]{
+ 0x043C10423D10583E;
+ 0x1400023904120438;
+ 0x06102A3607140005;
+ 0x37081058360ABB00;
+ 0x0759B700083A0B19;
+ 0x0B1209B6000A57B2;
+ 0x000BBB000C59B700;
+ 0x0D120EB6000F1BB6;
+ 0x0010B60011B60012;
+ 0xB2000BBB000C59B7;
+ 0x000D1213B6000F1C;
+ 0xB60014B60011B600;
+ 0x12B2000BBB000C59;
+ 0xB7000D1215B6000F;
+ 0x1DB60016B60011B6;
+ 0x0012B2000BBB000C;
+ 0x59B7000D1217B600;
+ 0x0F1804B60018B600;
+ 0x11B60012B2000BBB;
+ 0x000C59B7000D1219;
+ 0xB6000F1706B6001A;
+ 0xB60011B60012B200;
+ 0x0BBB000C59B7000D;
+ 0x121BB6000F1507B6;
+ 0x0014B60011B60012;
+ 0xB2000BBB000C59B7;
+ 0x000D121CB6000F16;
+ 0x08B6001DB60011B6;
+ 0x0012B2000BBB000C;
+ 0x59B7000D121EB600;
+ 0x0F150AB60014B600;
+ 0x11B60012B2000BBB;
+ 0x000C59B7000D121F;
+ 0xB6000F190BB60020;
+ 0xB60011B60012B1;
+ };
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ Attr(#38) { // LineNumberTable
+ [] { // LineNumberTable
+ 0 28;
+ 2 29;
+ 5 30;
+ 8 31;
+ 13 32;
+ 17 33;
+ 21 34;
+ 26 35;
+ 30 36;
+ 39 37;
+ 47 39;
+ 72 40;
+ 97 41;
+ 122 42;
+ 148 43;
+ 174 44;
+ 200 45;
+ 226 46;
+ 252 47;
+ 278 48;
+ }
+ } // end LineNumberTable
+ ;
+ Attr(#39) { // LocalVariableTable
+ [] { // LocalVariableTable
+ 0 279 44 45 0;
+ 2 277 46 47 1;
+ 5 274 48 49 2;
+ 8 271 50 51 3;
+ 13 266 52 53 4;
+ 17 262 54 55 6;
+ 21 258 56 57 7;
+ 26 253 58 59 8;
+ 30 249 60 61 10;
+ 39 240 62 63 11;
+ }
+ } // end LocalVariableTable
+ ;
+ Attr(#64) { // LocalVariableTypeTable
+ [] { // LocalVariableTypeTable
+ 39 240 62 65 11;
+ 39 240 62 65 11;
+ }
+ } // end LocalVariableTypeTable
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [] { // Attributes
+ Attr(#66) { // SourceFile
+ #67;
+ } // end SourceFile
+ } // Attributes
+} // end class DuplicateLVTT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/LocalVariableTable/NotFoundLVTT.cod Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// The LVTT entry points to a non-existant LVT entry
+
+class NotFoundLVTT {
+ 0xCAFEBABE;
+ 0; // minor version
+ 52; // version
+ [] { // Constant Pool
+ ; // first element is empty
+ Method #34 #68; // #1
+ double 0x3FF199999999999A;; // #2
+ float 0x3F99999A; // #4
+ long 0xFFFFFFFFCAFEBABE;; // #5
+ class #69; // #7
+ Method #7 #68; // #8
+ String #70; // #9
+ Method #7 #71; // #10
+ Field #72 #73; // #11
+ class #74; // #12
+ Method #12 #68; // #13
+ String #75; // #14
+ Method #12 #76; // #15
+ Method #12 #77; // #16
+ Method #12 #78; // #17
+ Method #79 #80; // #18
+ String #81; // #19
+ Method #12 #82; // #20
+ String #83; // #21
+ Method #12 #84; // #22
+ String #85; // #23
+ Method #12 #86; // #24
+ String #87; // #25
+ Method #12 #88; // #26
+ String #89; // #27
+ String #90; // #28
+ Method #12 #91; // #29
+ String #92; // #30
+ String #93; // #31
+ Method #12 #94; // #32
+ class #95; // #33
+ class #96; // #34
+ Utf8 "<init>"; // #35
+ Utf8 "()V"; // #36
+ Utf8 "Code"; // #37
+ Utf8 "LineNumberTable"; // #38
+ Utf8 "LocalVariableTable"; // #39
+ Utf8 "this"; // #40
+ Utf8 "LNotFoundLVTT;"; // #41
+ Utf8 "main"; // #42
+ Utf8 "([Ljava/lang/String;)V"; // #43
+ Utf8 "args"; // #44
+ Utf8 "[Ljava/lang/String;"; // #45
+ Utf8 "b"; // #46
+ Utf8 "Z"; // #47
+ Utf8 "by"; // #48
+ Utf8 "B"; // #49
+ Utf8 "c"; // #50
+ Utf8 "C"; // #51
+ Utf8 "d"; // #52
+ Utf8 "D"; // #53
+ Utf8 "f"; // #54
+ Utf8 "F"; // #55
+ Utf8 "i"; // #56
+ Utf8 "I"; // #57
+ Utf8 "l"; // #58
+ Utf8 "J"; // #59
+ Utf8 "s"; // #60
+ Utf8 "S"; // #61
+ Utf8 "list"; // #62
+ Utf8 "Ljava/util/ArrayList;"; // #63
+ Utf8 "LocalVariableTypeTable"; // #64
+ Utf8 "Ljava/util/ArrayList<Ljava/lang/String;>;"; // #65
+ Utf8 "SourceFile"; // #66
+ Utf8 "NotFoundLVTT.java"; // #67
+ NameAndType #35 #36; // #68
+ Utf8 "java/util/ArrayList"; // #69
+ Utf8 "me"; // #70
+ NameAndType #97 #98; // #71
+ class #99; // #72
+ NameAndType #100 #101; // #73
+ Utf8 "java/lang/StringBuilder"; // #74
+ Utf8 "b="; // #75
+ NameAndType #102 #103; // #76
+ NameAndType #102 #104; // #77
+ NameAndType #105 #106; // #78
+ class #107; // #79
+ NameAndType #108 #109; // #80
+ Utf8 "by="; // #81
+ NameAndType #102 #110; // #82
+ Utf8 "c="; // #83
+ NameAndType #102 #111; // #84
+ Utf8 "d="; // #85
+ NameAndType #102 #112; // #86
+ Utf8 "f="; // #87
+ NameAndType #102 #113; // #88
+ Utf8 "i="; // #89
+ Utf8 "l="; // #90
+ NameAndType #102 #114; // #91
+ Utf8 "s="; // #92
+ Utf8 "ArrayList<String>="; // #93
+ NameAndType #102 #115; // #94
+ Utf8 "NotFoundLVTT"; // #95
+ Utf8 "java/lang/Object"; // #96
+ Utf8 "add"; // #97
+ Utf8 "(Ljava/lang/Object;)Z"; // #98
+ Utf8 "java/lang/System"; // #99
+ Utf8 "out"; // #100
+ Utf8 "Ljava/io/PrintStream;"; // #101
+ Utf8 "append"; // #102
+ Utf8 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; // #103
+ Utf8 "(Z)Ljava/lang/StringBuilder;"; // #104
+ Utf8 "toString"; // #105
+ Utf8 "()Ljava/lang/String;"; // #106
+ Utf8 "java/io/PrintStream"; // #107
+ Utf8 "println"; // #108
+ Utf8 "(Ljava/lang/String;)V"; // #109
+ Utf8 "(I)Ljava/lang/StringBuilder;"; // #110
+ Utf8 "(C)Ljava/lang/StringBuilder;"; // #111
+ Utf8 "(D)Ljava/lang/StringBuilder;"; // #112
+ Utf8 "(F)Ljava/lang/StringBuilder;"; // #113
+ Utf8 "(J)Ljava/lang/StringBuilder;"; // #114
+ Utf8 "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; // #115
+ } // Constant Pool
+
+ 0x0021; // access
+ #33;// this_cpx
+ #34;// super_cpx
+
+ [] { // Interfaces
+ } // Interfaces
+
+ [] { // fields
+ } // fields
+
+ [] { // methods
+ { // Member
+ 0x0001; // access
+ #35; // name_cpx
+ #36; // sig_cpx
+ [] { // Attributes
+ Attr(#37) { // Code
+ 1; // max_stack
+ 1; // max_locals
+ Bytes[]{
+ 0x2AB70001B1;
+ };
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ Attr(#38) { // LineNumberTable
+ [] { // LineNumberTable
+ 0 26;
+ }
+ } // end LineNumberTable
+ ;
+ Attr(#39) { // LocalVariableTable
+ [] { // LocalVariableTable
+ 0 5 40 41 0;
+ }
+ } // end LocalVariableTable
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ ;
+ { // Member
+ 0x0009; // access
+ #42; // name_cpx
+ #43; // sig_cpx
+ [] { // Attributes
+ Attr(#37) { // Code
+ 4; // max_stack
+ 12; // max_locals
+ Bytes[]{
+ 0x043C10423D10583E;
+ 0x1400023904120438;
+ 0x06102A3607140005;
+ 0x37081058360ABB00;
+ 0x0759B700083A0B19;
+ 0x0B1209B6000A57B2;
+ 0x000BBB000C59B700;
+ 0x0D120EB6000F1BB6;
+ 0x0010B60011B60012;
+ 0xB2000BBB000C59B7;
+ 0x000D1213B6000F1C;
+ 0xB60014B60011B600;
+ 0x12B2000BBB000C59;
+ 0xB7000D1215B6000F;
+ 0x1DB60016B60011B6;
+ 0x0012B2000BBB000C;
+ 0x59B7000D1217B600;
+ 0x0F1804B60018B600;
+ 0x11B60012B2000BBB;
+ 0x000C59B7000D1219;
+ 0xB6000F1706B6001A;
+ 0xB60011B60012B200;
+ 0x0BBB000C59B7000D;
+ 0x121BB6000F1507B6;
+ 0x0014B60011B60012;
+ 0xB2000BBB000C59B7;
+ 0x000D121CB6000F16;
+ 0x08B6001DB60011B6;
+ 0x0012B2000BBB000C;
+ 0x59B7000D121EB600;
+ 0x0F150AB60014B600;
+ 0x11B60012B2000BBB;
+ 0x000C59B7000D121F;
+ 0xB6000F190BB60020;
+ 0xB60011B60012B1;
+ };
+ [] { // Traps
+ } // end Traps
+ [] { // Attributes
+ Attr(#38) { // LineNumberTable
+ [] { // LineNumberTable
+ 0 28;
+ 2 29;
+ 5 30;
+ 8 31;
+ 13 32;
+ 17 33;
+ 21 34;
+ 26 35;
+ 30 36;
+ 39 37;
+ 47 39;
+ 72 40;
+ 97 41;
+ 122 42;
+ 148 43;
+ 174 44;
+ 200 45;
+ 226 46;
+ 252 47;
+ 278 48;
+ }
+ } // end LineNumberTable
+ ;
+ Attr(#39) { // LocalVariableTable
+ [] { // LocalVariableTable
+ 0 279 44 45 0;
+ 2 277 46 47 1;
+ 5 274 48 49 2;
+ 8 271 50 51 3;
+ 13 266 52 53 4;
+ 17 262 54 55 6;
+ 21 258 56 57 7;
+ 26 253 58 59 8;
+ 30 249 60 61 10;
+ 39 240 62 63 11;
+ }
+ } // end LocalVariableTable
+ ;
+ Attr(#64) { // LocalVariableTypeTable
+ [] { // LocalVariableTypeTable
+ 38 240 62 65 11;
+ }
+ } // end LocalVariableTypeTable
+ } // Attributes
+ } // end Code
+ } // Attributes
+ } // Member
+ } // methods
+
+ [] { // Attributes
+ Attr(#66) { // SourceFile
+ #67;
+ } // end SourceFile
+ } // Attributes
+} // end class NotFoundLVTT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/LocalVariableTable/TestLVT.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8049632
+ * @summary Test ClassFileParser::copy_localvariable_table cases
+ * @library /testlibrary
+ * @compile -g -XDignore.symbol.file TestLVT.java
+ * @run main TestLVT
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.util.*;
+
+public class TestLVT {
+ public static void main(String[] args) throws Exception {
+ test(); // Test good LVT in this test
+
+ String jarFile = System.getProperty("test.src") + "/testcase.jar";
+
+ // java -cp $testSrc/testcase.jar DuplicateLVT
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-cp", jarFile, "DuplicateLVT");
+ new OutputAnalyzer(pb.start())
+ .shouldContain("Duplicated LocalVariableTable attribute entry for 'by' in class file DuplicateLVT")
+ .shouldHaveExitValue(1);
+
+ // java -cp $testclasses/testcase.jar DuplicateLVTT
+ pb = ProcessTools.createJavaProcessBuilder("-cp", jarFile, "DuplicateLVTT");
+ new OutputAnalyzer(pb.start())
+ .shouldContain("Duplicated LocalVariableTypeTable attribute entry for 'list' in class file DuplicateLVTT")
+ .shouldHaveExitValue(1);
+
+ // java -cp $testclasses/testcase.jar NotFoundLVTT
+ pb = ProcessTools.createJavaProcessBuilder("-cp", jarFile, "NotFoundLVTT");
+ new OutputAnalyzer(pb.start())
+ .shouldContain("LVTT entry for 'list' in class file NotFoundLVTT does not match any LVT entry")
+ .shouldHaveExitValue(1);
+ }
+
+ public static void test() {
+ boolean b = true;
+ byte by = 0x42;
+ char c = 'X';
+ double d = 1.1;
+ float f = (float) 1.2;
+ int i = 42;
+ long l = 0xCAFEBABE;
+ short s = 88;
+ ArrayList<String> list = new ArrayList<String>();
+ list.add("me");
+
+ System.out.println("b=" + b);
+ System.out.println("by=" + by);
+ System.out.println("c=" + c);
+ System.out.println("d=" + d);
+ System.out.println("f=" + f);
+ System.out.println("i=" + i);
+ System.out.println("l=" + l);
+ System.out.println("s=" + s);
+ System.out.println("ArrayList<String>=" + list);
+ }
+}
Binary file hotspot/test/runtime/LocalVariableTable/testcase.jar has changed
--- a/hotspot/test/runtime/Unsafe/AllocateMemory.java Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/test/runtime/Unsafe/AllocateMemory.java Wed Jul 05 20:19:27 2017 +0200
@@ -25,7 +25,7 @@
* @test
* @summary Verifies behaviour of Unsafe.allocateMemory
* @library /testlibrary
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=20m AllocateMemory
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m AllocateMemory
*/
import com.oracle.java.testlibrary.*;
@@ -56,7 +56,7 @@
// allocateMemory() should throw an OutOfMemoryError when the underlying malloc fails,
// we test this by limiting the malloc using -XX:MallocMaxTestWords
try {
- address = unsafe.allocateMemory(20 * 1024 * 1024 * 8);
+ address = unsafe.allocateMemory(100 * 1024 * 1024 * 8);
} catch (OutOfMemoryError e) {
// Expected
return;
--- a/hotspot/test/serviceability/attach/AttachWithStalePidFile.java Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/test/serviceability/attach/AttachWithStalePidFile.java Wed Jul 05 20:19:27 2017 +0200
@@ -26,6 +26,7 @@
* @bug 7162400
* @key regression
* @summary Regression test for attach issue where stale pid files in /tmp lead to connection issues
+ * @ignore 8024055
* @library /testlibrary
* @build com.oracle.java.testlibrary.* AttachWithStalePidFileTarget
* @run main AttachWithStalePidFile
--- a/hotspot/test/serviceability/dcmd/ClassLoaderStatsTest.java Thu Feb 12 16:23:24 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/*
- * 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
- *
- * @build ClassLoaderStatsTest DcmdUtil
- * @run main ClassLoaderStatsTest
- */
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.StringReader;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class ClassLoaderStatsTest {
-
- // ClassLoader Parent CLD* Classes ChunkSz BlockSz Type
- // 0x00000007c0215928 0x0000000000000000 0x0000000000000000 0 0 0 org.eclipse.osgi.baseadaptor.BaseAdaptor$1
- // 0x00000007c0009868 0x0000000000000000 0x00007fc52aebcc80 1 6144 3768 sun.reflect.DelegatingClassLoader
- // 0x00000007c0009868 0x0000000000000000 0x00007fc52b8916d0 1 6144 3688 sun.reflect.DelegatingClassLoader
- // 0x00000007c0009868 0x00000007c0038ba8 0x00007fc52afb8760 1 6144 3688 sun.reflect.DelegatingClassLoader
- // 0x00000007c0009868 0x0000000000000000 0x00007fc52afbb1a0 1 6144 3688 sun.reflect.DelegatingClassLoader
- // 0x0000000000000000 0x0000000000000000 0x00007fc523416070 5019 30060544 29956216 <boot classloader>
- // 455 1210368 672848 + unsafe anonymous classes
- // 0x00000007c016b5c8 0x00000007c0038ba8 0x00007fc52a995000 5 8192 5864 org.netbeans.StandardModule$OneModuleClassLoader
- // 0x00000007c0009868 0x00000007c016b5c8 0x00007fc52ac13640 1 6144 3896 sun.reflect.DelegatingClassLoader
- // ...
-
- static Pattern clLine = Pattern.compile("0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*(.*)");
- static Pattern anonLine = Pattern.compile("\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*.*");
-
- public static DummyClassLoader dummyloader;
-
- public static void main(String arg[]) throws Exception {
-
- // create a classloader and load our special class
- dummyloader = new DummyClassLoader();
- Class<?> c = Class.forName("TestClass", true, dummyloader);
- if (c.getClassLoader() != dummyloader) {
- throw new RuntimeException("TestClass defined by wrong classloader: " + c.getClassLoader());
- }
-
- String result = DcmdUtil.executeDcmd("VM.classloader_stats");
- BufferedReader r = new BufferedReader(new StringReader(result));
- String line;
- while((line = r.readLine()) != null) {
- Matcher m = clLine.matcher(line);
- if (m.matches()) {
- // verify that DummyClassLoader has loaded 1 class and 1 anonymous class
- if (m.group(4).equals("ClassLoaderStatsTest$DummyClassLoader")) {
- System.out.println("line: " + line);
- if (!m.group(1).equals("1")) {
- throw new Exception("Should have loaded 1 class: " + line);
- }
- checkPositiveInt(m.group(2));
- checkPositiveInt(m.group(3));
-
- String next = r.readLine();
- System.out.println("next: " + next);
- Matcher m1 = anonLine.matcher(next);
- m1.matches();
- if (!m1.group(1).equals("1")) {
- throw new Exception("Should have loaded 1 anonymous class, but found : " + m1.group(1));
- }
- checkPositiveInt(m1.group(2));
- checkPositiveInt(m1.group(3));
- }
- }
- }
- }
-
- private static void checkPositiveInt(String s) throws Exception {
- if (Integer.parseInt(s) <= 0) {
- throw new Exception("Value should have been > 0: " + s);
- }
- }
-
- public static class DummyClassLoader extends ClassLoader {
-
- public static final String CLASS_NAME = "TestClass";
-
- static ByteBuffer readClassFile(String name)
- {
- File f = new File(System.getProperty("test.classes", "."),
- name);
- try (FileInputStream fin = new FileInputStream(f);
- FileChannel fc = fin.getChannel())
- {
- return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
- } catch (IOException e) {
- throw new RuntimeException("Can't open file: " + name, e);
- }
- }
-
- protected Class<?> loadClass(String name, boolean resolve)
- throws ClassNotFoundException
- {
- Class<?> c;
- if (!"TestClass".equals(name)) {
- c = super.loadClass(name, resolve);
- } else {
- // should not delegate to the system class loader
- c = findClass(name);
- if (resolve) {
- resolveClass(c);
- }
- }
- return c;
- }
-
- protected Class<?> findClass(String name)
- throws ClassNotFoundException
- {
- if (!"TestClass".equals(name)) {
- throw new ClassNotFoundException("Unexpected class: " + name);
- }
- return defineClass(name, readClassFile(name + ".class"), null);
- }
- } /* DummyClassLoader */
-
-}
-
-class TestClass {
- static {
- // force creation of anonymous class (for the lambdaform)
- Runnable r = () -> System.out.println("Hello");
- r.run();
- }
-}
--- a/hotspot/test/serviceability/dcmd/DcmdUtil.java Thu Feb 12 16:23:24 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import sun.management.ManagementFactoryHelper;
-
-import com.sun.management.DiagnosticCommandMBean;
-
-public class DcmdUtil
-{
- public static String executeDcmd(String cmd, String ... args) {
- DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean();
- Object[] dcmdArgs = {args};
- String[] signature = {String[].class.getName()};
-
- try {
- System.out.print("> " + cmd + " ");
- for (String s : args) {
- System.out.print(s + " ");
- }
- System.out.println(":");
- String result = (String) dcmd.invoke(transform(cmd), dcmdArgs, signature);
- System.out.println(result);
- return result;
- } catch(Exception ex) {
- ex.printStackTrace();
- }
- return null;
- }
-
- private static String transform(String name) {
- StringBuilder sb = new StringBuilder();
- boolean toLower = true;
- boolean toUpper = false;
- for (int i = 0; i < name.length(); i++) {
- char c = name.charAt(i);
- if (c == '.' || c == '_') {
- toLower = false;
- toUpper = true;
- } else {
- if (toUpper) {
- toUpper = false;
- sb.append(Character.toUpperCase(c));
- } else if(toLower) {
- sb.append(Character.toLowerCase(c));
- } else {
- sb.append(c);
- }
- }
- }
- return sb.toString();
- }
-
-}
--- a/hotspot/test/serviceability/dcmd/DynLibDcmdTest.java Thu Feb 12 16:23:24 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-import java.util.HashSet;
-import java.util.Set;
-import com.oracle.java.testlibrary.Platform;
-
-/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @summary Test of VM.dynlib diagnostic command via MBean
- * @library /testlibrary
- * @build com.oracle.java.testlibrary.* DcmdUtil
- * @run main DynLibDcmdTest
- */
-
-public class DynLibDcmdTest {
-
- public static void main(String[] args) throws Exception {
- String result = DcmdUtil.executeDcmd("VM.dynlibs");
-
- String osDependentBaseString = null;
- if (Platform.isAix()) {
- osDependentBaseString = "lib%s.so";
- } else if (Platform.isLinux()) {
- osDependentBaseString = "lib%s.so";
- } else if (Platform.isOSX()) {
- osDependentBaseString = "lib%s.dylib";
- } else if (Platform.isSolaris()) {
- osDependentBaseString = "lib%s.so";
- } else if (Platform.isWindows()) {
- osDependentBaseString = "%s.dll";
- }
-
- if (osDependentBaseString == null) {
- throw new Exception("Unsupported OS");
- }
-
- Set<String> expectedContent = new HashSet<>();
- expectedContent.add(String.format(osDependentBaseString, "jvm"));
- expectedContent.add(String.format(osDependentBaseString, "java"));
- expectedContent.add(String.format(osDependentBaseString, "management"));
-
- for(String expected : expectedContent) {
- if (!result.contains(expected)) {
- throw new Exception("Dynamic library list output did not contain the expected string: '" + expected + "'");
- }
- }
- }
-}
--- a/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -24,17 +24,23 @@
/*
* @test CodeCacheTest
* @bug 8054889
- * @library ..
- * @build DcmdUtil CodeCacheTest
- * @run main/othervm -XX:+SegmentedCodeCache CodeCacheTest
- * @run main/othervm -XX:-SegmentedCodeCache CodeCacheTest
- * @run main/othervm -Xint -XX:+SegmentedCodeCache CodeCacheTest
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng/othervm -XX:+SegmentedCodeCache CodeCacheTest
+ * @run testng/othervm -XX:-SegmentedCodeCache CodeCacheTest
+ * @run testng/othervm -Xint -XX:+SegmentedCodeCache CodeCacheTest
* @summary Test of diagnostic command Compiler.codecache
*/
-import java.io.BufferedReader;
-import java.io.StringReader;
-import java.lang.reflect.Method;
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
+import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -72,7 +78,7 @@
private static boolean getFlagBool(String flag, String where) {
Matcher m = Pattern.compile(flag + "\\s+:?= (true|false)").matcher(where);
if (!m.find()) {
- throw new RuntimeException("Could not find value for flag " + flag + " in output string");
+ Assert.fail("Could not find value for flag " + flag + " in output string");
}
return m.group(1).equals("true");
}
@@ -80,16 +86,16 @@
private static int getFlagInt(String flag, String where) {
Matcher m = Pattern.compile(flag + "\\s+:?=\\s+\\d+").matcher(where);
if (!m.find()) {
- throw new RuntimeException("Could not find value for flag " + flag + " in output string");
+ Assert.fail("Could not find value for flag " + flag + " in output string");
}
String match = m.group();
return Integer.parseInt(match.substring(match.lastIndexOf(" ") + 1, match.length()));
}
- public static void main(String arg[]) throws Exception {
+ public void run(CommandExecutor executor) {
// Get number of code cache segments
int segmentsCount = 0;
- String flags = DcmdUtil.executeDcmd("VM.flags", "-all");
+ String flags = executor.execute("VM.flags -all").getOutput();
if (!getFlagBool("SegmentedCodeCache", flags) || !getFlagBool("UseCompiler", flags)) {
// No segmentation
segmentsCount = 1;
@@ -102,29 +108,29 @@
}
// Get output from dcmd (diagnostic command)
- String result = DcmdUtil.executeDcmd("Compiler.codecache");
- BufferedReader r = new BufferedReader(new StringReader(result));
+ OutputAnalyzer output = executor.execute("Compiler.codecache");
+ Iterator<String> lines = output.asLines().iterator();
// Validate code cache segments
String line;
Matcher m;
for (int s = 0; s < segmentsCount; ++s) {
// Validate first line
- line = r.readLine();
+ line = lines.next();
m = line1.matcher(line);
if (m.matches()) {
for (int i = 2; i <= 5; i++) {
int val = Integer.parseInt(m.group(i));
if (val < 0) {
- throw new Exception("Failed parsing dcmd codecache output");
+ Assert.fail("Failed parsing dcmd codecache output");
}
}
} else {
- throw new Exception("Regexp 1 failed");
+ Assert.fail("Regexp 1 failed to match line: " + line);
}
// Validate second line
- line = r.readLine();
+ line = lines.next();
m = line2.matcher(line);
if (m.matches()) {
String start = m.group(1);
@@ -133,44 +139,49 @@
// Lexical compare of hex numbers to check that they look sane.
if (start.compareTo(mark) > 1) {
- throw new Exception("Failed parsing dcmd codecache output");
+ Assert.fail("Failed parsing dcmd codecache output");
}
if (mark.compareTo(top) > 1) {
- throw new Exception("Failed parsing dcmd codecache output");
+ Assert.fail("Failed parsing dcmd codecache output");
}
} else {
- throw new Exception("Regexp 2 failed line: " + line);
+ Assert.fail("Regexp 2 failed to match line: " + line);
}
}
// Validate third line
- line = r.readLine();
+ line = lines.next();
m = line3.matcher(line);
if (m.matches()) {
int blobs = Integer.parseInt(m.group(1));
if (blobs <= 0) {
- throw new Exception("Failed parsing dcmd codecache output");
+ Assert.fail("Failed parsing dcmd codecache output");
}
int nmethods = Integer.parseInt(m.group(2));
if (nmethods < 0) {
- throw new Exception("Failed parsing dcmd codecache output");
+ Assert.fail("Failed parsing dcmd codecache output");
}
int adapters = Integer.parseInt(m.group(3));
if (adapters <= 0) {
- throw new Exception("Failed parsing dcmd codecache output");
+ Assert.fail("Failed parsing dcmd codecache output");
}
if (blobs < (nmethods + adapters)) {
- throw new Exception("Failed parsing dcmd codecache output");
+ Assert.fail("Failed parsing dcmd codecache output");
}
} else {
- throw new Exception("Regexp 3 failed");
+ Assert.fail("Regexp 3 failed to match line: " + line);
}
// Validate fourth line
- line = r.readLine();
+ line = lines.next();
m = line4.matcher(line);
if (!m.matches()) {
- throw new Exception("Regexp 4 failed");
+ Assert.fail("Regexp 4 failed to match line: " + line);
}
}
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
}
--- a/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -24,14 +24,21 @@
/*
* @test CodelistTest
* @bug 8054889
- * @library ..
- * @build DcmdUtil MethodIdentifierParser CodelistTest
- * @run main CodelistTest
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @build MethodIdentifierParser
+ * @run testng CodelistTest
* @summary Test of diagnostic command Compiler.codelist
*/
-import java.io.BufferedReader;
-import java.io.StringReader;
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
import java.lang.reflect.Method;
public class CodelistTest {
@@ -51,19 +58,17 @@
*
*/
- public static void main(String arg[]) throws Exception {
+ public void run(CommandExecutor executor) {
int ok = 0;
int fail = 0;
// Get output from dcmd (diagnostic command)
- String result = DcmdUtil.executeDcmd("Compiler.codelist");
- BufferedReader r = new BufferedReader(new StringReader(result));
+ OutputAnalyzer output = executor.execute("Compiler.codelist");
// Grab a method name from the output
- String line;
int count = 0;
- while((line = r.readLine()) != null) {
+ for (String line : output.asLines()) {
count++;
String[] parts = line.split(" ");
@@ -83,14 +88,16 @@
}
MethodIdentifierParser mf = new MethodIdentifierParser(methodPrintedInLogFormat);
- Method m;
+ Method m = null;
try {
m = mf.getMethod();
} catch (NoSuchMethodException e) {
m = null;
+ } catch (ClassNotFoundException e) {
+ Assert.fail("Test error: Caught unexpected exception", e);
}
if (m == null) {
- throw new Exception("Test failed on: " + methodPrintedInLogFormat);
+ Assert.fail("Test failed on: " + methodPrintedInLogFormat);
}
if (count > 10) {
// Testing 10 entries is enough. Lets not waste time.
@@ -98,4 +105,9 @@
}
}
}
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
}
--- a/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -24,17 +24,22 @@
/*
* @test CompilerQueueTest
* @bug 8054889
- * @library ..
+ * @library /testlibrary
* @ignore 8069160
- * @build DcmdUtil CompilerQueueTest
- * @run main CompilerQueueTest
- * @run main/othervm -XX:-TieredCompilation CompilerQueueTest
- * @run main/othervm -Xint CompilerQueueTest
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng CompilerQueueTest
+ * @run testng/othervm -XX:-TieredCompilation CompilerQueueTest
+ * @run testng/othervm -Xint CompilerQueueTest
* @summary Test of diagnostic command Compiler.queue
*/
-import java.io.BufferedReader;
-import java.io.StringReader;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+import org.testng.annotations.Test;
+
+import java.util.Iterator;
public class CompilerQueueTest {
@@ -60,52 +65,55 @@
*
**/
- public static void main(String arg[]) throws Exception {
+ public void run(CommandExecutor executor) {
// Get output from dcmd (diagnostic command)
- String result = DcmdUtil.executeDcmd("Compiler.queue");
- BufferedReader r = new BufferedReader(new StringReader(result));
-
- String str = r.readLine();
+ OutputAnalyzer output = executor.execute("Compiler.queue");
+ Iterator<String> lines = output.asLines().iterator();
- while (str != null) {
+ while (lines.hasNext()) {
+ String str = lines.next();
if (str.startsWith("Contents of C")) {
- match(r.readLine(), "----------------------------");
- str = r.readLine();
+ match(lines.next(), "----------------------------");
+ str = lines.next();
if (!str.equals("Empty")) {
while (str.charAt(0) != '-') {
validateMethodLine(str);
- str = r.readLine();
+ str = lines.next();
}
} else {
- str = r.readLine();
+ str = lines.next();
}
match(str,"----------------------------");
- str = r.readLine();
} else {
- throw new Exception("Failed parsing dcmd queue, line: " + str);
+ Assert.fail("Failed parsing dcmd queue, line: " + str);
}
}
}
- private static void validateMethodLine(String str) throws Exception {
+ private static void validateMethodLine(String str) {
// Skip until package/class name begins. Trim to remove whitespace that
// may differ.
String name = str.substring(14).trim();
int sep = name.indexOf("::");
if (sep == -1) {
- throw new Exception("Failed dcmd queue, didn't find separator :: in: " + name);
+ Assert.fail("Failed dcmd queue, didn't find separator :: in: " + name);
}
try {
Class.forName(name.substring(0, sep));
} catch (ClassNotFoundException e) {
- throw new Exception("Failed dcmd queue, Class for name: " + str);
+ Assert.fail("Failed dcmd queue, Class for name: " + str);
}
}
- public static void match(String line, String str) throws Exception {
+ public static void match(String line, String str) {
if (!line.equals(str)) {
- throw new Exception("String equals: " + line + ", " + str);
+ Assert.fail("String equals: " + line + ", " + str);
}
}
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
}
--- a/hotspot/test/serviceability/dcmd/compiler/MethodIdentifierParser.java Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/test/serviceability/dcmd/compiler/MethodIdentifierParser.java Wed Jul 05 20:19:27 2017 +0200
@@ -51,11 +51,11 @@
// Add sanity check for extracted fields
}
- public Method getMethod() throws NoSuchMethodException, SecurityException, ClassNotFoundException, Exception {
+ public Method getMethod() throws NoSuchMethodException, SecurityException, ClassNotFoundException {
try {
return Class.forName(className).getDeclaredMethod(methodName, getParamenterDescriptorArray());
} catch (UnexpectedTokenException e) {
- throw new Exception("Parse failed");
+ throw new RuntimeException("Parse failed");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/framework/HelpTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
+import com.oracle.java.testlibrary.dcmd.MainClassJcmdExecutor;
+import com.oracle.java.testlibrary.dcmd.FileJcmdExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @summary Test of diagnostic command help (tests all DCMD executors)
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng/othervm -XX:+UsePerfData HelpTest
+ */
+public class HelpTest {
+ public void run(CommandExecutor executor) {
+ OutputAnalyzer output = executor.execute("help");
+
+ output.shouldContain("The following commands are available");
+ output.shouldContain("help");
+ output.shouldContain("VM.version");
+ }
+
+ @Test
+ public void pid() {
+ run(new PidJcmdExecutor());
+ }
+
+ @Test
+ public void mainClass() {
+ run(new MainClassJcmdExecutor());
+ }
+
+ @Test
+ public void file() {
+ run(new FileJcmdExecutor());
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
+import com.oracle.java.testlibrary.dcmd.MainClassJcmdExecutor;
+import com.oracle.java.testlibrary.dcmd.FileJcmdExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @summary Test of invalid diagnostic command (tests all DCMD executors)
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng/othervm -XX:+UsePerfData InvalidCommandTest
+ */
+public class InvalidCommandTest {
+
+ public void run(CommandExecutor executor) {
+ OutputAnalyzer output = executor.execute("asdf");
+ output.shouldContain("Unknown diagnostic command");
+ }
+
+ @Test
+ public void pid() {
+ run(new PidJcmdExecutor());
+ }
+
+ @Test
+ public void mainClass() {
+ run(new MainClassJcmdExecutor());
+ }
+
+ @Test
+ public void file() {
+ run(new FileJcmdExecutor());
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/framework/VMVersionTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
+import com.oracle.java.testlibrary.dcmd.MainClassJcmdExecutor;
+import com.oracle.java.testlibrary.dcmd.FileJcmdExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @summary Test of diagnostic command VM.version (tests all DCMD executors)
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng/othervm -XX:+UsePerfData VMVersionTest
+ */
+public class VMVersionTest {
+ public void run(CommandExecutor executor) {
+ OutputAnalyzer output = executor.execute("VM.version");
+ output.shouldMatch(".*(?:HotSpot|OpenJDK).*VM.*");
+ }
+
+ @Test
+ public void pid() {
+ run(new PidJcmdExecutor());
+ }
+
+ @Test
+ public void mainClass() {
+ run(new MainClassJcmdExecutor());
+ }
+
+ @Test
+ public void file() {
+ run(new FileJcmdExecutor());
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/ClassHistogramAllTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test of diagnostic command GC.class_histogram -all=true
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @build ClassHistogramTest
+ * @run testng ClassHistogramAllTest
+ */
+public class ClassHistogramAllTest extends ClassHistogramTest {
+ public ClassHistogramAllTest() {
+ super();
+ classHistogramArgs = "-all=true";
+ }
+
+ /* See ClassHistogramTest for test cases */
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/ClassHistogramTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import java.util.regex.Pattern;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
+/*
+ * @test
+ * @summary Test of diagnostic command GC.class_histogram
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng ClassHistogramTest
+ */
+public class ClassHistogramTest {
+ public static class TestClass {}
+ public static TestClass[] instances = new TestClass[1024];
+ protected String classHistogramArgs = "";
+
+ static {
+ for (int i = 0; i < instances.length; ++i) {
+ instances[i] = new TestClass();
+ }
+ }
+
+ public void run(CommandExecutor executor) {
+ OutputAnalyzer output = executor.execute("GC.class_histogram " + classHistogramArgs);
+
+ /*
+ * example output:
+ * num #instances #bytes class name
+ * ----------------------------------------------
+ * 1: 1647 1133752 [B
+ * 2: 6198 383168 [C
+ * 3: 1464 165744 java.lang.Class
+ * 4: 6151 147624 java.lang.String
+ * 5: 2304 73728 java.util.concurrent.ConcurrentHashMap$Node
+ * 6: 1199 64280 [Ljava.lang.Object;
+ * ...
+ */
+
+ /* Require at least one java.lang.Class */
+ output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.lang.Class\\s*$");
+
+ /* Require at least one java.lang.String */
+ output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.lang.String\\s*$");
+
+ /* Require at least one java.lang.Object */
+ output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.lang.Object\\s*$");
+
+ /* Require at exactly one TestClass[] */
+ output.shouldMatch("^\\s+\\d+:\\s+1\\s+\\d+\\s+" +
+ Pattern.quote(TestClass[].class.getName()) + "\\s*$");
+
+ /* Require at exactly 1024 TestClass */
+ output.shouldMatch("^\\s+\\d+:\\s+1024\\s+\\d+\\s+" +
+ Pattern.quote(TestClass.class.getName()) + "\\s*$");
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/HeapDumpAllTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test of diagnostic command GC.heap_dump -all=true
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @build HeapDumpTest
+ * @run testng HeapDumpAllTest
+ */
+public class HeapDumpAllTest extends HeapDumpTest {
+ public HeapDumpAllTest() {
+ super();
+ heapDumpArgs = "-all=true";
+ }
+
+ /* See HeapDumpTest for test cases */
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/HeapDumpTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import java.io.IOException;
+
+import com.oracle.java.testlibrary.JDKToolFinder;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
+
+/*
+ * @test
+ * @summary Test of diagnostic command GC.heap_dump
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng HeapDumpTest
+ */
+public class HeapDumpTest {
+ protected String heapDumpArgs = "";
+
+ public void run(CommandExecutor executor) {
+ String fileName = "jcmd.gc.heap_dump." + System.currentTimeMillis() + ".hprof";
+ String cmd = "GC.heap_dump " + heapDumpArgs + " " + fileName;
+ executor.execute(cmd);
+
+ verifyHeapDump(fileName);
+ }
+
+ private void verifyHeapDump(String fileName) {
+ String jhat = JDKToolFinder.getJDKTool("jhat");
+ String[] cmd = { jhat, "-parseonly", "true", fileName };
+
+ ProcessBuilder pb = new ProcessBuilder(cmd);
+ pb.redirectErrorStream(true);
+ Process p = null;
+ OutputAnalyzer output = null;
+
+ try {
+ p = pb.start();
+ output = new OutputAnalyzer(p);
+
+ /*
+ * Some hprof dumps of all objects contain constantPoolOop references that cannot be resolved, so we ignore
+ * failures about resolving constantPoolOop fields using a negative lookahead
+ */
+ output.shouldNotMatch(".*WARNING(?!.*Failed to resolve object.*constantPoolOop.*).*");
+ } catch (IOException e) {
+ Assert.fail("Test error: Caught exception while reading stdout/err of jhat", e);
+ } finally {
+ if (p != null) {
+ p.destroy();
+ }
+ }
+
+ if (output.getExitValue() != 0) {
+ Assert.fail("Test error: jhat exit code was nonzero");
+ }
+ }
+
+ /* GC.heap_dump is not available over JMX, running jcmd pid executor instead */
+ @Test
+ public void pid() {
+ run(new PidJcmdExecutor());
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/RunFinalizationTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
+/*
+ * @test
+ * @summary Test of diagnostic command GC.run_finalization
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng RunFinalizationTest
+ */
+public class RunFinalizationTest {
+ static ReentrantLock lock = new ReentrantLock();
+ static Condition cond = lock.newCondition();
+ static volatile boolean wasFinalized = false;
+ static volatile boolean wasInitialized = false;
+
+ class MyObject {
+ public MyObject() {
+ /* Make sure object allocation/deallocation is not optimized out */
+ wasInitialized = true;
+ }
+
+ protected void finalize() {
+ lock.lock();
+ wasFinalized = true;
+ cond.signalAll();
+ lock.unlock();
+ }
+ }
+
+ public static MyObject o;
+
+ public void run(CommandExecutor executor) {
+ lock.lock();
+ o = new MyObject();
+ o = null;
+ System.gc();
+ executor.execute("GC.run_finalization");
+
+ int waited = 0;
+ int waitTime = 15;
+
+ try {
+ System.out.println("Waiting for signal from finalizer");
+
+ while (!cond.await(waitTime, TimeUnit.SECONDS)) {
+ waited += waitTime;
+ System.out.println(String.format("Waited %d seconds", waited));
+ }
+
+ System.out.println("Received signal");
+ } catch (InterruptedException e) {
+ Assert.fail("Test error: Interrupted while waiting for signal from finalizer", e);
+ } finally {
+ lock.unlock();
+ }
+
+ if (!wasFinalized) {
+ Assert.fail("Test failure: Object was not finalized");
+ }
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/RunGCTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
+/*
+ * @test
+ * @summary Test of diagnostic command GC.run
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng/othervm -XX:+PrintGCDetails -Xloggc:RunGC.gclog RunGCTest
+ */
+public class RunGCTest {
+ public void run(CommandExecutor executor) {
+ executor.execute("GC.run");
+
+ Path gcLogPath = Paths.get("RunGC.gclog").toAbsolutePath();
+ String gcLog = null;
+
+ try {
+ gcLog = new String(Files.readAllBytes(gcLogPath));
+ } catch (IOException e) {
+ Assert.fail("Test error: Could not read GC log file: " + gcLogPath, e);
+ }
+
+ OutputAnalyzer output = new OutputAnalyzer(gcLog, "");
+ output.shouldMatch(".*\\[Full GC \\(System(\\.gc\\(\\))?.*");
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/thread/PrintConcurrentLocksTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test of diagnostic command Thread.print -l=true
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @build PrintTest
+ * @run testng PrintConcurrentLocksTest
+ */
+public class PrintConcurrentLocksTest extends PrintTest {
+ public PrintConcurrentLocksTest() {
+ jucLocks = true;
+ }
+
+ /* See PrintTest for test cases */
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/thread/PrintTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.regex.Pattern;
+
+/*
+ * @test
+ * @summary Test of diagnostic command Thread.print
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng PrintTest
+ */
+public class PrintTest {
+ protected boolean jucLocks = false;
+
+ CyclicBarrier readyBarrier = new CyclicBarrier(3);
+ CyclicBarrier doneBarrier = new CyclicBarrier(3);
+
+ private void waitForBarrier(CyclicBarrier b) {
+ try {
+ b.await();
+ } catch (InterruptedException | BrokenBarrierException e) {
+ Assert.fail("Test error: Caught unexpected exception:", e);
+ }
+ }
+
+ class MonitorThread extends Thread {
+ Object lock = new Object();
+
+ public void run() {
+ /* Hold lock on "lock" to show up in thread dump */
+ synchronized (lock) {
+ /* Signal that we're ready for thread dump */
+ waitForBarrier(readyBarrier);
+
+ /* Released when the thread dump has been taken */
+ waitForBarrier(doneBarrier);
+ }
+ }
+ }
+
+ class LockThread extends Thread {
+ ReentrantLock lock = new ReentrantLock();
+
+ public void run() {
+ /* Hold lock "lock" to show up in thread dump */
+ lock.lock();
+
+ /* Signal that we're ready for thread dump */
+ waitForBarrier(readyBarrier);
+
+ /* Released when the thread dump has been taken */
+ waitForBarrier(doneBarrier);
+
+ lock.unlock();
+ }
+ }
+
+ public void run(CommandExecutor executor) {
+ MonitorThread mThread = new MonitorThread();
+ mThread.start();
+ LockThread lThread = new LockThread();
+ lThread.start();
+
+ /* Wait for threads to get ready */
+ waitForBarrier(readyBarrier);
+
+ /* Execute */
+ OutputAnalyzer output = executor.execute("Thread.print" + (jucLocks ? " -l=true" : ""));
+
+ /* Signal that we've got the thread dump */
+ waitForBarrier(doneBarrier);
+
+ /*
+ * Example output (trimmed) with arrows indicating the rows we are looking for:
+ *
+ * ...
+ * "Thread-2" #24 prio=5 os_prio=0 tid=0x00007f913411f800 nid=0x4fc9 waiting on condition [0x00007f91fbffe000]
+ * java.lang.Thread.State: WAITING (parking)
+ * at sun.misc.Unsafe.park(Native Method)
+ * - parking to wait for <0x000000071a0868a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
+ * at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
+ * at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
+ * at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:234)
+ * at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362)
+ * at Print.waitForBarrier(Print.java:26)
+ * at Print.access$000(Print.java:18)
+ * at Print$LockThread.run(Print.java:58)
+ *
+ * --> Locked ownable synchronizers:
+ * --> - <0x000000071a294930> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
+ *
+ * "Thread-1" #23 prio=5 os_prio=0 tid=0x00007f913411e800 nid=0x4fc8 waiting on condition [0x00007f9200113000]
+ * java.lang.Thread.State: WAITING (parking)
+ * at sun.misc.Unsafe.park(Native Method)
+ * - parking to wait for <0x000000071a0868a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
+ * at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
+ * at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
+ * at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:234)
+ * at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362)
+ * at Print.waitForBarrier(Print.java:26)
+ * at Print.access$000(Print.java:18)
+ * at Print$MonitorThread.run(Print.java:42)
+ * --> - locked <0x000000071a294390> (a java.lang.Object)
+ *
+ * Locked ownable synchronizers:
+ * - None
+ *
+ * "MainThread" #22 prio=5 os_prio=0 tid=0x00007f923015b000 nid=0x4fc7 in Object.wait() [0x00007f9200840000]
+ * java.lang.Thread.State: WAITING (on object monitor)
+ * at java.lang.Object.wait(Native Method)
+ * - waiting on <0x000000071a70ad98> (a java.lang.UNIXProcess)
+ * at java.lang.Object.wait(Object.java:502)
+ * at java.lang.UNIXProcess.waitFor(UNIXProcess.java:397)
+ * - locked <0x000000071a70ad98> (a java.lang.UNIXProcess)
+ * at com.oracle.java.testlibrary.dcmd.JcmdExecutor.executeImpl(JcmdExecutor.java:32)
+ * at com.oracle.java.testlibrary.dcmd.CommandExecutor.execute(CommandExecutor.java:24)
+ * --> at Print.run(Print.java:74)
+ * at Print.file(Print.java:112)
+ * ...
+
+ */
+ output.shouldMatch(".*at " + Pattern.quote(PrintTest.class.getName()) + "\\.run.*");
+ output.shouldMatch(".*- locked <0x\\p{XDigit}+> \\(a " + Pattern.quote(mThread.lock.getClass().getName()) + "\\).*");
+
+ String jucLockPattern1 = ".*Locked ownable synchronizers:.*";
+ String jucLockPattern2 = ".*- <0x\\p{XDigit}+> \\(a " + Pattern.quote(lThread.lock.getClass().getName()) + ".*";
+
+ if (jucLocks) {
+ output.shouldMatch(jucLockPattern1);
+ output.shouldMatch(jucLockPattern2);
+ } else {
+ output.shouldNotMatch(jucLockPattern1);
+ output.shouldNotMatch(jucLockPattern2);
+ }
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/ClassLoaderStatsTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,170 @@
+/*
+ * 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
+ * @summary Test of diagnostic command VM.classloader_stats
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng ClassLoaderStatsTest
+ */
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.Iterator;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ClassLoaderStatsTest {
+
+ // ClassLoader Parent CLD* Classes ChunkSz BlockSz Type
+ // 0x00000007c0215928 0x0000000000000000 0x0000000000000000 0 0 0 org.eclipse.osgi.baseadaptor.BaseAdaptor$1
+ // 0x00000007c0009868 0x0000000000000000 0x00007fc52aebcc80 1 6144 3768 sun.reflect.DelegatingClassLoader
+ // 0x00000007c0009868 0x0000000000000000 0x00007fc52b8916d0 1 6144 3688 sun.reflect.DelegatingClassLoader
+ // 0x00000007c0009868 0x00000007c0038ba8 0x00007fc52afb8760 1 6144 3688 sun.reflect.DelegatingClassLoader
+ // 0x00000007c0009868 0x0000000000000000 0x00007fc52afbb1a0 1 6144 3688 sun.reflect.DelegatingClassLoader
+ // 0x0000000000000000 0x0000000000000000 0x00007fc523416070 5019 30060544 29956216 <boot classloader>
+ // 455 1210368 672848 + unsafe anonymous classes
+ // 0x00000007c016b5c8 0x00000007c0038ba8 0x00007fc52a995000 5 8192 5864 org.netbeans.StandardModule$OneModuleClassLoader
+ // 0x00000007c0009868 0x00000007c016b5c8 0x00007fc52ac13640 1 6144 3896 sun.reflect.DelegatingClassLoader
+ // ...
+
+ static Pattern clLine = Pattern.compile("0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*(.*)");
+ static Pattern anonLine = Pattern.compile("\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*.*");
+
+ public static DummyClassLoader dummyloader;
+
+ public void run(CommandExecutor executor) throws ClassNotFoundException {
+
+ // create a classloader and load our special class
+ dummyloader = new DummyClassLoader();
+ Class<?> c = Class.forName("TestClass", true, dummyloader);
+ if (c.getClassLoader() != dummyloader) {
+ Assert.fail("TestClass defined by wrong classloader: " + c.getClassLoader());
+ }
+
+ OutputAnalyzer output = executor.execute("VM.classloader_stats");
+ Iterator<String> lines = output.asLines().iterator();
+ while (lines.hasNext()) {
+ String line = lines.next();
+ Matcher m = clLine.matcher(line);
+ if (m.matches()) {
+ // verify that DummyClassLoader has loaded 1 class and 1 anonymous class
+ if (m.group(4).equals("ClassLoaderStatsTest$DummyClassLoader")) {
+ System.out.println("line: " + line);
+ if (!m.group(1).equals("1")) {
+ Assert.fail("Should have loaded 1 class: " + line);
+ }
+ checkPositiveInt(m.group(2));
+ checkPositiveInt(m.group(3));
+
+ String next = lines.next();
+ System.out.println("next: " + next);
+ Matcher m1 = anonLine.matcher(next);
+ m1.matches();
+ if (!m1.group(1).equals("1")) {
+ Assert.fail("Should have loaded 1 anonymous class, but found : " + m1.group(1));
+ }
+ checkPositiveInt(m1.group(2));
+ checkPositiveInt(m1.group(3));
+ }
+ }
+ }
+ }
+
+ private static void checkPositiveInt(String s) {
+ if (Integer.parseInt(s) <= 0) {
+ Assert.fail("Value should have been > 0: " + s);
+ }
+ }
+
+ public static class DummyClassLoader extends ClassLoader {
+
+ public static final String CLASS_NAME = "TestClass";
+
+ static ByteBuffer readClassFile(String name)
+ {
+ File f = new File(System.getProperty("test.classes", "."),
+ name);
+ try (FileInputStream fin = new FileInputStream(f);
+ FileChannel fc = fin.getChannel())
+ {
+ return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+ } catch (IOException e) {
+ Assert.fail("Can't open file: " + name, e);
+ }
+
+ /* Will not reach here as Assert.fail() throws exception */
+ return null;
+ }
+
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException
+ {
+ Class<?> c;
+ if (!"TestClass".equals(name)) {
+ c = super.loadClass(name, resolve);
+ } else {
+ // should not delegate to the system class loader
+ c = findClass(name);
+ if (resolve) {
+ resolveClass(c);
+ }
+ }
+ return c;
+ }
+
+ protected Class<?> findClass(String name)
+ throws ClassNotFoundException
+ {
+ if (!"TestClass".equals(name)) {
+ throw new ClassNotFoundException("Unexpected class: " + name);
+ }
+ return defineClass(name, readClassFile(name + ".class"), null);
+ }
+ } /* DummyClassLoader */
+
+ @Test
+ public void jmx() throws ClassNotFoundException {
+ run(new JMXExecutor());
+ }
+}
+
+class TestClass {
+ static {
+ // force creation of anonymous class (for the lambdaform)
+ Runnable r = () -> System.out.println("Hello");
+ r.run();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/CommandLineTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import org.testng.annotations.Test;
+
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
+/*
+ * @test
+ * @summary Test of diagnostic command VM.command_line
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis CommandLineTest
+ */
+public class CommandLineTest {
+ public void run(CommandExecutor executor) {
+ OutputAnalyzer output = executor.execute("VM.command_line");
+ output.shouldContain("-XX:+IgnoreUnrecognizedVMOptions");
+ output.shouldContain("-XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis");
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/DynLibsTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,72 @@
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.Platform;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test of VM.dynlib diagnostic command via MBean
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng DynLibsTest
+ */
+
+public class DynLibsTest {
+
+ public void run(CommandExecutor executor) {
+ OutputAnalyzer output = executor.execute("VM.dynlibs");
+
+ String osDependentBaseString = null;
+ if (Platform.isAix()) {
+ osDependentBaseString = "lib%s.so";
+ } else if (Platform.isLinux()) {
+ osDependentBaseString = "lib%s.so";
+ } else if (Platform.isOSX()) {
+ osDependentBaseString = "lib%s.dylib";
+ } else if (Platform.isSolaris()) {
+ osDependentBaseString = "lib%s.so";
+ } else if (Platform.isWindows()) {
+ osDependentBaseString = "%s.dll";
+ }
+
+ if (osDependentBaseString == null) {
+ Assert.fail("Unsupported OS");
+ }
+
+ output.shouldContain(String.format(osDependentBaseString, "jvm"));
+ output.shouldContain(String.format(osDependentBaseString, "java"));
+ output.shouldContain(String.format(osDependentBaseString, "management"));
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/FlagsTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @summary Test of diagnostic command VM.flags
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng/othervm -Xmx129m -XX:+PrintGC -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis_Right -XX:-TieredCompilation FlagsTest
+ */
+public class FlagsTest {
+ public void run(CommandExecutor executor) {
+ OutputAnalyzer output = executor.execute("VM.flags");
+
+ /* The following are interpreted by the JVM as actual "flags" */
+ output.shouldContain("-XX:+PrintGC");
+ output.shouldContain("-XX:+UnlockDiagnosticVMOptions");
+ output.shouldContain("-XX:+IgnoreUnrecognizedVMOptions");
+ output.shouldContain("-XX:-TieredCompilation");
+
+ /* The following are not */
+ output.shouldNotContain("-Xmx129m");
+ output.shouldNotContain("-XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis_Right");
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/SystemPropertiesTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
+/*
+ * @test
+ * @summary Test of diagnostic command VM.system_properties
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng SystemPropertiesTest
+ */
+public class SystemPropertiesTest {
+ private final static String PROPERTY_NAME = "SystemPropertiesTestPropertyName";
+ private final static String PROPERTY_VALUE = "SystemPropertiesTestPropertyValue";
+
+ public void run(CommandExecutor executor) {
+ System.setProperty(PROPERTY_NAME, PROPERTY_VALUE);
+
+ OutputAnalyzer output = executor.execute("VM.system_properties");
+ output.shouldContain(PROPERTY_NAME + "=" + PROPERTY_VALUE);
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/UptimeTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.dcmd.CommandExecutor;
+import com.oracle.java.testlibrary.dcmd.JMXExecutor;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+
+/*
+ * @test
+ * @summary Test of diagnostic command VM.uptime
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng UptimeTest
+ */
+public class UptimeTest {
+ public void run(CommandExecutor executor) {
+ double someUptime = 1.0;
+ long startTime = System.currentTimeMillis();
+ try {
+ synchronized (this) {
+ /* Loop to guard against spurious wake ups */
+ while (System.currentTimeMillis() < (startTime + someUptime * 1000)) {
+ wait((int) someUptime * 1000);
+ }
+ }
+ } catch (InterruptedException e) {
+ Assert.fail("Test error: Exception caught when sleeping:", e);
+ }
+
+ OutputAnalyzer output = executor.execute("VM.uptime");
+
+ output.stderrShouldBeEmpty();
+
+ /*
+ * Output should be:
+ * [pid]:
+ * xx.yyy s
+ *
+ * If there is only one line in output there is no "[pid]:" printout;
+ * skip first line, split on whitespace and grab first half
+ */
+ int index = output.asLines().size() == 1 ? 0 : 1;
+ String uptimeString = output.asLines().get(index).split("\\s+")[0];
+
+ try {
+ double uptime = NumberFormat.getNumberInstance().parse(uptimeString).doubleValue();
+ if (uptime < someUptime) {
+ Assert.fail(String.format(
+ "Test failure: Uptime was less than intended sleep time: %.3f s < %.3f s",
+ uptime, someUptime));
+ }
+ } catch (ParseException e) {
+ Assert.fail("Test failure: Could not parse uptime string: " +
+ uptimeString, e);
+ }
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Wed Jul 05 20:19:27 2017 +0200
@@ -24,6 +24,8 @@
package com.oracle.java.testlibrary;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -69,6 +71,58 @@
}
/**
+ * Verify that the stdout contents of output buffer is empty
+ *
+ * @throws RuntimeException
+ * If stdout was not empty
+ */
+ public void stdoutShouldBeEmpty() {
+ if (!getStdout().isEmpty()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("stdout was not empty");
+ }
+ }
+
+ /**
+ * Verify that the stderr contents of output buffer is empty
+ *
+ * @throws RuntimeException
+ * If stderr was not empty
+ */
+ public void stderrShouldBeEmpty() {
+ if (!getStderr().isEmpty()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("stderr was not empty");
+ }
+ }
+
+ /**
+ * Verify that the stdout contents of output buffer is not empty
+ *
+ * @throws RuntimeException
+ * If stdout was empty
+ */
+ public void stdoutShouldNotBeEmpty() {
+ if (getStdout().isEmpty()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("stdout was empty");
+ }
+ }
+
+ /**
+ * Verify that the stderr contents of output buffer is not empty
+ *
+ * @throws RuntimeException
+ * If stderr was empty
+ */
+ public void stderrShouldNotBeEmpty() {
+ if (getStderr().isEmpty()) {
+ reportDiagnosticSummary();
+ throw new RuntimeException("stderr was empty");
+ }
+ }
+
+ /**
* Verify that the stdout and stderr contents of output buffer contains the string
*
* @param expectedString String that buffer should contain
@@ -365,4 +419,18 @@
public int getExitValue() {
return exitValue;
}
+
+ /**
+ * Get the contents of the output buffer (stdout and stderr) as list of strings.
+ * Output will be split by newlines.
+ *
+ * @return Contents of the output buffer as list of strings
+ */
+ public List<String> asLines() {
+ return asLines(getOutput());
+ }
+
+ private List<String> asLines(String buffer) {
+ return Arrays.asList(buffer.split("(\\r\\n|\\n|\\r)"));
+ }
}
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Thu Feb 12 16:23:24 2015 -0800
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Wed Jul 05 20:19:27 2017 +0200
@@ -184,23 +184,36 @@
return executeProcess(pb);
}
- /**
- * Executes a process, waits for it to finish and returns the process output.
- * @param pb The ProcessBuilder to execute.
- * @return The output from the process.
- */
- public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Throwable {
- OutputAnalyzer output = null;
- try {
- output = new OutputAnalyzer(pb.start());
- return output;
- } catch (Throwable t) {
- System.out.println("executeProcess() failed: " + t);
- throw t;
- } finally {
- System.out.println(getProcessLog(pb, output));
+ /**
+ * Executes a process, waits for it to finish and returns the process output.
+ * The process will have exited before this method returns.
+ * @param pb The ProcessBuilder to execute.
+ * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
+ */
+ public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Exception {
+ OutputAnalyzer output = null;
+ Process p = null;
+ boolean failed = false;
+ try {
+ p = pb.start();
+ output = new OutputAnalyzer(p);
+ p.waitFor();
+
+ return output;
+ } catch (Throwable t) {
+ if (p != null) {
+ p.destroyForcibly().waitFor();
+ }
+
+ failed = true;
+ System.out.println("executeProcess() failed: " + t);
+ throw t;
+ } finally {
+ if (failed) {
+ System.err.println(getProcessLog(pb, output));
+ }
+ }
}
- }
/**
* Executes a process, waits for it to finish and returns the process output.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/CommandExecutor.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary.dcmd;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+/**
+ * Abstract base class for Diagnostic Command executors
+ */
+public abstract class CommandExecutor {
+
+ /**
+ * Execute a diagnostic command
+ *
+ * @param cmd The diagnostic command to execute
+ * @return an {@link jdk.testlibrary.OutputAnalyzer} encapsulating the output of the command
+ * @throws CommandExecutorException if there is an exception on the "calling side" while trying to execute the
+ * Diagnostic Command. Exceptions thrown on the remote side are available as textual representations in
+ * stderr, regardless of the specific executor used.
+ */
+ public final OutputAnalyzer execute(String cmd) throws CommandExecutorException {
+ System.out.printf("Running DCMD '%s' through '%s'%n", cmd, this.getClass().getSimpleName());
+ OutputAnalyzer oa = executeImpl(cmd);
+
+ System.out.println("---------------- stdout ----------------");
+ System.out.println(oa.getStdout());
+ System.out.println("---------------- stderr ----------------");
+ System.out.println(oa.getStderr());
+ System.out.println("----------------------------------------");
+ System.out.println();
+
+ return oa;
+ }
+
+ protected abstract OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/CommandExecutorException.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary.dcmd;
+
+/**
+ * CommandExecutorException encapsulates exceptions thrown (on the "calling side") from the execution of Diagnostic
+ * Commands
+ */
+public class CommandExecutorException extends RuntimeException {
+ private static final long serialVersionUID = -7039597746579144280L;
+
+ public CommandExecutorException(String message, Throwable e) {
+ super(message, e);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/FileJcmdExecutor.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary.dcmd;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Executes Diagnostic Commands on the target VM (specified by pid) using the jcmd tool and its ability to read
+ * Diagnostic Commands from a file.
+ */
+public class FileJcmdExecutor extends PidJcmdExecutor {
+
+ /**
+ * Instantiates a new FileJcmdExecutor targeting the current VM
+ */
+ public FileJcmdExecutor() {
+ super();
+ }
+
+ /**
+ * Instantiates a new FileJcmdExecutor targeting the VM indicated by the given pid
+ *
+ * @param target Pid of the target VM
+ */
+ public FileJcmdExecutor(String target) {
+ super(target);
+ }
+
+ protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
+ File cmdFile = createTempFile();
+ writeCommandToTemporaryFile(cmd, cmdFile);
+
+ return Arrays.asList(jcmdBinary, Integer.toString(pid),
+ "-f", cmdFile.getAbsolutePath());
+ }
+
+ private void writeCommandToTemporaryFile(String cmd, File cmdFile) {
+ try (PrintWriter pw = new PrintWriter(cmdFile)) {
+ pw.println(cmd);
+ } catch (IOException e) {
+ String message = "Could not write to file: " + cmdFile.getAbsolutePath();
+ throw new CommandExecutorException(message, e);
+ }
+ }
+
+ private File createTempFile() {
+ try {
+ File cmdFile = File.createTempFile("input", "jcmd");
+ cmdFile.deleteOnExit();
+ return cmdFile;
+ } catch (IOException e) {
+ throw new CommandExecutorException("Could not create temporary file", e);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/JMXExecutor.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary.dcmd;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+
+import javax.management.*;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import java.lang.management.ManagementFactory;
+
+import java.util.HashMap;
+
+/**
+ * Executes Diagnostic Commands on the target VM (specified by a host/port combination or a full JMX Service URL) using
+ * the JMX interface. If the target is not the current VM, the JMX Remote interface must be enabled beforehand.
+ */
+public class JMXExecutor extends CommandExecutor {
+
+ private final MBeanServerConnection mbs;
+
+ /**
+ * Instantiates a new JMXExecutor targeting the current VM
+ */
+ public JMXExecutor() {
+ super();
+ mbs = ManagementFactory.getPlatformMBeanServer();
+ }
+
+ /**
+ * Instantiates a new JMXExecutor targeting the VM indicated by the given host/port combination or a full JMX
+ * Service URL
+ *
+ * @param target a host/port combination on the format "host:port" or a full JMX Service URL of the target VM
+ */
+ public JMXExecutor(String target) {
+ String urlStr;
+
+ if (target.matches("^\\w[\\w\\-]*(\\.[\\w\\-]+)*:\\d+$")) {
+ /* Matches "hostname:port" */
+ urlStr = String.format("service:jmx:rmi:///jndi/rmi://%s/jmxrmi", target);
+ } else if (target.startsWith("service:")) {
+ urlStr = target;
+ } else {
+ throw new IllegalArgumentException("Could not recognize target string: " + target);
+ }
+
+ try {
+ JMXServiceURL url = new JMXServiceURL(urlStr);
+ JMXConnector c = JMXConnectorFactory.connect(url, new HashMap<>());
+ mbs = c.getMBeanServerConnection();
+ } catch (IOException e) {
+ throw new CommandExecutorException("Could not initiate connection to target: " + target, e);
+ }
+ }
+
+ protected OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException {
+ String stdout = "";
+ String stderr = "";
+
+ String[] cmdParts = cmd.split(" ", 2);
+ String operation = commandToMethodName(cmdParts[0]);
+ Object[] dcmdArgs = produceArguments(cmdParts);
+ String[] signature = {String[].class.getName()};
+
+ ObjectName beanName = getMBeanName();
+
+ try {
+ stdout = (String) mbs.invoke(beanName, operation, dcmdArgs, signature);
+ }
+
+ /* Failures on the "local" side, the one invoking the command. */
+ catch (ReflectionException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof NoSuchMethodException) {
+ /* We want JMXExecutor to match the behavior of the other CommandExecutors */
+ String message = "Unknown diagnostic command: " + operation;
+ stderr = exceptionTraceAsString(new IllegalArgumentException(message, e));
+ } else {
+ rethrowExecutorException(operation, dcmdArgs, e);
+ }
+ }
+
+ /* Failures on the "local" side, the one invoking the command. */
+ catch (InstanceNotFoundException | IOException e) {
+ rethrowExecutorException(operation, dcmdArgs, e);
+ }
+
+ /* Failures on the remote side, the one executing the invoked command. */
+ catch (MBeanException e) {
+ stdout = exceptionTraceAsString(e);
+ }
+
+ return new OutputAnalyzer(stdout, stderr);
+ }
+
+ private void rethrowExecutorException(String operation, Object[] dcmdArgs,
+ Exception e) throws CommandExecutorException {
+ String message = String.format("Could not invoke: %s %s", operation,
+ String.join(" ", (String[]) dcmdArgs[0]));
+ throw new CommandExecutorException(message, e);
+ }
+
+ private ObjectName getMBeanName() throws CommandExecutorException {
+ String MBeanName = "com.sun.management:type=DiagnosticCommand";
+
+ try {
+ return new ObjectName(MBeanName);
+ } catch (MalformedObjectNameException e) {
+ String message = "MBean not found: " + MBeanName;
+ throw new CommandExecutorException(message, e);
+ }
+ }
+
+ private Object[] produceArguments(String[] cmdParts) {
+ Object[] dcmdArgs = {new String[0]}; /* Default: No arguments */
+
+ if (cmdParts.length == 2) {
+ dcmdArgs[0] = cmdParts[1].split(" ");
+ }
+ return dcmdArgs;
+ }
+
+ /**
+ * Convert from diagnostic command to MBean method name
+ *
+ * Examples:
+ * help --> help
+ * VM.version --> vmVersion
+ * VM.command_line --> vmCommandLine
+ */
+ private static String commandToMethodName(String cmd) {
+ String operation = "";
+ boolean up = false; /* First letter is to be lower case */
+
+ /*
+ * If a '.' or '_' is encountered it is not copied,
+ * instead the next character will be converted to upper case
+ */
+ for (char c : cmd.toCharArray()) {
+ if (('.' == c) || ('_' == c)) {
+ up = true;
+ } else if (up) {
+ operation = operation.concat(Character.toString(c).toUpperCase());
+ up = false;
+ } else {
+ operation = operation.concat(Character.toString(c).toLowerCase());
+ }
+ }
+
+ return operation;
+ }
+
+ private static String exceptionTraceAsString(Throwable cause) {
+ StringWriter sw = new StringWriter();
+ cause.printStackTrace(new PrintWriter(sw));
+ return sw.toString();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/JcmdExecutor.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary.dcmd;
+
+import com.oracle.java.testlibrary.JDKToolFinder;
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+import java.util.List;
+
+/**
+ * Base class for Diagnostic Command Executors using the jcmd tool
+ */
+public abstract class JcmdExecutor extends CommandExecutor {
+ protected String jcmdBinary;
+
+ protected abstract List<String> createCommandLine(String cmd) throws CommandExecutorException;
+
+ protected JcmdExecutor() {
+ jcmdBinary = JDKToolFinder.getJDKTool("jcmd");
+ }
+
+ protected OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException {
+ List<String> commandLine = createCommandLine(cmd);
+
+ try {
+ System.out.printf("Executing command '%s'%n", commandLine);
+ OutputAnalyzer output = ProcessTools.executeProcess(new ProcessBuilder(commandLine));
+ System.out.printf("Command returned with exit code %d%n", output.getExitValue());
+
+ return output;
+ } catch (Exception e) {
+ String message = String.format("Caught exception while executing '%s'", commandLine);
+ throw new CommandExecutorException(message, e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/MainClassJcmdExecutor.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary.dcmd;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Executes Diagnostic Commands on the target VM (specified by main class) using the jcmd tool
+ */
+public class MainClassJcmdExecutor extends JcmdExecutor {
+ private final String mainClass;
+
+ /**
+ * Instantiates a new MainClassJcmdExecutor targeting the current VM
+ */
+ public MainClassJcmdExecutor() {
+ super();
+ mainClass = System.getProperty("sun.java.command").split(" ")[0];
+ }
+
+ /**
+ * Instantiates a new MainClassJcmdExecutor targeting the VM indicated by the given main class
+ *
+ * @param target Main class of the target VM
+ */
+ public MainClassJcmdExecutor(String target) {
+ super();
+ mainClass = target;
+ }
+
+ protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
+ return Arrays.asList(jcmdBinary, mainClass, cmd);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/PidJcmdExecutor.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary.dcmd;
+
+import com.oracle.java.testlibrary.ProcessTools;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Executes Diagnostic Commands on the target VM (specified by pid) using the jcmd tool
+ */
+public class PidJcmdExecutor extends JcmdExecutor {
+ protected final int pid;
+
+ /**
+ * Instantiates a new PidJcmdExecutor targeting the current VM
+ */
+ public PidJcmdExecutor() {
+ super();
+ try {
+ pid = ProcessTools.getProcessId();
+ } catch (Exception e) {
+ throw new CommandExecutorException("Could not determine own pid", e);
+ }
+ }
+
+ /**
+ * Instantiates a new PidJcmdExecutor targeting the VM indicated by the given pid
+ *
+ * @param target Pid of the target VM
+ */
+ public PidJcmdExecutor(String target) {
+ super();
+ pid = Integer.valueOf(target);
+ }
+
+ protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
+ return Arrays.asList(jcmdBinary, Integer.toString(pid), cmd);
+ }
+
+}
--- a/jdk/.hgtags Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/.hgtags Wed Jul 05 20:19:27 2017 +0200
@@ -292,3 +292,4 @@
b641c14730ac05d9ec8b4f66e6fca3dc21adb403 jdk9-b47
ebb2eb7f1aec78eb6d8cc4c96f018afa11093cde jdk9-b48
541a8cef4e0d54c3e4b52a98c6af3c31e2096669 jdk9-b49
+f6b8edd397ee463be208fee27517c99101293267 jdk9-b50
--- a/jdk/make/Tools.gmk Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/make/Tools.gmk Wed Jul 05 20:19:27 2017 +0200
@@ -147,6 +147,15 @@
EXCLUDES := jdk/internal/jimage/concurrent, \
BIN := $(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes))
+# Because of the explicit INCLUDES in the compilation setup above, the service provider
+# file will not be copied unless META-INF/services would also be added to the INCLUDES.
+# Adding META-INF/services would include all files in that directory when only the one
+# is needed, which is why this explicit copy is defined instead.
+$(eval $(call SetupCopyFiles,COPY_JIMAGE_SERVICE_PROVIDER, \
+ SRC := $(JDK_TOPDIR)/src/java.base/share/classes, \
+ DEST := $(BUILDTOOLS_OUTPUTDIR)/interim_jimage_classes, \
+ FILES := META-INF/services/java.nio.file.spi.FileSystemProvider))
+
##########################################################################################
# Tools needed on solaris because OBJCOPY is broken.
@@ -173,7 +182,7 @@
PROGRAM := fix_empty_sec_hdr_flags))
endif
-$(BUILD_TOOLS_JDK): $(BUILD_INTERIM_JIMAGE)
+$(BUILD_TOOLS_JDK): $(BUILD_INTERIM_JIMAGE) $(COPY_JIMAGE_SERVICE_PROVIDER)
java-tools: $(BUILD_TOOLS_JDK)
--- a/jdk/make/launcher/Launcher-jdk.runtime.gmk Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/make/launcher/Launcher-jdk.runtime.gmk Wed Jul 05 20:19:27 2017 +0200
@@ -66,19 +66,6 @@
ifeq ($(OPENJDK_TARGET_OS), solaris)
UNPACKEXE_LANG := C++
endif
-UNPACKEXE_DEBUG_SYMBOLS := true
-# On windows, unpack200 is linked completely differently to all other
-# executables, using the compiler with the compiler arguments.
-# It's also linked incrementally, producing a .ilk file that needs to
-# be kept away.
-ifeq ($(OPENJDK_TARGET_OS), windows)
- BUILD_UNPACKEXE_LDEXE := $(CC)
- EXE_OUT_OPTION_save := $(EXE_OUT_OPTION)
- EXE_OUT_OPTION := -Fe
- # With the current way unpack200 is built, debug symbols aren't supported
- # anyway.
- UNPACKEXE_DEBUG_SYMBOLS := false
-endif
# The linker on older SuSE distros (e.g. on SLES 10) complains with:
# "Invalid version tag `SUNWprivate_1.1'. Only anonymous version tag is allowed in executable."
@@ -93,49 +80,36 @@
SRC := $(UNPACKEXE_SRC), \
LANG := $(UNPACKEXE_LANG), \
OPTIMIZATION := LOW, \
- CFLAGS := $(UNPACKEXE_CFLAGS) $(CXXFLAGS_JDKEXE) \
- -DFULL, \
+ CFLAGS := $(UNPACKEXE_CFLAGS) $(CXXFLAGS_JDKEXE) -DFULL, \
CFLAGS_release := -DPRODUCT, \
CFLAGS_linux := -fPIC, \
CFLAGS_solaris := -KPIC, \
CFLAGS_macosx := -fPIC, \
MAPFILE := $(UNPACK_MAPFILE),\
- LDFLAGS := $(UNPACKEXE_ZIPOBJS), \
- LDFLAGS_windows := $(CXXFLAGS_JDKEXE), \
- LDFLAGS_unix := $(LDFLAGS_JDKEXE) $(LDFLAGS_CXX_JDK) \
+ LDFLAGS := $(UNPACKEXE_ZIPOBJS) \
+ $(LDFLAGS_JDKEXE) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_NAME,$(LIBRARY_PREFIX)unpack$(SHARED_LIBRARY_SUFFIX)) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_linux := -lc, \
LDFLAGS_solaris := $(UNPACKEXE_LDFLAGS_solaris) -lc, \
LDFLAGS_SUFFIX := $(LIBCXX), \
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/unpackexe$(OUTPUT_SUBDIR), \
- OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/unpackexe$(OUTPUT_SUBDIR), \
+ OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_cmds/$(MODULE), \
PROGRAM := unpack200, \
VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
RC_FLAGS := $(RC_FLAGS) \
-D "JDK_FNAME=unpack200.exe" \
-D "JDK_INTERNAL_NAME=unpack200" \
-D "JDK_FTYPE=0x1L", \
- DEBUG_SYMBOLS := $(UNPACKEXE_DEBUG_SYMBOLS), \
+ DEBUG_SYMBOLS := true, \
MANIFEST := $(JDK_TOPDIR)/src/jdk.runtime/windows/native/unpack200/unpack200_proto.exe.manifest))
-ifeq ($(OPENJDK_TARGET_OS), windows)
- EXE_OUT_OPTION := $(EXE_OUT_OPTION_save)
-endif
-
ifneq ($(USE_EXTERNAL_LIBZ), true)
$(BUILD_UNPACKEXE): $(UNPACKEXE_ZIPOBJS)
endif
-# Build into object dir and copy executable afterwards to avoid .ilk file in
-# image. The real fix would be clean up linking of unpack200 using
-# -link -incremental:no
-# like all other launchers.
-$(SUPPORT_OUTPUTDIR)/modules_cmds/$(MODULE)/unpack200$(EXE_SUFFIX): $(BUILD_UNPACKEXE)
- $(call install-file)
-
-TARGETS += $(SUPPORT_OUTPUTDIR)/modules_cmds/$(MODULE)/unpack200$(EXE_SUFFIX)
+TARGETS += $(BUILD_UNPACKEXE)
################################################################################
--- a/jdk/make/src/classes/build/tools/module/boot.modules Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/make/src/classes/build/tools/module/boot.modules Wed Jul 05 20:19:27 2017 +0200
@@ -1,7 +1,5 @@
java.base
java.desktop
-java.activation
-java.annotations.common
java.compiler
java.corba
java.instrument
@@ -18,9 +16,7 @@
java.sql.rowset
java.transaction
java.xml
-java.xml.bind
java.xml.crypto
-java.xml.ws
jdk.charsets
jdk.deploy
jdk.deploy.osx
--- a/jdk/make/src/classes/build/tools/module/ext.modules Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/make/src/classes/build/tools/module/ext.modules Wed Jul 05 20:19:27 2017 +0200
@@ -1,3 +1,7 @@
+java.activation
+java.annotations.common
+java.xml.bind
+java.xml.ws
jdk.crypto.ec
jdk.crypto.mscapi
jdk.crypto.pkcs11
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,9 +29,7 @@
package com.sun.crypto.provider;
-import java.util.Arrays;
-import java.security.*;
-import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE;
+import java.security.ProviderException;
/**
* This class represents the GHASH function defined in NIST 800-38D
@@ -44,62 +43,90 @@
*/
final class GHASH {
- private static final byte P128 = (byte) 0xe1; //reduction polynomial
-
- private static boolean getBit(byte[] b, int pos) {
- int p = pos / 8;
- pos %= 8;
- int i = (b[p] >>> (7 - pos)) & 1;
- return i != 0;
+ private static long getLong(byte[] buffer, int offset) {
+ long result = 0;
+ int end = offset + 8;
+ for (int i = offset; i < end; ++i) {
+ result = (result << 8) + (buffer[i] & 0xFF);
+ }
+ return result;
}
- private static void shift(byte[] b) {
- byte temp, temp2;
- temp2 = 0;
- for (int i = 0; i < b.length; i++) {
- temp = (byte) ((b[i] & 0x01) << 7);
- b[i] = (byte) ((b[i] & 0xff) >>> 1);
- b[i] = (byte) (b[i] | temp2);
- temp2 = temp;
+ private static void putLong(byte[] buffer, int offset, long value) {
+ int end = offset + 8;
+ for (int i = end - 1; i >= offset; --i) {
+ buffer[i] = (byte) value;
+ value >>= 8;
}
}
- // Given block X and Y, returns the muliplication of X * Y
- private static byte[] blockMult(byte[] x, byte[] y) {
- if (x.length != AES_BLOCK_SIZE || y.length != AES_BLOCK_SIZE) {
- throw new RuntimeException("illegal input sizes");
- }
- byte[] z = new byte[AES_BLOCK_SIZE];
- byte[] v = y.clone();
- // calculate Z1-Z127 and V1-V127
- for (int i = 0; i < 127; i++) {
+ private static final int AES_BLOCK_SIZE = 16;
+
+ // Multiplies state0, state1 by V0, V1.
+ private void blockMult(long V0, long V1) {
+ long Z0 = 0;
+ long Z1 = 0;
+ long X;
+
+ // Separate loops for processing state0 and state1.
+ X = state0;
+ for (int i = 0; i < 64; i++) {
// Zi+1 = Zi if bit i of x is 0
- if (getBit(x, i)) {
- for (int n = 0; n < z.length; n++) {
- z[n] ^= v[n];
- }
- }
- boolean lastBitOfV = getBit(v, 127);
- shift(v);
- if (lastBitOfV) v[0] ^= P128;
+ long mask = X >> 63;
+ Z0 ^= V0 & mask;
+ Z1 ^= V1 & mask;
+
+ // Save mask for conditional reduction below.
+ mask = (V1 << 63) >> 63;
+
+ // V = rightshift(V)
+ long carry = V0 & 1;
+ V0 = V0 >>> 1;
+ V1 = (V1 >>> 1) | (carry << 63);
+
+ // Conditional reduction modulo P128.
+ V0 ^= 0xe100000000000000L & mask;
+ X <<= 1;
}
+
+ X = state1;
+ for (int i = 64; i < 127; i++) {
+ // Zi+1 = Zi if bit i of x is 0
+ long mask = X >> 63;
+ Z0 ^= V0 & mask;
+ Z1 ^= V1 & mask;
+
+ // Save mask for conditional reduction below.
+ mask = (V1 << 63) >> 63;
+
+ // V = rightshift(V)
+ long carry = V0 & 1;
+ V0 = V0 >>> 1;
+ V1 = (V1 >>> 1) | (carry << 63);
+
+ // Conditional reduction.
+ V0 ^= 0xe100000000000000L & mask;
+ X <<= 1;
+ }
+
// calculate Z128
- if (getBit(x, 127)) {
- for (int n = 0; n < z.length; n++) {
- z[n] ^= v[n];
- }
- }
- return z;
+ long mask = X >> 63;
+ Z0 ^= V0 & mask;
+ Z1 ^= V1 & mask;
+
+ // Save result.
+ state0 = Z0;
+ state1 = Z1;
}
// hash subkey H; should not change after the object has been constructed
- private final byte[] subkeyH;
+ private final long subkeyH0, subkeyH1;
// buffer for storing hash
- private byte[] state;
+ private long state0, state1;
// variables for save/restore calls
- private byte[] stateSave = null;
+ private long stateSave0, stateSave1;
/**
* Initializes the cipher in the specified mode with the given key
@@ -114,8 +141,8 @@
if ((subkeyH == null) || subkeyH.length != AES_BLOCK_SIZE) {
throw new ProviderException("Internal error");
}
- this.subkeyH = subkeyH;
- this.state = new byte[AES_BLOCK_SIZE];
+ this.subkeyH0 = getLong(subkeyH, 0);
+ this.subkeyH1 = getLong(subkeyH, 8);
}
/**
@@ -124,31 +151,33 @@
* this object for different data w/ the same H.
*/
void reset() {
- Arrays.fill(state, (byte) 0);
+ state0 = 0;
+ state1 = 0;
}
/**
* Save the current snapshot of this GHASH object.
*/
void save() {
- stateSave = state.clone();
+ stateSave0 = state0;
+ stateSave1 = state1;
}
/**
* Restores this object using the saved snapshot.
*/
void restore() {
- state = stateSave;
+ state0 = stateSave0;
+ state1 = stateSave1;
}
private void processBlock(byte[] data, int ofs) {
if (data.length - ofs < AES_BLOCK_SIZE) {
throw new RuntimeException("need complete block");
}
- for (int n = 0; n < state.length; n++) {
- state[n] ^= data[ofs + n];
- }
- state = blockMult(state, subkeyH);
+ state0 ^= getLong(data, ofs);
+ state1 ^= getLong(data, ofs + 8);
+ blockMult(subkeyH0, subkeyH1);
}
void update(byte[] in) {
@@ -169,10 +198,10 @@
}
byte[] digest() {
- try {
- return state.clone();
- } finally {
- reset();
- }
+ byte[] result = new byte[AES_BLOCK_SIZE];
+ putLong(result, 0, state0);
+ putLong(result, 8, state1);
+ reset();
+ return result;
}
}
--- a/jdk/src/java.base/share/classes/java/io/PushbackInputStream.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/io/PushbackInputStream.java Wed Jul 05 20:19:27 2017 +0200
@@ -28,9 +28,10 @@
/**
* A <code>PushbackInputStream</code> adds
* functionality to another input stream, namely
- * the ability to "push back" or "unread"
- * one byte. This is useful in situations where
- * it is convenient for a fragment of code
+ * the ability to "push back" or "unread" bytes,
+ * by storing pushed-back bytes in an internal buffer.
+ * This is useful in situations where
+ * it is convenient for a fragment of code
* to read an indefinite number of data bytes
* that are delimited by a particular byte
* value; after reading the terminating byte,
@@ -77,11 +78,9 @@
/**
* Creates a <code>PushbackInputStream</code>
* with a pushback buffer of the specified <code>size</code>,
- * and saves its argument, the input stream
+ * and saves its argument, the input stream
* <code>in</code>, for later use. Initially,
- * there is no pushed-back byte (the field
- * <code>pushBack</code> is initialized to
- * <code>-1</code>).
+ * the pushback buffer is empty.
*
* @param in the input stream from which bytes will be read.
* @param size the size of the pushback buffer.
@@ -99,11 +98,9 @@
/**
* Creates a <code>PushbackInputStream</code>
- * and saves its argument, the input stream
+ * with a 1-byte pushback buffer, and saves its argument, the input stream
* <code>in</code>, for later use. Initially,
- * there is no pushed-back byte (the field
- * <code>pushBack</code> is initialized to
- * <code>-1</code>).
+ * the pushback buffer is empty.
*
* @param in the input stream from which bytes will be read.
*/
--- a/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessBuilder.java Wed Jul 05 20:19:27 2017 +0200
@@ -951,9 +951,6 @@
* {@code command} array as its argument. This may result in
* a {@link SecurityException} being thrown.
*
- * <p>If the operating system does not support the creation of
- * processes, an {@link UnsupportedOperationException} will be thrown.
- *
* <p>Starting an operating system process is highly system-dependent.
* Among the many things that can go wrong are:
* <ul>
@@ -967,6 +964,9 @@
* of the exception is system-dependent, but it will always be a
* subclass of {@link IOException}.
*
+ * <p>If the operating system does not support the creation of
+ * processes, an {@link UnsupportedOperationException} will be thrown.
+ *
* <p>Subsequent modifications to this process builder will not
* affect the returned {@link Process}.
*
--- a/jdk/src/java.base/share/classes/java/lang/Runtime.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Runtime.java Wed Jul 05 20:19:27 2017 +0200
@@ -564,9 +564,6 @@
* <code>cmdarray</code> as its argument. This may result in a
* {@link SecurityException} being thrown.
*
- * <p>If the operating system does not support the creation of
- * processes, an {@link UnsupportedOperationException} will be thrown.
- *
* <p>Starting an operating system process is highly system-dependent.
* Among the many things that can go wrong are:
* <ul>
@@ -579,6 +576,9 @@
* of the exception is system-dependent, but it will always be a
* subclass of {@link IOException}.
*
+ * <p>If the operating system does not support the creation of
+ * processes, an {@link UnsupportedOperationException} will be thrown.
+ *
*
* @param cmdarray array containing the command to call and
* its arguments.
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Executable.java Wed Jul 05 20:19:27 2017 +0200
@@ -662,7 +662,7 @@
*
* If this {@code Executable} object represents a static method or
* represents a constructor of a top level, static member, local, or
- * anoymous class, then the return value is null.
+ * anonymous class, then the return value is null.
*
* @return an object representing the receiver type of the method or
* constructor represented by this {@code Executable} or {@code null} if
--- a/jdk/src/java.base/share/classes/java/math/BigDecimal.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/math/BigDecimal.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -4814,41 +4814,61 @@
if (dividendHi >= divisor) {
return null;
}
+
final int shift = Long.numberOfLeadingZeros(divisor);
divisor <<= shift;
final long v1 = divisor >>> 32;
final long v0 = divisor & LONG_MASK;
- long q1, q0;
- long r_tmp;
-
long tmp = dividendLo << shift;
long u1 = tmp >>> 32;
long u0 = tmp & LONG_MASK;
tmp = (dividendHi << shift) | (dividendLo >>> 64 - shift);
long u2 = tmp & LONG_MASK;
- tmp = divWord(tmp,v1);
- q1 = tmp & LONG_MASK;
- r_tmp = tmp >>> 32;
+ long q1, r_tmp;
+ if (v1 == 1) {
+ q1 = tmp;
+ r_tmp = 0;
+ } else if (tmp >= 0) {
+ q1 = tmp / v1;
+ r_tmp = tmp - q1 * v1;
+ } else {
+ long[] rq = divRemNegativeLong(tmp, v1);
+ q1 = rq[1];
+ r_tmp = rq[0];
+ }
+
while(q1 >= DIV_NUM_BASE || unsignedLongCompare(q1*v0, make64(r_tmp, u1))) {
q1--;
r_tmp += v1;
if (r_tmp >= DIV_NUM_BASE)
break;
}
+
tmp = mulsub(u2,u1,v1,v0,q1);
u1 = tmp & LONG_MASK;
- tmp = divWord(tmp,v1);
- q0 = tmp & LONG_MASK;
- r_tmp = tmp >>> 32;
+ long q0;
+ if (v1 == 1) {
+ q0 = tmp;
+ r_tmp = 0;
+ } else if (tmp >= 0) {
+ q0 = tmp / v1;
+ r_tmp = tmp - q0 * v1;
+ } else {
+ long[] rq = divRemNegativeLong(tmp, v1);
+ q0 = rq[1];
+ r_tmp = rq[0];
+ }
+
while(q0 >= DIV_NUM_BASE || unsignedLongCompare(q0*v0,make64(r_tmp,u0))) {
q0--;
r_tmp += v1;
if (r_tmp >= DIV_NUM_BASE)
break;
}
+
if((int)q1 < 0) {
// result (which is positive and unsigned here)
// can't fit into long due to sign bit is used for value
@@ -4871,10 +4891,13 @@
}
}
}
+
long q = make64(q1,q0);
q*=sign;
+
if (roundingMode == ROUND_DOWN && scale == preferredScale)
return valueOf(q, scale);
+
long r = mulsub(u1, u0, v1, v0, q0) >>> shift;
if (r != 0) {
boolean increment = needIncrement(divisor >>> shift, roundingMode, sign, q, r);
@@ -4917,28 +4940,35 @@
}
}
- private static long divWord(long n, long dLong) {
- long r;
- long q;
- if (dLong == 1) {
- q = (int)n;
- return (q & LONG_MASK);
- }
+ /**
+ * Calculate the quotient and remainder of dividing a negative long by
+ * another long.
+ *
+ * @param n the numerator; must be negative
+ * @param d the denominator; must not be unity
+ * @return a two-element {@long} array with the remainder and quotient in
+ * the initial and final elements, respectively
+ */
+ private static long[] divRemNegativeLong(long n, long d) {
+ assert n < 0 : "Non-negative numerator " + n;
+ assert d != 1 : "Unity denominator";
+
// Approximate the quotient and remainder
- q = (n >>> 1) / (dLong >>> 1);
- r = n - q*dLong;
+ long q = (n >>> 1) / (d >>> 1);
+ long r = n - q * d;
// Correct the approximation
while (r < 0) {
- r += dLong;
+ r += d;
q--;
}
- while (r >= dLong) {
- r -= dLong;
+ while (r >= d) {
+ r -= d;
q++;
}
- // n - q*dlong == r && 0 <= r <dLong, hence we're done.
- return (r << 32) | (q & LONG_MASK);
+
+ // n - q*d == r && 0 <= r < d, hence we're done.
+ return new long[] {r, q};
}
private static long make64(long hi, long lo) {
--- a/jdk/src/java.base/share/classes/java/net/DatagramSocket.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/net/DatagramSocket.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1308,6 +1308,7 @@
/**
* Sets the value of a socket option.
*
+ * @param <T> The type of the socket option value
* @param name The socket option
* @param value The value of the socket option. A value of {@code null}
* may be valid for some options.
@@ -1342,6 +1343,7 @@
/**
* Returns the value of a socket option.
*
+ * @param <T> The type of the socket option value
* @param name The socket option
*
* @return The value of the socket option.
--- a/jdk/src/java.base/share/classes/java/net/DatagramSocketImpl.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/net/DatagramSocketImpl.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -267,6 +267,7 @@
/**
* Called to set a socket option.
*
+ * @param <T> The type of the socket option value
* @param name The socket option
*
* @param value The value of the socket option. A value of {@code null}
@@ -276,7 +277,7 @@
* support the option
*
* @throws NullPointerException if name is {@code null}
- *
+ * @throws IOException if an I/O problem occurs while attempting to set the option
* @since 1.9
*/
protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
@@ -308,12 +309,15 @@
/**
* Called to get a socket option.
*
+ * @return the socket option
+ * @param <T> The type of the socket option value
* @param name The socket option
*
* @throws UnsupportedOperationException if the DatagramSocketImpl does not
* support the option
*
* @throws NullPointerException if name is {@code null}
+ * @throws IOException if an I/O problem occurs while attempting to set the option
*
* @since 1.9
*/
--- a/jdk/src/java.base/share/classes/java/net/ServerSocket.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/net/ServerSocket.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -924,6 +924,7 @@
/**
* Sets the value of a socket option.
*
+ * @param <T> The type of the socket option value
* @param name The socket option
* @param value The value of the socket option. A value of {@code null}
* may be valid for some options.
@@ -957,6 +958,7 @@
/**
* Returns the value of a socket option.
*
+ * @param <T> The type of the socket option value
* @param name The socket option
*
* @return The value of the socket option.
--- a/jdk/src/java.base/share/classes/java/net/Socket.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/net/Socket.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1727,6 +1727,7 @@
/**
* Sets the value of a socket option.
*
+ * @param <T> The type of the socket option value
* @param name The socket option
* @param value The value of the socket option. A value of {@code null}
* may be valid for some options.
@@ -1758,6 +1759,7 @@
/**
* Returns the value of a socket option.
*
+ * @param <T> The type of the socket option value
* @param name The socket option
*
* @return The value of the socket option.
--- a/jdk/src/java.base/share/classes/java/net/SocketImpl.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/net/SocketImpl.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -362,6 +362,7 @@
/**
* Called to set a socket option.
*
+ * @param <T> The type of the socket option value
* @param name The socket option
*
* @param value The value of the socket option. A value of {@code null}
@@ -397,6 +398,7 @@
/**
* Called to get a socket option.
*
+ * @param <T> The type of the socket option value
* @param name The socket option
*
* @return the value of the named option
--- a/jdk/src/java.base/share/classes/java/security/KeyStore.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/security/KeyStore.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1618,11 +1618,13 @@
* integrity check.
*
* <p>
- * This method traverses the list of registered security {@link Providers},
- * starting with the most preferred Provider.
- * For each {@link KeyStoreSpi} implementation supported by a Provider,
- * it invokes the {@link engineProbe} method to determine if it supports
- * the specified keystore.
+ * This method traverses the list of registered security
+ * {@linkplain Provider providers}, starting with the most
+ * preferred Provider.
+ * For each {@link KeyStoreSpi} implementation supported by a
+ * Provider, it invokes the {@link
+ * KeyStoreSpi#engineProbe(InputStream) engineProbe} method to
+ * determine if it supports the specified keystore.
* A new KeyStore object is returned that encapsulates the KeyStoreSpi
* implementation from the first Provider that supports the specified file.
*
@@ -1672,11 +1674,12 @@
* unlock the keystore data or perform an integrity check.
*
* <p>
- * This method traverses the list of registered security {@link Providers},
- * starting with the most preferred Provider.
- * For each {@link KeyStoreSpi} implementation supported by a Provider,
- * it invokes the {@link engineProbe} method to determine if it supports
- * the specified keystore.
+ * This method traverses the list of registered security {@linkplain
+ * Provider providers}, starting with the most preferred Provider.
+ * For each {@link KeyStoreSpi} implementation supported by a
+ * Provider, it invokes the {@link
+ * KeyStoreSpi#engineProbe(InputStream) engineProbe} method to
+ * determine if it supports the specified keystore.
* A new KeyStore object is returned that encapsulates the KeyStoreSpi
* implementation from the first Provider that supports the specified file.
*
--- a/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java Wed Jul 05 20:19:27 2017 +0200
@@ -538,7 +538,14 @@
* <ul>
* <li>a leap-year must imply a year-length longer than a non leap-year.
* <li>a chronology that does not support the concept of a year must return false.
+ * <li>the correct result must be returned for all years within the
+ * valid range of years for the chronology.
* </ul>
+ * <p>
+ * Outside the range of valid years an implementation is free to return
+ * either a best guess or false.
+ * An implementation must not throw an exception, even if the year is
+ * outside the range of valid years.
*
* @param prolepticYear the proleptic-year to check, not validated for range
* @return true if the year is a leap year
--- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java Wed Jul 05 20:19:27 2017 +0200
@@ -475,10 +475,10 @@
@Override
public boolean isLeapYear(long prolepticYear) {
checkCalendarInit();
+ if (prolepticYear < getMinimumYear() || prolepticYear > getMaximumYear()) {
+ return false;
+ }
int epochMonth = yearToEpochMonth((int) prolepticYear);
- if (epochMonth < 0 || epochMonth > maxEpochDay) {
- throw new DateTimeException("Hijrah date out of range");
- }
int len = getYearLength((int) prolepticYear);
return (len > 354);
}
--- a/jdk/src/java.base/share/classes/java/util/ComparableTimSort.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/ComparableTimSort.java Wed Jul 05 20:19:27 2017 +0200
@@ -147,7 +147,7 @@
*/
int stackLen = (len < 120 ? 5 :
len < 1542 ? 10 :
- len < 119151 ? 24 : 40);
+ len < 119151 ? 24 : 49);
runBase = new int[stackLen];
runLen = new int[stackLen];
}
--- a/jdk/src/java.base/share/classes/java/util/TimSort.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/TimSort.java Wed Jul 05 20:19:27 2017 +0200
@@ -177,7 +177,7 @@
*/
int stackLen = (len < 120 ? 5 :
len < 1542 ? 10 :
- len < 119151 ? 24 : 40);
+ len < 119151 ? 24 : 49);
runBase = new int[stackLen];
runLen = new int[stackLen];
}
--- a/jdk/src/java.base/share/classes/java/util/stream/Stream.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/stream/Stream.java Wed Jul 05 20:19:27 2017 +0200
@@ -988,6 +988,21 @@
}
/**
+ * Returns a sequential {@code Stream} containing a single element, if
+ * non-null, otherwise returns an empty {@code Stream}.
+ *
+ * @param t the single element
+ * @param <T> the type of stream elements
+ * @return a stream with a single element if the specified element
+ * is non-null, otherwise an empty stream
+ * @since 1.9
+ */
+ public static<T> Stream<T> ofNullable(T t) {
+ return t == null ? Stream.empty()
+ : StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
+ }
+
+ /**
* Returns a sequential ordered stream whose elements are the specified values.
*
* @param <T> the type of stream elements
--- a/jdk/src/java.base/share/classes/sun/nio/cs/SingleByte.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/SingleByte.java Wed Jul 05 20:19:27 2017 +0200
@@ -160,22 +160,18 @@
byte[] da = dst.array();
int dp = dst.arrayOffset() + dst.position();
int dl = dst.arrayOffset() + dst.limit();
+ int len = Math.min(dl - dp, sl - sp);
- CoderResult cr = CoderResult.UNDERFLOW;
- if ((dl - dp) < (sl - sp)) {
- sl = sp + (dl - dp);
- cr = CoderResult.OVERFLOW;
- }
-
- while (sp < sl) {
+ while (len-- > 0) {
char c = sa[sp];
int b = encode(c);
if (b == UNMAPPABLE_ENCODING) {
if (Character.isSurrogate(c)) {
if (sgp == null)
sgp = new Surrogate.Parser();
- if (sgp.parse(c, sa, sp, sl) < 0)
+ if (sgp.parse(c, sa, sp, sl) < 0) {
return withResult(sgp.error(), src, sp, dst, dp);
+ }
return withResult(sgp.unmappableResult(), src, sp, dst, dp);
}
return withResult(CoderResult.unmappableForLength(1),
@@ -184,7 +180,8 @@
da[dp++] = (byte)b;
sp++;
}
- return withResult(cr, src, sp, dst, dp);
+ return withResult(sp < sl ? CoderResult.OVERFLOW : CoderResult.UNDERFLOW,
+ src, sp, dst, dp);
}
private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) {
--- a/jdk/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java Wed Jul 05 20:19:27 2017 +0200
@@ -243,8 +243,11 @@
if (cr.isUnderflow()) {
if (lcb.hasRemaining()) {
leftoverChar = lcb.get();
- if (cb != null && cb.hasRemaining())
- flushLeftoverChar(cb, endOfInput);
+ if (cb != null && cb.hasRemaining()) {
+ lcb.clear();
+ lcb.put(leftoverChar).put(cb.get()).flip();
+ continue;
+ }
return;
}
break;
@@ -265,24 +268,24 @@
CharBuffer cb = CharBuffer.wrap(cbuf, off, len);
if (haveLeftoverChar)
- flushLeftoverChar(cb, false);
+ flushLeftoverChar(cb, false);
while (cb.hasRemaining()) {
- CoderResult cr = encoder.encode(cb, bb, false);
- if (cr.isUnderflow()) {
- assert (cb.remaining() <= 1) : cb.remaining();
- if (cb.remaining() == 1) {
- haveLeftoverChar = true;
- leftoverChar = cb.get();
+ CoderResult cr = encoder.encode(cb, bb, false);
+ if (cr.isUnderflow()) {
+ assert (cb.remaining() <= 1) : cb.remaining();
+ if (cb.remaining() == 1) {
+ haveLeftoverChar = true;
+ leftoverChar = cb.get();
+ }
+ break;
}
- break;
- }
- if (cr.isOverflow()) {
- assert bb.position() > 0;
- writeBytes();
- continue;
- }
- cr.throwException();
+ if (cr.isOverflow()) {
+ assert bb.position() > 0;
+ writeBytes();
+ continue;
+ }
+ cr.throwException();
}
}
--- a/jdk/src/java.base/share/classes/sun/security/util/HostnameChecker.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/util/HostnameChecker.java Wed Jul 05 20:19:27 2017 +0200
@@ -26,6 +26,8 @@
package sun.security.util;
import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.*;
import java.security.Principal;
@@ -148,6 +150,17 @@
String ipAddress = (String)next.get(1);
if (expectedIP.equalsIgnoreCase(ipAddress)) {
return;
+ } else {
+ // compare InetAddress objects in order to ensure
+ // equality between a long IPv6 address and its
+ // abbreviated form.
+ try {
+ if (InetAddress.getByName(expectedIP).equals(
+ InetAddress.getByName(ipAddress))) {
+ return;
+ }
+ } catch (UnknownHostException e) {
+ } catch (SecurityException e) {}
}
}
}
--- a/jdk/src/java.base/share/conf/security/java.policy Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/share/conf/security/java.policy Wed Jul 05 20:19:27 2017 +0200
@@ -55,6 +55,29 @@
permission java.io.FilePermission "<<ALL FILES>>", "read";
};
+grant codeBase "jrt:/java.xml.ws" {
+ permission java.lang.RuntimePermission "accessClassInPackage.com.sun.xml.internal.*";
+ permission java.lang.RuntimePermission "accessClassInPackage.com.sun.istack.internal";
+ permission java.lang.RuntimePermission "accessClassInPackage.com.sun.istack.internal.*";
+ permission java.lang.RuntimePermission "accessClassInPackage.com.sun.org.apache.xerces.internal.*";
+ permission java.lang.RuntimePermission "accessDeclaredMembers";
+ permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+ permission java.util.PropertyPermission "*", "read";
+};
+
+grant codeBase "jrt:/java.xml.bind" {
+ permission java.lang.RuntimePermission "accessClassInPackage.com.sun.xml.internal.*";
+ permission java.lang.RuntimePermission "accessClassInPackage.com.sun.istack.internal";
+ permission java.lang.RuntimePermission "accessClassInPackage.com.sun.istack.internal.*";
+ permission java.lang.RuntimePermission "accessDeclaredMembers";
+ permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+ permission java.util.PropertyPermission "*", "read";
+};
+
+grant codeBase "jrt:/java.activation" {
+ permission java.security.AllPermission;
+};
+
// default permissions granted to all domains
grant {
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java Wed Jul 05 20:19:27 2017 +0200
@@ -391,6 +391,10 @@
if (!this.root.equalsIgnoreCase(other.root))
throw new IllegalArgumentException("'other' has different root");
+ // this path is the empty path
+ if (this.isEmpty())
+ return other;
+
int bn = this.getNameCount();
int cn = other.getNameCount();
--- a/jdk/src/java.base/windows/native/libjava/ProcessImpl_md.c Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/windows/native/libjava/ProcessImpl_md.c Wed Jul 05 20:19:27 2017 +0200
@@ -30,6 +30,7 @@
#include "jvm.h"
#include "jni_util.h"
#include "io_util.h"
+#include "io_util_md.h"
#include <windows.h>
#include <io.h>
@@ -467,26 +468,6 @@
return (jboolean) CloseHandle((HANDLE) handle);
}
-/**
- * Returns a copy of the Unicode characters of a string. Fow now this
- * function doesn't handle long path names and other issues.
- */
-static WCHAR* getPath(JNIEnv *env, jstring ps) {
- WCHAR *pathbuf = NULL;
- const jchar *chars = (*(env))->GetStringChars(env, ps, NULL);
- if (chars != NULL) {
- size_t pathlen = wcslen(chars);
- pathbuf = (WCHAR*)malloc((pathlen + 6) * sizeof(WCHAR));
- if (pathbuf == NULL) {
- JNU_ThrowOutOfMemoryError(env, NULL);
- } else {
- wcscpy(pathbuf, chars);
- }
- (*env)->ReleaseStringChars(env, ps, chars);
- }
- return pathbuf;
-}
-
JNIEXPORT jlong JNICALL
Java_java_lang_ProcessImpl_openForAtomicAppend(JNIEnv *env, jclass ignored, jstring path)
{
@@ -495,7 +476,7 @@
const DWORD disposition = OPEN_ALWAYS;
const DWORD flagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
HANDLE h;
- WCHAR *pathbuf = getPath(env, path);
+ WCHAR *pathbuf = pathToNTPath(env, path, JNI_FALSE);
if (pathbuf == NULL) {
/* Exception already pending */
return -1;
--- a/jdk/src/java.base/windows/native/libjava/io_util_md.h Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.base/windows/native/libjava/io_util_md.h Wed Jul 05 20:19:27 2017 +0200
@@ -33,7 +33,8 @@
/*
* Prototypes for functions in io_util_md.c called from io_util.c,
- * FileDescriptor.c, FileInputStream.c, FileOutputStream.c
+ * FileDescriptor.c, FileInputStream.c, FileOutputStream.c,
+ * ProcessImpl_md.c
*/
WCHAR* pathToNTPath(JNIEnv *env, jstring path, jboolean throwFNFE);
WCHAR* fileToNTPath(JNIEnv *env, jobject file, jfieldID id);
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Wed Jul 05 20:19:27 2017 +0200
@@ -138,6 +138,7 @@
* @return The value for the given parameter. Returns <code>null</code> if no
* value is assigned to the key.
*
+ * @throws NullPointerException if the key is null.
*/
public Object getParameter(String key);
--- a/jdk/src/jdk.rmic/share/classes/sun/rmi/rmic/BatchEnvironment.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/jdk.rmic/share/classes/sun/rmi/rmic/BatchEnvironment.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -61,6 +61,7 @@
* they are subject to change or removal without notice.
*/
+@SuppressWarnings("deprecation")
public class BatchEnvironment extends sun.tools.javac.BatchEnvironment {
/** instance of Main which created this environment */
--- a/jdk/src/jdk.rmic/share/classes/sun/rmi/rmic/Main.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/jdk.rmic/share/classes/sun/rmi/rmic/Main.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -676,7 +676,7 @@
* Compile a single class.
* Fallthrough is intentional
*/
- @SuppressWarnings("fallthrough")
+ @SuppressWarnings({"fallthrough", "deprecation"})
public boolean compileClass (ClassDeclaration c,
ByteArrayOutputStream buf,
BatchEnvironment env)
--- a/jdk/src/jdk.rmic/share/classes/sun/tools/java/BinaryClass.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/jdk.rmic/share/classes/sun/tools/java/BinaryClass.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
* supported API. Code that depends on them does so at its own risk:
* they are subject to change or removal without notice.
*/
+@SuppressWarnings("deprecation")
public final
class BinaryClass extends ClassDefinition implements Constants {
BinaryConstantPool cpool;
--- a/jdk/src/jdk.rmic/share/classes/sun/tools/java/ClassDefinition.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/jdk.rmic/share/classes/sun/tools/java/ClassDefinition.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,7 @@
* supported API. Code that depends on them does so at its own risk:
* they are subject to change or removal without notice.
*/
+@SuppressWarnings("deprecation")
public
class ClassDefinition implements Constants {
--- a/jdk/src/jdk.rmic/share/classes/sun/tools/java/MemberDefinition.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/jdk.rmic/share/classes/sun/tools/java/MemberDefinition.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@
* supported API. Code that depends on them does so at its own risk:
* they are subject to change or removal without notice.
*/
+@SuppressWarnings("deprecation")
public
class MemberDefinition implements Constants {
protected long where;
--- a/jdk/src/jdk.rmic/share/classes/sun/tools/java/Scanner.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/src/jdk.rmic/share/classes/sun/tools/java/Scanner.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -58,6 +58,7 @@
* @author Arthur van Hoff
*/
+@SuppressWarnings("deprecation")
public
class Scanner implements Constants {
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2015, Red Hat, Inc.
+ * 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 8069072
+ * @summary Test vectors for com.sun.crypto.provider.GHASH
+ */
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+
+public class TestGHASH {
+
+ private final Constructor<?> GHASH;
+ private final Method UPDATE;
+ private final Method DIGEST;
+
+ TestGHASH(String className) throws Exception {
+ Class<?> cls = Class.forName(className);
+ GHASH = cls.getDeclaredConstructor(byte[].class);
+ GHASH.setAccessible(true);
+ UPDATE = cls.getDeclaredMethod("update", byte[].class);
+ UPDATE.setAccessible(true);
+ DIGEST = cls.getDeclaredMethod("digest");
+ DIGEST.setAccessible(true);
+ }
+
+
+ private Object newGHASH(byte[] H) throws Exception {
+ return GHASH.newInstance(H);
+ }
+
+ private void updateGHASH(Object hash, byte[] data)
+ throws Exception {
+ UPDATE.invoke(hash, data);
+ }
+
+ private byte[] digestGHASH(Object hash) throws Exception {
+ return (byte[]) DIGEST.invoke(hash);
+ }
+
+ private static final String HEX_DIGITS = "0123456789abcdef";
+
+ private static String hex(byte[] bs) {
+ StringBuilder sb = new StringBuilder(2 * bs.length);
+ for (byte b : bs) {
+ sb.append(HEX_DIGITS.charAt((b >> 4) & 0xF));
+ sb.append(HEX_DIGITS.charAt(b & 0xF));
+ }
+ return sb.toString();
+ }
+
+ private static byte[] bytes(String hex) {
+ if ((hex.length() & 1) != 0) {
+ throw new AssertionError();
+ }
+ byte[] result = new byte[hex.length() / 2];
+ for (int i = 0; i < result.length; ++i) {
+ int a = HEX_DIGITS.indexOf(hex.charAt(2 * i));
+ int b = HEX_DIGITS.indexOf(hex.charAt(2 * i + 1));
+ if ((a | b) < 0) {
+ if (a < 0) {
+ throw new AssertionError(
+ "bad character " + (int) hex.charAt(2 * i));
+ }
+ throw new AssertionError(
+ "bad character " + (int) hex.charAt(2 * i + 1));
+ }
+ result[i] = (byte) ((a << 4) | b);
+ }
+ return result;
+ }
+
+ private static byte[] bytes(long L0, long L1) {
+ return ByteBuffer.allocate(16)
+ .putLong(L0)
+ .putLong(L1)
+ .array();
+ }
+
+ private void check(int testCase, String H, String A,
+ String C, String expected) throws Exception {
+ int lenA = A.length() * 4;
+ while ((A.length() % 32) != 0) {
+ A += '0';
+ }
+ int lenC = C.length() * 4;
+ while ((C.length() % 32) != 0) {
+ C += '0';
+ }
+
+ Object hash = newGHASH(bytes(H));
+ updateGHASH(hash, bytes(A));
+ updateGHASH(hash, bytes(C));
+ updateGHASH(hash, bytes(lenA, lenC));
+ byte[] digest = digestGHASH(hash);
+ String actual = hex(digest);
+ if (!expected.equals(actual)) {
+ throw new AssertionError(String.format("%d: expected %s, got %s",
+ testCase, expected, actual));
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ TestGHASH test;
+ if (args.length == 0) {
+ test = new TestGHASH("com.sun.crypto.provider.GHASH");
+ } else {
+ test = new TestGHASH(args[0]);
+ }
+
+ // Test vectors from David A. McGrew, John Viega,
+ // "The Galois/Counter Mode of Operation (GCM)", 2005.
+ // <http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf>
+
+ test.check(1, "66e94bd4ef8a2c3b884cfa59ca342b2e", "", "",
+ "00000000000000000000000000000000");
+ test.check(2,
+ "66e94bd4ef8a2c3b884cfa59ca342b2e", "",
+ "0388dace60b6a392f328c2b971b2fe78",
+ "f38cbb1ad69223dcc3457ae5b6b0f885");
+ test.check(3,
+ "b83b533708bf535d0aa6e52980d53b78", "",
+ "42831ec2217774244b7221b784d0d49c" +
+ "e3aa212f2c02a4e035c17e2329aca12e" +
+ "21d514b25466931c7d8f6a5aac84aa05" +
+ "1ba30b396a0aac973d58e091473f5985",
+ "7f1b32b81b820d02614f8895ac1d4eac");
+ test.check(4,
+ "b83b533708bf535d0aa6e52980d53b78",
+ "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
+ "42831ec2217774244b7221b784d0d49c" +
+ "e3aa212f2c02a4e035c17e2329aca12e" +
+ "21d514b25466931c7d8f6a5aac84aa05" +
+ "1ba30b396a0aac973d58e091",
+ "698e57f70e6ecc7fd9463b7260a9ae5f");
+ test.check(5, "b83b533708bf535d0aa6e52980d53b78",
+ "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
+ "61353b4c2806934a777ff51fa22a4755" +
+ "699b2a714fcdc6f83766e5f97b6c7423" +
+ "73806900e49f24b22b097544d4896b42" +
+ "4989b5e1ebac0f07c23f4598",
+ "df586bb4c249b92cb6922877e444d37b");
+ }
+}
--- a/jdk/test/com/sun/jdi/ShellScaffold.sh Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/com/sun/jdi/ShellScaffold.sh Wed Jul 05 20:19:27 2017 +0200
@@ -259,7 +259,7 @@
;;
esac
- if [ -r $jdk/bin/dt_shmem.dll -o -r $jdk/jre/bin/dt_shmem.dll ] ; then
+ if [ -r $jdk/bin/dt_shmem.dll ] ; then
transport=dt_shmem
address=kkkk.$$
else
@@ -933,18 +933,10 @@
debuggeeCmd=`$jdk/bin/jps -v | $grep $debuggeeKeyword`
realDebuggeePid=`echo "$debuggeeCmd" | sed -e 's@ .*@@'`
if [ ! -z "$realDebuggeePid" ] ; then
- if [ -r "$jdk/lib/sa-jdi.jar" ] ; then
- # disableVersionCheck can be removed after 6475822
- # is fixed.
- moption="-m -J-Dsun.jvm.hotspot.runtime.VM.disableVersionCheck"
- else
- moption=
- fi
-
echo "-- debuggee process info ----------------------" >&2
echo " $debuggeeCmd" >&2
echo "-- debuggee threads: jstack $moption $realDebuggeePid" >&2
- $jdk/bin/$jstack $moption $realDebuggeePid >&2
+ $jdk/bin/$jstack $realDebuggeePid >&2
echo "=============================================" >&2
echo >&2
fi
--- a/jdk/test/demo/jvmti/DemoRun.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/demo/jvmti/DemoRun.java Wed Jul 05 20:19:27 2017 +0200
@@ -115,10 +115,7 @@
*/
public void runit(String class_name, String vm_options[])
{
- String jre_home = System.getProperty("java.home");
- String sdk_home = (jre_home.endsWith("jre") ?
- (jre_home + File.separator + "..") :
- jre_home );
+ String sdk_home = System.getProperty("java.home");
String cdir = System.getProperty("test.classes", ".");
String os_arch = System.getProperty("os.arch");
String os_name = System.getProperty("os.name");
@@ -126,7 +123,7 @@
String libsuffix = os_name.contains("Windows")?".dll":
os_name.contains("OS X")?".dylib":".so";
boolean hprof = demo_name.equals("hprof");
- String java = jre_home
+ String java = sdk_home
+ File.separator + "bin"
+ File.separator + "java";
/* Array of strings to be passed in for exec:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ProcessBuilder/RedirectWithLongFilename.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2015 SAP SE. 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 8072611
+ * @summary ProcessBuilder Redirect to file appending on Windows should work with long file names
+ * @author Thomas Stuefe
+ */
+
+import java.io.File;
+import java.lang.ProcessBuilder.Redirect;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class RedirectWithLongFilename {
+
+ public static void main(String[] args) throws Exception {
+
+ // windows only
+ if (!Basic.Windows.is()) {
+ return;
+ }
+
+ // Redirect ProcessBuilder output to a file whose pathlen is > 255.
+ Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir"));
+ File dir2 = null;
+ File longFileName = null;
+
+ try {
+ dir2 = Files.createTempDirectory(tmpDir, "RedirectWithLongFilename").toFile();
+ dir2.mkdirs();
+ longFileName = new File(dir2,
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "012345678901234567890123456789012345678901234567890123456789" +
+ "0123456789");
+
+ ProcessBuilder pb = new ProcessBuilder("hostname.exe");
+ pb.redirectOutput(Redirect.appendTo(longFileName));
+ Process p = pb.start();
+ p.waitFor();
+
+ if (longFileName.exists()) {
+ System.out.println("OK");
+ } else {
+ throw new RuntimeException("Test failed.");
+ }
+
+ } finally {
+ longFileName.delete();
+ dir2.delete();
+ }
+
+ }
+
+}
--- a/jdk/test/java/lang/management/MemoryMXBean/Pending.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/java/lang/management/MemoryMXBean/Pending.java Wed Jul 05 20:19:27 2017 +0200
@@ -39,7 +39,7 @@
public class Pending {
final static int NO_REF_COUNT = 600;
- final static int REF_COUNT = 600;
+ final static int REF_COUNT = 500;
final static int TOTAL_FINALIZABLE = (NO_REF_COUNT + REF_COUNT);
private static int finalized = 0;
private static MemoryMXBean mbean
@@ -83,31 +83,22 @@
// Clean the memory and remove all objects that are pending
// finalization
System.gc();
- Runtime.getRuntime().runFinalization();
-
- // Let the finalizer to finish
- try {
- Thread.sleep(200);
- } catch (Exception e) {
- throw e;
- }
-
- // Create a number of new objects but no references to them
- int startCount = mbean.getObjectPendingFinalizationCount();
+ Snapshot snapshot = getSnapshotAfterFinalization();
System.out.println("Number of objects pending for finalization:");
- System.out.println(" Before creating object: " + startCount +
- " finalized = " + finalized);
+ System.out.println(" Before creating object: " + snapshot);
printFinalizerInstanceCount();
+ // Create objects without saving reference. Should be removed at next GC.
for (int i = 0; i < NO_REF_COUNT; i++) {
new MyObject();
}
- Snapshot snapshot = getSnapshot();
+ snapshot = getSnapshot();
System.out.println(" Afer creating objects with no ref: " + snapshot);
printFinalizerInstanceCount();
+ // Create objects and save references.
objs = new Object[REF_COUNT];
for (int i = 0; i < REF_COUNT; i++) {
objs[i] = new MyObject();
@@ -139,9 +130,8 @@
+ TOTAL_FINALIZABLE);
}
- if (startCount != 0 || snapshot.curPending != 0) {
+ if (snapshot.curPending != 0) {
throw new RuntimeException("Wrong number of objects pending "
- + "finalization start = " + startCount
+ " end = " + snapshot);
}
@@ -161,29 +151,8 @@
snapshot.curFinalized != expectedTotal && i <= MAX_GC_LOOP;
i++) {
System.gc();
-
- // Pause to give a chance to Finalizer thread to run
- pause();
+ snapshot = getSnapshotAfterFinalization();
- printFinalizerInstanceCount();
- // Race condition may occur; attempt to check this
- // a few times before throwing exception.
- for (int j = 0; j < 5; j++) {
- // poll for another current pending count
- snapshot = getSnapshot();
- if (snapshot.curFinalized == expectedTotal ||
- snapshot.curPending != 0) {
- break;
- }
- }
- System.out.println(" After GC " + i + ": " + snapshot);
-
- Runtime.getRuntime().runFinalization();
-
- // Pause to give a chance to Finalizer thread to run
- pause();
-
- snapshot = getSnapshot();
if (snapshot.curFinalized == expectedTotal &&
snapshot.curPending != 0) {
throw new RuntimeException(
@@ -237,17 +206,21 @@
}
}
- private static Object pauseObj = new Object();
- private static void pause() {
- // Enter lock a without blocking
- synchronized (pauseObj) {
- try {
- // may need to tune this timeout for different platforms
- pauseObj.wait(20);
- } catch (Exception e) {
- System.err.println("Unexpected exception.");
- e.printStackTrace(System.err);
+ // Repeat getSnapshot until no pending finalization.
+ private static Snapshot getSnapshotAfterFinalization() throws Exception {
+ int loopCount = 0;
+ Snapshot snapshot = null;
+ while (loopCount < 100) {
+ Runtime.getRuntime().runFinalization();
+ Thread.sleep(50);
+ snapshot = getSnapshot();
+ if (snapshot.curPending == 0) {
+ return snapshot;
}
+ ++loopCount;
+ System.out.println("Waiting for curPending to be 0. snapshot=" + snapshot);
}
+ String msg = "Objects pending finalization is not 0. snapshot=%s";
+ throw new RuntimeException(String.format(msg, snapshot));
}
}
--- a/jdk/test/java/lang/management/ThreadMXBean/SynchronizationStatistics.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/java/lang/management/ThreadMXBean/SynchronizationStatistics.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -75,7 +75,7 @@
}
private static void waitForThreadState(Thread t, Thread.State state) throws InterruptedException {
- while (!t.isInterrupted() && t.getState() != state) {
+ while (t.getState() != state) {
Thread.sleep(3);
}
}
@@ -109,7 +109,9 @@
synchronized(lock1) {
p.arriveAndAwaitAdvance(); // phase[1]
waitForThreadState(lt, Thread.State.BLOCKED);
- lockName = mbean.getThreadInfo(tid).getLockName();
+ do {
+ lockName = mbean.getThreadInfo(tid).getLockName();
+ } while (lockName == null);
}
p.arriveAndAwaitAdvance(); // phase[2]
@@ -159,7 +161,9 @@
synchronized(lock1) {
p.arriveAndAwaitAdvance(); // phase[1]
waitForThreadState(lt, Thread.State.BLOCKED);
- lockName = mbean.getThreadInfo(tid).getLockName();
+ do {
+ lockName = mbean.getThreadInfo(tid).getLockName();
+ } while (lockName == null);
}
p.arriveAndAwaitAdvance(); // phase[2]
@@ -168,7 +172,9 @@
synchronized(lock2) {
p.arriveAndAwaitAdvance(); // phase [3]
waitForThreadState(lt, Thread.State.BLOCKED);
- lockName = mbean.getThreadInfo(tid).getLockName();
+ do {
+ lockName = mbean.getThreadInfo(tid).getLockName();
+ } while (lockName == null);
}
p.arriveAndAwaitAdvance(); // phase [4]
testBlocked(ti, () -> mbean.getThreadInfo(tid), lockName, lock2);
--- a/jdk/test/java/math/BigDecimal/DivideTests.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/java/math/BigDecimal/DivideTests.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4851776 4907265 6177836 6876282
+ * @bug 4851776 4907265 6177836 6876282 8066842
* @summary Some tests for the divide methods.
* @author Joseph D. Darcy
*/
@@ -358,6 +358,57 @@
return failures;
}
+ private static int divideByOneTests() {
+ int failures = 0;
+
+ //problematic divisor: one with scale 17
+ BigDecimal one = BigDecimal.ONE.setScale(17);
+ RoundingMode rounding = RoundingMode.UNNECESSARY;
+
+ long[][] unscaledAndScale = new long[][] {
+ { Long.MAX_VALUE, 17},
+ {-Long.MAX_VALUE, 17},
+ { Long.MAX_VALUE, 0},
+ {-Long.MAX_VALUE, 0},
+ { Long.MAX_VALUE, 100},
+ {-Long.MAX_VALUE, 100}
+ };
+
+ for (long[] uas : unscaledAndScale) {
+ long unscaled = uas[0];
+ int scale = (int)uas[1];
+
+ BigDecimal noRound = null;
+ try {
+ noRound = BigDecimal.valueOf(unscaled, scale).
+ divide(one, RoundingMode.UNNECESSARY);
+ } catch (ArithmeticException e) {
+ failures++;
+ System.err.println("ArithmeticException for value " + unscaled
+ + " and scale " + scale + " without rounding");
+ }
+
+ BigDecimal roundDown = null;
+ try {
+ roundDown = BigDecimal.valueOf(unscaled, scale).
+ divide(one, RoundingMode.DOWN);
+ } catch (ArithmeticException e) {
+ failures++;
+ System.err.println("ArithmeticException for value " + unscaled
+ + " and scale " + scale + " with rounding down");
+ }
+
+ if (noRound != null && roundDown != null
+ && noRound.compareTo(roundDown) != 0) {
+ failures++;
+ System.err.println("Equality failure for value " + unscaled
+ + " and scale " + scale);
+ }
+ }
+
+ return failures;
+ }
+
public static void main(String argv[]) {
int failures = 0;
@@ -366,10 +417,11 @@
failures += properScaleTests();
failures += trailingZeroTests();
failures += scaledRoundedDivideTests();
+ failures += divideByOneTests();
if (failures > 0) {
throw new RuntimeException("Incurred " + failures +
- " failures while testing exact divide.");
+ " failures while testing division.");
}
}
}
--- a/jdk/test/java/nio/file/Path/PathOps.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/java/nio/file/Path/PathOps.java Wed Jul 05 20:19:27 2017 +0200
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4313887 6838333 6925932 7006126 8037945
+ * @bug 4313887 6838333 6925932 7006126 8037945 8072495
* @summary Unit test for java.nio.file.Path path operations
*/
@@ -516,7 +516,9 @@
.relativize("\\\\server\\share\\bar", "..\\bar")
.relativize("\\\\server\\share\\foo", "");
test("")
- .relativize("", "");
+ .relativize("", "")
+ .relativize("a", "a")
+ .relativize("a\\b\\c", "a\\b\\c");
// normalize
test("C:\\")
--- a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Wed Jul 05 20:19:27 2017 +0200
@@ -30,6 +30,7 @@
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
import static java.time.temporal.ChronoField.YEAR;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@@ -71,6 +72,7 @@
/**
* Tests for the Umm alQura chronology and data.
* Note: The dates used for testing are just a sample of calendar data.
+ * @bug 8067800
*/
@Test
public class TestUmmAlQuraChronology {
@@ -530,6 +532,24 @@
assertEquals(date.isLeapYear(), leapyear);
}
+ // Data provider to verify that a given hijrah year is outside the range of supported years
+ // The values are dependent on the currently configured UmmAlQura calendar data
+ @DataProvider(name="OutOfRangeLeapYears")
+ Object[][] data_invalid_leapyears() {
+ return new Object[][] {
+ {1299},
+ {1601},
+ {Integer.MAX_VALUE},
+ {Integer.MIN_VALUE},
+ };
+ }
+
+ @Test(dataProvider="OutOfRangeLeapYears")
+ public void test_notLeapYears(int y) {
+ assertFalse(HijrahChronology.INSTANCE.isLeapYear(y), "Out of range leap year");
+ }
+
+
// Date samples to convert HijrahDate to LocalDate and vice versa
@DataProvider(name="samples")
Object[][] data_samples() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Arrays/TimSortStackSize2.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8072909
+ * @run main/othervm TimSortStackSize2 67108864
+ * not for regular execution on all platforms:
+ * run main/othervm -Xmx8g TimSortStackSize2 1073741824
+ * run main/othervm -Xmx32g TimSortStackSize2 2147483644
+ * @summary Test TimSort stack size on big arrays
+ */
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+public class TimSortStackSize2 {
+
+ public static void main(String[] args) {
+ int lengthOfTest = Integer.parseInt(args[0]);
+ boolean passed = true;
+ try {
+ Arrays.sort(new TimSortStackSize2(lengthOfTest).createArray(),
+ new Comparator<Object>() {
+ @SuppressWarnings("unchecked")
+ public int compare(Object first, Object second) {
+ return ((Comparable<Object>)first).compareTo(second);
+ }
+ });
+ System.out.println("TimSort OK");
+ } catch (ArrayIndexOutOfBoundsException e){
+ System.out.println("TimSort broken");
+ e.printStackTrace();
+ passed = false;
+ }
+ try {
+ Arrays.sort(new TimSortStackSize2(lengthOfTest).createArray());
+ System.out.println("ComparableTimSort OK");
+ } catch (ArrayIndexOutOfBoundsException e){
+ System.out.println("ComparableTimSort broken:");
+ e.printStackTrace();
+ passed = false;
+ }
+ if ( !passed ){
+ throw new RuntimeException();
+ }
+ }
+
+ private static final int MIN_MERGE = 32;
+ private final int minRun;
+ private final int length;
+ private final List<Long> runs = new ArrayList<Long>();
+
+ public TimSortStackSize2(int len) {
+ this.length = len;
+ minRun = minRunLength(len);
+ fillRunsJDKWorstCase();
+ }
+
+ private static int minRunLength(int n) {
+ assert n >= 0;
+ int r = 0; // Becomes 1 if any 1 bits are shifted off
+ while (n >= MIN_MERGE) {
+ r |= (n & 1);
+ n >>= 1;
+ }
+ return n + r;
+ }
+
+ /**
+ * Adds a sequence x_1, ..., x_n of run lengths to <code>runs</code> such that:<br>
+ * 1. X = x_1 + ... + x_n <br>
+ * 2. x_j >= minRun for all j <br>
+ * 3. x_1 + ... + x_{j-2} < x_j < x_1 + ... + x_{j-1} for all j <br>
+ * These conditions guarantee that TimSort merges all x_j's one by one
+ * (resulting in X) using only merges on the second-to-last element.
+ * @param X The sum of the sequence that should be added to runs.
+ */
+ private void generateJDKWrongElem(long X) {
+ for(long newTotal; X >= 2*minRun+1; X = newTotal) {
+ //Default strategy
+ newTotal = X/2 + 1;
+ //Specialized strategies
+ if(3*minRun+3 <= X && X <= 4*minRun+1) {
+ // add x_1=MIN+1, x_2=MIN, x_3=X-newTotal to runs
+ newTotal = 2*minRun+1;
+ } else if(5*minRun+5 <= X && X <= 6*minRun+5) {
+ // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=X-newTotal to runs
+ newTotal = 3*minRun+3;
+ } else if(8*minRun+9 <= X && X <= 10*minRun+9) {
+ // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=2MIN+2, x_5=X-newTotal to runs
+ newTotal = 5*minRun+5;
+ } else if(13*minRun+15 <= X && X <= 16*minRun+17) {
+ // add x_1=MIN+1, x_2=MIN, x_3=MIN+2, x_4=2MIN+2, x_5=3MIN+4, x_6=X-newTotal to runs
+ newTotal = 8*minRun+9;
+ }
+ runs.add(0, X-newTotal);
+ }
+ runs.add(0, X);
+ }
+
+ /**
+ * Fills <code>runs</code> with a sequence of run lengths of the form<br>
+ * Y_n x_{n,1} x_{n,2} ... x_{n,l_n} <br>
+ * Y_{n-1} x_{n-1,1} x_{n-1,2} ... x_{n-1,l_{n-1}} <br>
+ * ... <br>
+ * Y_1 x_{1,1} x_{1,2} ... x_{1,l_1}<br>
+ * The Y_i's are chosen to satisfy the invariant throughout execution,
+ * but the x_{i,j}'s are merged (by <code>TimSort.mergeCollapse</code>)
+ * into an X_i that violates the invariant.
+ * X is the sum of all run lengths that will be added to <code>runs</code>.
+ */
+ private void fillRunsJDKWorstCase() {
+ long runningTotal = 0;
+ long Y = minRun + 4;
+ long X = minRun;
+
+ while(runningTotal+Y+X <= length) {
+ runningTotal += X + Y;
+ generateJDKWrongElem(X);
+ runs.add(0,Y);
+
+ // X_{i+1} = Y_i + x_{i,1} + 1, since runs.get(1) = x_{i,1}
+ X = Y + runs.get(1) + 1;
+
+ // Y_{i+1} = X_{i+1} + Y_i + 1
+ Y += X + 1;
+ }
+
+ if(runningTotal + X <= length) {
+ runningTotal += X;
+ generateJDKWrongElem(X);
+ }
+
+ runs.add(length-runningTotal);
+ }
+
+ private Integer[] createArray() {
+ Integer[] a = new Integer[length];
+ Arrays.fill(a, 0);
+ int endRun = -1;
+ for(long len : runs)
+ a[endRun+=len] = 1;
+ a[length-1]=0;
+ return a;
+ }
+
+}
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamBuilderTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -55,8 +55,30 @@
@Test
+ public void testOfNullableWithNonNull() {
+ TestData.OfRef<Integer> data = TestData.Factory.ofSupplier("{1}",
+ () -> Stream.ofNullable(1));
+
+ withData(data).
+ stream(s -> s).
+ expectedResult(Collections.singletonList(1)).
+ exercise();
+ }
+
+ @Test
+ public void testOfNullableWithNull() {
+ TestData.OfRef<Integer> data = TestData.Factory.ofSupplier("{null})",
+ () -> Stream.ofNullable(null));
+
+ withData(data).
+ stream(s -> s).
+ expectedResult(Collections.emptyList()).
+ exercise();
+ }
+
+ @Test
public void testSingleton() {
- TestData.OfRef<Integer> data = TestData.Factory.ofSupplier("[0, 1)",
+ TestData.OfRef<Integer> data = TestData.Factory.ofSupplier("{1}",
() -> Stream.of(1));
withData(data).
@@ -118,7 +140,7 @@
@Test
public void testIntSingleton() {
- TestData.OfInt data = TestData.Factory.ofIntSupplier("[0, 1)",
+ TestData.OfInt data = TestData.Factory.ofIntSupplier("{1}",
() -> IntStream.of(1));
withData(data).
@@ -180,7 +202,7 @@
@Test
public void testLongSingleton() {
- TestData.OfLong data = TestData.Factory.ofLongSupplier("[0, 1)",
+ TestData.OfLong data = TestData.Factory.ofLongSupplier("{1}",
() -> LongStream.of(1));
withData(data).
@@ -242,7 +264,7 @@
@Test
public void testDoubleSingleton() {
- TestData.OfDouble data = TestData.Factory.ofDoubleSupplier("[0, 1)", () -> DoubleStream.of(1));
+ TestData.OfDouble data = TestData.Factory.ofDoubleSupplier("{1}", () -> DoubleStream.of(1));
withData(data).
stream(s -> s).
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Wed Jul 05 20:19:27 2017 +0200
@@ -218,19 +218,8 @@
* @return Process id
*/
public static int getProcessId() throws Exception {
-
- // Get the current process id using a reflection hack
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
- Field jvm = runtime.getClass().getDeclaredField("jvm");
-
- jvm.setAccessible(true);
- VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
-
- Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId");
-
- pid_method.setAccessible(true);
-
- int pid = (Integer) pid_method.invoke(mgmt);
+ int pid = Integer.parseInt(runtime.getName().split("@")[0]);
return pid;
}
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/SimpleSSLContext.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/SimpleSSLContext.java Wed Jul 05 20:19:27 2017 +0200
@@ -56,7 +56,7 @@
*/
public SimpleSSLContext () throws IOException {
String paths = System.getProperty("test.src.path");
- StringTokenizer st = new StringTokenizer(paths,":");
+ StringTokenizer st = new StringTokenizer(paths, File.pathSeparator);
boolean securityExceptions = false;
while (st.hasMoreTokens()) {
String path = st.nextToken();
--- a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,9 @@
import java.io.File;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.net.BindException;
import java.net.ConnectException;
import java.net.ServerSocket;
import java.rmi.RemoteException;
@@ -31,15 +33,15 @@
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Iterator;
import java.util.List;
import java.util.Objects;
+import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
import javax.management.*;
import javax.management.remote.*;
@@ -47,6 +49,8 @@
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.JDKToolLauncher;
+import sun.management.Agent;
+import sun.management.AgentConfigurationError;
/**
* @test
@@ -54,65 +58,55 @@
* @library /lib/testlibrary
* @build jdk.testlibrary.* JMXStartStopTest JMXStartStopDoSomething
* @run main/othervm/timeout=600 -XX:+UsePerfData JMXStartStopTest
- * @summary Makes sure that enabling/disabling the management agent through
- * JCMD achieves the desired results
+ * @summary Makes sure that enabling/disabling the management agent through JCMD
+ * achieves the desired results
*/
public class JMXStartStopTest {
+
private static final String TEST_SRC = System.getProperty("test.src");
private static final boolean verbose = false;
/**
- * Dynamically allocates two distinct ports using {@linkplain java.net.ServerSocket}
- * It keeps each of those ports blocked until it is first accessed by its getter
+ * Dynamically allocates distinct ports from the ephemeral range 49152-65535
*/
private static class PortAllocator {
- private final int port1, port2;
- private final ServerSocket ss1, ss2;
- PortAllocator() {
- try {
- ss1 = new ServerSocket(0);
- ss2 = new ServerSocket(0);
- port1 = ss1.getLocalPort();
- port2 = ss2.getLocalPort();
- } catch (IOException e) {
- throw new Error("Error while obtaining free ports", e);
- }
- }
+
+ private final static int LOWER_BOUND = 49152;
+ private final static int UPPER_BOUND = 65535;
+
+ private final static Random RND = new Random(System.currentTimeMillis());
- public int getPort1() {
- if (!ss1.isClosed()) {
- try {
- ss1.close();
- } catch (IOException e) {
- // just ignore
+ private static int[] allocatePorts(final int numPorts) {
+ int[] ports = new int[numPorts];
+ for (int i = 0; i < numPorts; i++) {
+ int port = -1;
+ while (port == -1) {
+ port = RND.nextInt(UPPER_BOUND - LOWER_BOUND + 1) + LOWER_BOUND;
+ for (int j = 0; j < i; j++) {
+ if (ports[j] == port) {
+ port = -1;
+ break;
+ }
+ }
}
+ System.err.println("*** port = " + port);
+ ports[i] = port;
}
- return port1;
- }
-
- public int getPort2() {
- if (!ss2.isClosed()) {
- try {
- ss2.close();
- } catch (IOException e) {
- // just ignore
- }
- }
- return port2;
+ return ports;
}
}
- private static void dbg_print(String msg){
+ private static void dbg_print(String msg) {
if (verbose) {
- System.out.println("DBG: " +msg);
+ System.out.println("DBG: " + msg);
}
}
private static int listMBeans(MBeanServerConnection server,
- ObjectName pattern,
- QueryExp query)
- throws Exception {
+ ObjectName pattern,
+ QueryExp query)
+ throws Exception {
Set<ObjectName> names = server.queryNames(pattern,query);
for (ObjectName name : names) {
@@ -131,9 +125,8 @@
return names.size();
}
-
private static void testConnectLocal(long pid)
- throws Exception {
+ throws Exception {
String jmxUrlStr = null;
@@ -208,12 +201,12 @@
String jmxUrlStr = (rmiPort != 0) ?
String.format(
- "service:jmx:rmi://localhost:%d/jndi/rmi://localhost:%d/jmxrmi",
- rmiPort,
+ "service:jmx:rmi://localhost:%d/jndi/rmi://localhost:%d/jmxrmi",
+ rmiPort,
port) :
String.format(
- "service:jmx:rmi:///jndi/rmi://localhost:%d/jmxrmi",
- port);
+ "service:jmx:rmi:///jndi/rmi://localhost:%d/jmxrmi",
+ port);
JMXServiceURL url = new JMXServiceURL(jmxUrlStr);
@@ -292,7 +285,21 @@
if (m.getName().startsWith("test_")) {
long t1 = System.currentTimeMillis();
try {
- m.invoke(null);
+ boolean retry = false;
+ do {
+ try {
+ m.invoke(null);
+ retry = false;
+ } catch (InvocationTargetException e) {
+ if (e.getCause() instanceof BindException ||
+ e.getCause() instanceof java.rmi.ConnectException) {
+ System.out.println("Failed to allocate ports. Retrying ...");
+ retry = true;
+ } else {
+ throw e;
+ }
+ }
+ } while (retry);
System.out.println("=== PASSED");
} catch (Throwable e) {
failures.add(new Failure(e, m.getName() + " failed"));
@@ -326,13 +333,23 @@
public synchronized void start() throws InterruptedException, IOException, TimeoutException {
if (started.compareAndSet(false, true)) {
try {
+ AtomicBoolean error = new AtomicBoolean(false);
p = ProcessTools.startProcess(
- "JMXStartStopDoSomething",
- pb,
- (line) -> line.equals("main enter"),
- 5,
- TimeUnit.SECONDS
+ "JMXStartStopDoSomething{" + name + "}",
+ pb,
+ (line) -> {
+ boolean ok = line.equals("main enter");
+ error.set(line.contains("BindException"));
+
+ return ok || error.get();
+ },
+ 5,
+ TimeUnit.SECONDS
);
+ if (error.get()) {
+ throw new BindException("Starting process failed due to " +
+ "the requested port not being available");
+ }
pid = p.getPid();
} catch (TimeoutException e) {
p.destroy();
@@ -347,7 +364,7 @@
}
public synchronized void stop()
- throws IOException, InterruptedException {
+ throws IOException, InterruptedException {
if (started.compareAndSet(true, false)) {
p.getOutputStream().write(0);
p.getOutputStream().flush();
@@ -374,16 +391,16 @@
* @throws TimeoutException
*/
private static Something doSomething(String name, String ... args)
- throws Exception {
+ throws Exception {
List<String> pbArgs = new ArrayList<>(Arrays.asList(
- "-cp",
- System.getProperty("test.class.path")
+ "-cp",
+ System.getProperty("test.class.path")
));
pbArgs.addAll(Arrays.asList(args));
pbArgs.add("JMXStartStopDoSomething");
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
- pbArgs.toArray(new String[pbArgs.size()])
+ pbArgs.toArray(new String[pbArgs.size()])
);
Something s = new Something(pb, name);
s.start();
@@ -399,7 +416,7 @@
*/
private static void jcmd(String ... command) throws IOException, InterruptedException {
if (command.length == 0) {
- jcmd(null, (Consumer<String>)null);
+ jcmd(null, c->{});
} else {
jcmd(null, command);
}
@@ -408,7 +425,7 @@
/**
* Run the "jcmd" command
*
- * @param c {@linkplain Consumer} instance; may be null
+ * @param c {@linkplain Consumer} instance
* @param command Command with parameters; space separated string
* @throws IOException
* @throws InterruptedException
@@ -419,8 +436,9 @@
/**
* Run the "jcmd" command
+ *
* @param target The target application name (or PID)
- * @param c {@linkplain Consumer} instance; may be null
+ * @param c {@linkplain Consumer} instance
* @param command Command with parameters; space separated string
* @throws IOException
* @throws InterruptedException
@@ -430,21 +448,37 @@
JDKToolLauncher l = JDKToolLauncher.createUsingTestJDK("jcmd");
l.addToolArg(target);
- for(String cmd : command) {
+ for (String cmd : command) {
l.addToolArg(cmd);
}
+
+ AtomicBoolean portUnavailable = new AtomicBoolean(false);
Process p = ProcessTools.startProcess(
"jcmd",
new ProcessBuilder(l.getCommand()),
- c
+ line -> {
+ if (line.contains("BindException") ||
+ line.contains(Agent.getText(AgentConfigurationError.CONNECTOR_SERVER_IO_ERROR))) {
+ portUnavailable.set(true);
+ } else {
+ c.accept(line);
+ }
+ }
);
p.waitFor();
dbg_print("[jcmd] --------");
+ if (portUnavailable.get()) {
+ String cmd = Arrays.asList(l.getCommand()).stream()
+ .collect(
+ Collectors.joining(" ", "", ": Unable to bind address")
+ );
+ throw new BindException(cmd);
+ }
}
private static final String CMD_STOP = "ManagementAgent.stop";
- private static final String CMD_START= "ManagementAgent.start";
+ private static final String CMD_START = "ManagementAgent.start";
private static final String CMD_START_LOCAL = "ManagementAgent.start_local";
static void test_01() throws Exception {
@@ -452,22 +486,22 @@
// restart on other port
System.out.println("**** Test one ****");
- PortAllocator pa = new PortAllocator();
+ int ports[] = PortAllocator.allocatePorts(2);
Something s = doSomething(
- "test_01",
- "-Dcom.sun.management.jmxremote.port=" + pa.getPort1(),
- "-Dcom.sun.management.jmxremote.authenticate=false",
- "-Dcom.sun.management.jmxremote.ssl=false");
+ "test_01",
+ "-Dcom.sun.management.jmxremote.port=" + ports[0],
+ "-Dcom.sun.management.jmxremote.authenticate=false",
+ "-Dcom.sun.management.jmxremote.ssl=false");
try {
- testConnect(pa.getPort1());
+ testConnect(ports[0]);
jcmd(CMD_STOP);
- testNoConnect(pa.getPort1());
+ testNoConnect(ports[0]);
- jcmd(CMD_START, "jmxremote.port=" + pa.getPort2());
- testConnect(pa.getPort2());
+ jcmd(CMD_START, "jmxremote.port=" + ports[1]);
+ testConnect(ports[1]);
} finally {
s.stop();
}
@@ -479,15 +513,15 @@
System.out.println("**** Test two ****");
+ int[] ports = PortAllocator.allocatePorts(1);
Something s = doSomething("test_02");
- PortAllocator pa = new PortAllocator();
try {
jcmd(CMD_START,
- "jmxremote.port=" + pa.getPort1(),
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false");
- testConnect(pa.getPort1());
+ testConnect(ports[0]);
} finally {
// debugPortUsage(pa);
s.stop();
@@ -500,25 +534,25 @@
System.out.println("**** Test three ****");
+ int[] ports = PortAllocator.allocatePorts(2);
Something s = doSomething("test_03");
- PortAllocator pa = new PortAllocator();
try {
jcmd(CMD_START,
- "jmxremote.port=" + pa.getPort1(),
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false");
// Second agent shouldn't start
jcmd(CMD_START,
- "jmxremote.port=" + pa.getPort2(),
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ "jmxremote.port=" + ports[1],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false");
// First agent should connect
- testConnect(pa.getPort1());
+ testConnect(ports[0]);
// Second agent should not connect
- testNoConnect(pa.getPort2());
+ testNoConnect(ports[1]);
} finally {
s.stop();
}
@@ -530,16 +564,16 @@
System.out.println("**** Test four ****");
+ int[] ports = PortAllocator.allocatePorts(2);
Something s = doSomething("test_04");
- PortAllocator pa = new PortAllocator();
try {
jcmd(CMD_START,
- "jmxremote.port=" + pa.getPort1(),
- "jmxremote.rmi.port=" + pa.getPort2(),
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ "jmxremote.port=" + ports[0],
+ "jmxremote.rmi.port=" + ports[1],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false");
- testConnect(pa.getPort1(), pa.getPort2());
+ testConnect(ports[0], ports[1]);
} finally {
s.stop();
}
@@ -550,13 +584,12 @@
// but should leave remote server disabled
System.out.println("**** Test five ****");
-
+ int[] ports = PortAllocator.allocatePorts(1);
Something s = doSomething("test_05");
- PortAllocator pa = new PortAllocator();
try {
jcmd(CMD_START_LOCAL);
- testNoConnect(pa.getPort1());
+ testNoConnect(ports[0]);
testConnectLocal(s.getPid());
} finally {
s.stop();
@@ -566,94 +599,36 @@
static void test_06() throws Exception {
// Run an app without JMX enabled
// start JMX by jcmd on one port, specify rmi port explicitly
- // attempt to start it again
- // 1) with the same port
- // 2) with other port
- // 3) attempt to stop it twice
+ // attempt to start it again with the same port
// Check for valid messages in the output
System.out.println("**** Test six ****");
+ int[] ports = PortAllocator.allocatePorts(2);
Something s = doSomething("test_06");
- PortAllocator pa = new PortAllocator();
try {
jcmd(CMD_START,
- "jmxremote.port=" + pa.getPort1(),
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
-
- testConnect(pa.getPort1(), pa.getPort2());
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false");
- final AtomicInteger checks = new AtomicInteger();
- jcmd(
- line -> {
- if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
- checks.getAndUpdate((op) -> op | 1);
- }
- },
- CMD_START,
- "jmxremote.port=" + pa.getPort1(),
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
-
- jcmd(
- line -> {
- if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
- checks.getAndUpdate((op) -> op | 2);
- }
- },
- CMD_START,
- "jmxremote.port=" + pa.getPort2(),
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
-
- jcmd(CMD_STOP);
- jcmd(CMD_STOP);
+ testConnect(ports[0], ports[1]);
- int busyPort;
- try (ServerSocket ss = new ServerSocket(0))
- {
- busyPort = ss.getLocalPort();
- int retryCntr = 1;
- do {
- final boolean[] retry = new boolean[]{false};
- jcmd(
- line -> {
- boolean match = line.contains("Port already in use: " +
- busyPort);
- System.out.println("[match] " + line + " => " + match);
- if (match) {
- checks.getAndUpdate((op) -> op | 4);
- retry[0] = false;
- } else if (line.contains("Exception thrown by the agent")) {
- retry[0] = true;
- }
- },
- CMD_START,
- "jmxremote.port=" + ss.getLocalPort(),
- "jmxremote.rmi.port=" + pa.getPort2(),
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false"
- );
- if (!retry[0]) {
- break;
- }
- System.out.println("Attempt " + retryCntr + " >>>");
- System.out.println("Unexpected reply from the agent. Retrying in 500ms ...");
- Thread.sleep(500);
- } while (retryCntr++ < 10);
- }
- if ((checks.get() & 1) == 0) {
- throw new Exception("Starting agent on port " + pa.getPort1() + " should " +
- "report an invalid agent state");
- }
- if ((checks.get() & 2) == 0) {
- throw new Exception("Starting agent on poprt " + pa.getPort2() + " should " +
- "report an invalid agent state");
- }
- if ((checks.get() & 4) == 0) {
- throw new Exception("Starting agent on port " + busyPort + " should " +
- "report port in use");
+ final AtomicBoolean checks = new AtomicBoolean(false);
+ jcmd(
+ line -> {
+ if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
+ checks.set(true);
+ }
+ },
+ CMD_START,
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false");
+
+ if (!checks.get()) {
+ throw new Exception("Starting agent on port " + ports[0] + " should "
+ + "report an invalid agent state");
}
} finally {
s.stop();
@@ -661,68 +636,188 @@
}
static void test_07() throws Exception {
- // Run an app without JMX enabled, but with some properties set
- // in command line.
- // make sure these properties overridden corectly
+ // Run an app without JMX enabled
+ // start JMX by jcmd on one port, specify rmi port explicitly
+ // attempt to start it again with other port
+ // Check for valid messages in the output
System.out.println("**** Test seven ****");
- Something s = doSomething(
- "test_07",
- "-Dcom.sun.management.jmxremote.authenticate=false",
- "-Dcom.sun.management.jmxremote.ssl=true");
- PortAllocator pa = new PortAllocator();
-
+ int[] ports = PortAllocator.allocatePorts(2);
+ Something s = doSomething("test_07");
try {
- testNoConnect(pa.getPort1());
+ jcmd(CMD_START,
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false");
+
+ testConnect(ports[0], ports[1]);
+
+ final AtomicBoolean checks = new AtomicBoolean(false);
+
jcmd(
- CMD_START,
- "jmxremote.port=" + pa.getPort2(),
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false"
- );
- testConnect(pa.getPort2());
+ line -> {
+ if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
+ checks.set(true);
+ }
+ },
+ CMD_START,
+ "jmxremote.port=" + ports[1],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false");
+
+ if (!checks.get()) {
+ throw new Exception("Starting agent on poprt " + ports[1] + " should "
+ + "report an invalid agent state");
+ }
} finally {
s.stop();
}
}
static void test_08() throws Exception {
- // Run an app with JMX enabled and with some properties set
- // in command line.
- // stop JMX agent and then start it again with different property values
- // make sure these properties overridden corectly
+ // Run an app without JMX enabled
+ // start JMX by jcmd on one port, specify rmi port explicitly
+ // attempt to stop it twice
+ // Check for valid messages in the output
System.out.println("**** Test eight ****");
- PortAllocator pa = new PortAllocator();
- Something s = doSomething(
- "test_08",
- "-Dcom.sun.management.jmxremote.port=" + pa.getPort1(),
- "-Dcom.sun.management.jmxremote.authenticate=false",
- "-Dcom.sun.management.jmxremote.ssl=true");
+ int[] ports = PortAllocator.allocatePorts(2);
+ Something s = doSomething("test_08");
+ try {
+ jcmd(CMD_START,
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false");
- try {
- testNoConnect(pa.getPort1());
+ testConnect(ports[0], ports[1]);
jcmd(CMD_STOP);
-
- testNoConnect(pa.getPort1());
-
- jcmd(
- CMD_START,
- "jmxremote.port=" + pa.getPort2(),
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false"
- );
-
- testConnect(pa.getPort2());
+ jcmd(CMD_STOP);
} finally {
s.stop();
}
}
static void test_09() throws Exception {
+ // Run an app without JMX enabled
+ // attempt to start JMX using a non-available port
+ // Check for valid messages in the output
+
+ System.out.println("**** Test nine ****");
+
+ Something s = doSomething("test_09");
+
+ try (ServerSocket ss = new ServerSocket(0)) {
+ int localPort = ss.getLocalPort();
+ int[] ports;
+ do {
+ ports = PortAllocator.allocatePorts(1);
+ } while (localPort == ports[0]);
+
+ final AtomicBoolean checks = new AtomicBoolean(false);
+
+ int retryCntr = 1;
+ do {
+ final AtomicBoolean retry = new AtomicBoolean(false);
+
+ try {
+ jcmd(
+ line -> {
+ if (line.contains(Agent.getText(AgentConfigurationError.AGENT_EXCEPTION))) {
+ retry.set(true);
+ }
+ },
+ CMD_START,
+ "jmxremote.port=" + ports[0],
+ "jmxremote.rmi.port=" + localPort,
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
+ } catch (BindException e) {
+ checks.set(true);
+ }
+ if (!retry.get()) {
+ break;
+ }
+ System.out.println("Attempt " + retryCntr + " >>>");
+ System.out.println("Unexpected reply from the agent. Retrying in 500ms ...");
+ Thread.sleep(500);
+ } while (retryCntr++ < 10);
+
+ if (!checks.get()) {
+ throw new Exception("Starting agent on port " + ports[0] + " should "
+ + "report port in use");
+ }
+ } finally {
+ s.stop();
+ }
+
+ }
+
+ static void test_10() throws Exception {
+ // Run an app without JMX enabled, but with some properties set
+ // in command line.
+ // make sure these properties overridden corectly
+
+ System.out.println("**** Test ten ****");
+
+ int[] ports = PortAllocator.allocatePorts(2);
+ Something s = doSomething(
+ "test_10",
+ "-Dcom.sun.management.jmxremote.authenticate=false",
+ "-Dcom.sun.management.jmxremote.ssl=true");
+
+ try {
+ testNoConnect(ports[0]);
+ jcmd(
+ CMD_START,
+ "jmxremote.port=" + ports[1],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
+ testConnect(ports[1]);
+ } finally {
+ s.stop();
+ }
+ }
+
+ static void test_11() throws Exception {
+ // Run an app with JMX enabled and with some properties set
+ // in command line.
+ // stop JMX agent and then start it again with different property values
+ // make sure these properties overridden corectly
+
+ System.out.println("**** Test eleven ****");
+ int[] ports = PortAllocator.allocatePorts(2);
+ Something s = doSomething(
+ "test_11",
+ "-Dcom.sun.management.jmxremote.port=" + ports[0],
+ "-Dcom.sun.management.jmxremote.authenticate=false",
+ "-Dcom.sun.management.jmxremote.ssl=true");
+
+ try {
+ testNoConnect(ports[0]);
+
+ jcmd(CMD_STOP);
+
+ testNoConnect(ports[0]);
+
+ jcmd(
+ CMD_START,
+ "jmxremote.port=" + ports[1],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
+
+ testConnect(ports[1]);
+ } finally {
+ s.stop();
+ }
+ }
+
+ static void test_12() throws Exception {
// Run an app with JMX enabled and with some properties set
// in command line.
// stop JMX agent and then start it again with different property values
@@ -730,87 +825,85 @@
// in command line
// make sure these properties overridden corectly
- System.out.println("**** Test nine ****");
+ System.out.println("**** Test twelve ****");
- Something s = doSomething("test_09",
- "-Dcom.sun.management.config.file=" +
- TEST_SRC + File.separator + "management_cl.properties",
- "-Dcom.sun.management.jmxremote.authenticate=false"
+ int[] ports = PortAllocator.allocatePorts(2);
+ Something s = doSomething("test_12",
+ "-Dcom.sun.management.config.file="
+ + TEST_SRC + File.separator + "management_cl.properties",
+ "-Dcom.sun.management.jmxremote.authenticate=false"
);
- PortAllocator pa = new PortAllocator();
try {
- testNoConnect(pa.getPort1());
+ testNoConnect(ports[0]);
jcmd(CMD_STOP);
- testNoConnect(pa.getPort1());
+ testNoConnect(ports[0]);
jcmd(CMD_START,
- "config.file=" + TEST_SRC + File.separator +
- "management_jcmd.properties",
- "jmxremote.authenticate=false",
- "jmxremote.port=" + pa.getPort2()
+ "config.file=" + TEST_SRC + File.separator
+ + "management_jcmd.properties",
+ "jmxremote.authenticate=false",
+ "jmxremote.port=" + ports[1]
);
- testConnect(pa.getPort2());
+ testConnect(ports[1]);
} finally {
s.stop();
}
}
- static void test_10() throws Exception {
+ static void test_13() throws Exception {
// Run an app with JMX enabled and with some properties set
// in command line.
// stop JMX agent and then start it again with different property values
// stop JMX agent again and then start it without property value
// make sure these properties overridden corectly
- System.out.println("**** Test ten ****");
- PortAllocator pa = new PortAllocator();
-
+ System.out.println("**** Test thirteen ****");
+ int[] ports = PortAllocator.allocatePorts(1);
Something s = doSomething(
- "test_10",
- "-Dcom.sun.management.jmxremote.port=" + pa.getPort1(),
- "-Dcom.sun.management.jmxremote.authenticate=false",
- "-Dcom.sun.management.jmxremote.ssl=true");
+ "test_13",
+ "-Dcom.sun.management.jmxremote.port=" + ports[0],
+ "-Dcom.sun.management.jmxremote.authenticate=false",
+ "-Dcom.sun.management.jmxremote.ssl=true");
try {
- testNoConnect(pa.getPort1());
+ testNoConnect(ports[0]);
jcmd(CMD_STOP);
jcmd(CMD_START,
- "jmxremote.ssl=false",
- "jmxremote.port=" + pa.getPort1()
+ "jmxremote.ssl=false",
+ "jmxremote.port=" + ports[0]
);
- testConnect(pa.getPort1());
+ testConnect(ports[0]);
jcmd(CMD_STOP);
jcmd(CMD_START,
- "jmxremote.port=" + pa.getPort1()
+ "jmxremote.port=" + ports[0]
);
- testNoConnect(pa.getPort1());
+ testNoConnect(ports[0]);
} finally {
s.stop();
}
}
- static void test_11() throws Exception {
+ static void test_14() throws Exception {
// Run an app with JMX enabled
// stop remote agent
// make sure local agent is not affected
- System.out.println("**** Test eleven ****");
- PortAllocator pa = new PortAllocator();
-
+ System.out.println("**** Test fourteen ****");
+ int[] ports = PortAllocator.allocatePorts(1);
Something s = doSomething(
- "test_11",
- "-Dcom.sun.management.jmxremote.port=" + pa.getPort1(),
- "-Dcom.sun.management.jmxremote.authenticate=false",
- "-Dcom.sun.management.jmxremote.ssl=false");
+ "test_14",
+ "-Dcom.sun.management.jmxremote.port=" + ports[0],
+ "-Dcom.sun.management.jmxremote.authenticate=false",
+ "-Dcom.sun.management.jmxremote.ssl=false");
try {
- testConnect(pa.getPort1());
+ testConnect(ports[0]);
jcmd(CMD_STOP);
testConnectLocal(s.getPid());
} finally {
@@ -818,17 +911,17 @@
}
}
- static void test_12() throws Exception {
+ static void test_15() throws Exception {
// Run an app with JMX disabled
// start local agent only
- System.out.println("**** Test twelve ****");
+ System.out.println("**** Test fifteen ****");
- Something s = doSomething("test_12");
- PortAllocator pa = new PortAllocator();
+ int[] ports = PortAllocator.allocatePorts(1);
+ Something s = doSomething("test_15");
try {
- testNoConnect(pa.getPort1());
+ testNoConnect(ports[0]);
jcmd(CMD_START + "_local");
testConnectLocal(s.getPid());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/nio/cs/StreamEncoderOut.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ @bug 8030179
+ @summary test if the charset encoder deails with surrogate correctly
+ * @run testng/othervm -esa StreamEncoderOut
+ */
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.charset.Charset;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.joining;
+
+@Test
+public class StreamEncoderOut {
+
+ enum Input {
+ HIGH("\ud834"),
+ LOW("\udd1e"),
+ HIGH_LOW("\ud834\udd1e");
+
+ final String value;
+
+ Input(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return name() + " : \'" + value + "\"";
+ }
+ }
+
+ @DataProvider(name = "CharsetAndString")
+ // [Charset, Input]
+ public static Object[][] makeStreamTestData() {
+ // Cross product of supported charsets and inputs
+ return Charset.availableCharsets().values().stream().
+ filter(Charset::canEncode).
+ flatMap(cs -> Stream.of(Input.values()).map(i -> new Object[]{cs, i})).
+ toArray(Object[][]::new);
+ }
+
+ private static String generate(String s, int n) {
+ return Stream.generate(() -> s).limit(n).collect(joining());
+ }
+
+ static final OutputStream DEV_NULL = new OutputStream() {
+ @Override
+ public void write(byte b[], int off, int len) throws IOException {}
+
+ @Override
+ public void write(int b) throws IOException {}
+ };
+
+ @Test(dataProvider = "CharsetAndString")
+ public void test(Charset cs, Input input) throws IOException {
+ OutputStreamWriter w = new OutputStreamWriter(DEV_NULL, cs);
+ String t = generate(input.value, 8193);
+ for (int i = 0; i < 10; i++) {
+ w.append(t);
+ }
+ }
+}
--- a/jdk/test/sun/security/util/HostnameMatcher/TestHostnameChecker.java Thu Feb 12 16:23:24 2015 -0800
+++ b/jdk/test/sun/security/util/HostnameMatcher/TestHostnameChecker.java Wed Jul 05 20:19:27 2017 +0200
@@ -187,6 +187,9 @@
in = new FileInputStream(new File(PATH, "cert4.crt"));
X509Certificate cert4 = (X509Certificate)cf.generateCertificate(in);
in.close();
+ in = new FileInputStream(new File(PATH, "cert5.crt"));
+ X509Certificate cert5 = (X509Certificate)cf.generateCertificate(in);
+ in.close();
HostnameChecker checker = HostnameChecker.getInstance(
HostnameChecker.TYPE_TLS);
@@ -202,6 +205,9 @@
check(checker, "5.6.7.8", cert3, true);
check(checker, "foo.bar.com", cert4, true);
check(checker, "altfoo.bar.com", cert4, true);
+ check(checker, "2001:db8:3c4d:15::1a2f:1a2b", cert5, true);
+ check(checker, "2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b", cert5, true);
+ check(checker, "2002:db8:3c4d:15::1a2f:1a2b", cert5, false);
checker = HostnameChecker.getInstance(
HostnameChecker.TYPE_LDAP);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/util/HostnameMatcher/cert5.crt Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIIECDCCAvCgAwIBAgIJAJaBmuUlfY8sMA0GCSqGSIb3DQEBBQUAMIGmMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTESMBAGA1UEBwwJU29tZS1DaXR5
+MSowKAYDVQQKDCFVbmNvbmZpZ3VyZWQgT3BlblNTTCBJbnN0YWxsYXRpb24xEDAO
+BgNVBAsMB3NlY3Rpb24xMDAuBgNVBAMMJzIwMDE6MGRiODozYzRkOjAwMTU6MDAw
+MDowMDAwOjFhMmY6MWEyYjAeFw0xNTAyMTAxODMzMjBaFw0xNTAzMTIxODMzMjBa
+MIGmMQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTESMBAGA1UEBwwJ
+U29tZS1DaXR5MSowKAYDVQQKDCFVbmNvbmZpZ3VyZWQgT3BlblNTTCBJbnN0YWxs
+YXRpb24xEDAOBgNVBAsMB3NlY3Rpb24xMDAuBgNVBAMMJzIwMDE6MGRiODozYzRk
+OjAwMTU6MDAwMDowMDAwOjFhMmY6MWEyYjCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAMcigWxmeF6Dmo3xAw3y/8d3vB8Th4YsmvwXb9DxwNWV+B3vxJgq
+ww6T6VBxrle1bgu/RtZDJwLf5vMhVElxuuE86di2qyurKFbpe29C9xnCxuMlXpje
+X2pNknz4ZzOqD4opmIAFjXZ2Xp1kLt+HJX7ABoz7Uga+IbVfDRPPf2KOqYNpBQkp
+dgI5VOZDQNVNb+8vdXDwyanMQ0TgPXKL4BQIkGB4RM8sgpPMUvB+tEB7zmUtgSco
+2a5M84wIhxv85CmFFoTVSzXsRCDhVAZj0aHRkkmAsMSmzPa4HiPnuVRV740oQjDy
+oMGLndaEs2nxIqckUFHOHcSTf0/wmcvPbIsCAwEAAaM3MDUwCQYDVR0TBAIwADAL
+BgNVHQ8EBAMCBeAwGwYDVR0RBBQwEocQIAENuDxNABUAAAAAGi8aKzANBgkqhkiG
+9w0BAQUFAAOCAQEAtnelRbYPPZRgTd4oxOiPqwc01EE9JgtkFWlooCwVUDChOR2k
+us1qlhKsvbN2Tcsm1Ss3p0Uxk/g1o2/mY8rA/dJ8qiN6jbfjpEi8b2MirP5tQSE0
+QNXbVGr5FnLbuUmn+82pB0vBSaq7gxehbV6S7dteyQUnb2imltC5wS9PwYb8wWx7
+IpyXWt0jkYkC8KJEevVYI7qtwpjYhyc1FqwzUiPmdqGz2AFLQ4RgTXJi93SPoyKM
+s65oPV+r6/0qwnslScxVfszHxxFn1Yfsc5Oseare1MnlNzH69PmWs523C/fBvnB2
+MsHKLPdoN7uSpBLB7j46g5jQG/ceri/cquZKYA==
+-----END CERTIFICATE-----
--- a/make/Main.gmk Thu Feb 12 16:23:24 2015 -0800
+++ b/make/Main.gmk Wed Jul 05 20:19:27 2017 +0200
@@ -212,7 +212,7 @@
@$(RM) $@
@$(call GetSourceTips)
-BOOTCYCLE_TARGET := images
+BOOTCYCLE_TARGET := product-images
bootcycle-images:
@$(ECHO) Boot cycle build step 2: Building a new JDK image using previously built image
+$(MAKE) $(MAKE_ARGS) -f Main.gmk SPEC=$(dir $(SPEC))bootcycle-spec.gmk $(BOOTCYCLE_TARGET)
@@ -443,31 +443,45 @@
ALL_MODULE_TARGETS := $(sort $(GENSRC_MODULES) $(JAVA_MODULES) \
$(GENDATA_MODULES) $(LIBS_MODULES) $(LAUNCHER_MODULES) $(COPY_MODULES))
+# The "exploded image" is a locally runnable JDK in $(BUILD_OUTPUT)/jdk.
exploded-image: $(ALL_MODULE_TARGETS)
-# The old 'jdk' target most closely matches the new exploded-image. Keep an
-# alias for ease of use.
-jdk: exploded-image
+
+# The $(BUILD_OUTPUT)/images directory contain the resulting deliverables,
+# and in line with this, our targets for creating these are named *-image[s].
-images: test-image jimages demos samples zip-security verify-modules
+# This target builds the product images, e.g. the JRE and JDK image
+# (and possibly other, more specific versions)
+product-images: jimages demos samples zip-security verify-modules
ifeq ($(OPENJDK_TARGET_OS), macosx)
- images: mac-bundles
+ product-images: mac-bundles
endif
-docs: docs-javadoc docs-jvmtidoc
+# This target builds the documentation image
+docs-image: docs-javadoc docs-jvmtidoc
+# This target builds the test image
test-image: prepare-test-image
+# all-images is the top-most target, it builds all our deliverables ("images").
+all-images: product-images test-image docs-image
+
ALL_TARGETS += buildtools gensrc gendata copy java rmic libs launchers \
- jdk.jdwp.agent-gensrc $(ALL_MODULE_TARGETS) exploded-image jdk images \
- docs test-image
+ jdk.jdwp.agent-gensrc $(ALL_MODULE_TARGETS) exploded-image \
+ product-images docs-image test-image all-images
################################################################################
-all: images
+# Traditional targets typically run by users.
+# These can be considered aliases for the targets now named by a more
+# "modern" naming scheme.
default: exploded-image
+jdk: exploded-image
+images: product-images
+docs: docs-image
+all: all-images
-ALL_TARGETS += default all
+ALL_TARGETS += default jdk images docs all
################################################################################
################################################################################
@@ -553,7 +567,8 @@
else
@$(ECHO) "Re-running configure using default settings"
endif
- @( cd $(OUTPUT_ROOT) && $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) )
+ @( cd $(OUTPUT_ROOT) && PATH="$(ORIGINAL_PATH)" \
+ $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) )
ALL_TARGETS += reconfigure
--- a/make/StripBinaries.gmk Thu Feb 12 16:23:24 2015 -0800
+++ b/make/StripBinaries.gmk Wed Jul 05 20:19:27 2017 +0200
@@ -53,7 +53,7 @@
endif
# Don't include debug info for executables.
-ALL_CMDS_SRC := $(filter-out %.debuginfo %.diz %.map %.pdb, \
+ALL_CMDS_SRC := $(filter-out %.bc %.debuginfo %.diz %.map %.pdb, \
$(shell $(FIND) $(SUPPORT_OUTPUTDIR)/modules_cmds -type f -o -type l))
COPY_CMDS_SRC := $(filter %.cgi, $(ALL_CMDS_SRC))
STRIP_CMDS_SRC := $(filter-out $(COPY_CMDS_SRC), $(ALL_CMDS_SRC))
--- a/make/common/NativeCompilation.gmk Thu Feb 12 16:23:24 2015 -0800
+++ b/make/common/NativeCompilation.gmk Wed Jul 05 20:19:27 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -53,6 +53,8 @@
UNIX_PATH_PREFIX :=
endif
+# This pattern is used to transform the output of the microsoft CL compiler
+# into a make syntax dependency file (.d)
WINDOWS_SHOWINCLUDE_SED_PATTERN := \
-e '/^Note: including file:/!d' \
-e 's|Note: including file: *||' \
@@ -62,6 +64,16 @@
-e 's|$$$$| \\|g' \
#
+# This pattern is used to transform a dependency file (.d) to a list
+# of make targets for dependent files (.d.targets)
+DEPENDENCY_TARGET_SED_PATTERN := \
+ -e 's/\#.*//' \
+ -e 's/^[^:]*: *//' \
+ -e 's/ *\\$$$$//' \
+ -e '/^$$$$/ d' \
+ -e 's/$$$$/ :/' \
+ #
+
define add_native_source
# param 1 = BUILD_MYPACKAGE
# parma 2 = the source file name (..../alfa.c or .../beta.cpp)
@@ -75,12 +87,12 @@
ifneq (,$$(filter %.c,$2))
# Compile as a C file
- $1_$2_FLAGS=$4 $$($1_$(notdir $2)_CFLAGS) -DTHIS_FILE='"$$(<F)"' -c
+ $1_$2_FLAGS=$(CFLAGS_CCACHE) $4 $$($1_$(notdir $2)_CFLAGS) -DTHIS_FILE='"$$(<F)"' -c
$1_$2_COMP=$5
$1_$2_DEP_FLAG:=$(C_FLAG_DEPS)
else ifneq (,$$(filter %.m,$2))
# Compile as a objective-c file
- $1_$2_FLAGS=-x objective-c $4 $$($1_$(notdir $2)_CFLAGS) -DTHIS_FILE='"$$(<F)"' -c
+ $1_$2_FLAGS=-x objective-c $(CFLAGS_CCACHE) $4 $$($1_$(notdir $2)_CFLAGS) -DTHIS_FILE='"$$(<F)"' -c
$1_$2_COMP=$8
$1_$2_DEP_FLAG:=$(C_FLAG_DEPS)
else ifneq (,$$(filter %.s,$2))
@@ -90,7 +102,7 @@
$1_$2_DEP_FLAG:=
else ifneq (,$$(filter %.cpp,$2)$$(filter %.mm,$2))
# Compile as a C++ file
- $1_$2_FLAGS=$6 $$($1_$(notdir $2)_CXXFLAGS) -DTHIS_FILE='"$$(<F)"' -c
+ $1_$2_FLAGS=$(CFLAGS_CCACHE) $6 $$($1_$(notdir $2)_CXXFLAGS) -DTHIS_FILE='"$$(<F)"' -c
$1_$2_COMP=$7
$1_$2_DEP_FLAG:=$(CXX_FLAG_DEPS)
else
@@ -105,8 +117,13 @@
ifeq (,$$(filter %.s,$2))
# And this is the dependency file for this obj file.
$1_$2_DEP:=$$(patsubst %$(OBJ_SUFFIX),%.d,$$($1_$2_OBJ))
+ # The dependency target file lists all dependencies as empty targets
+ # to avoid make error "No rule to make target" for removed files
+ $1_$2_DEP_TARGETS:=$$(patsubst %$(OBJ_SUFFIX),%.d.targets,$$($1_$2_OBJ))
+
# Include previously generated dependency information. (if it exists)
-include $$($1_$2_DEP)
+ -include $$($1_$2_DEP_TARGETS)
ifeq ($(TOOLCHAIN_TYPE), microsoft)
$1_$2_DEBUG_OUT_FLAGS:=-Fd$$(patsubst %$(OBJ_SUFFIX),%.pdb,$$($1_$2_OBJ)) \
@@ -139,6 +156,11 @@
($(ECHO) $$@: \\ \
&& $(SED) $(WINDOWS_SHOWINCLUDE_SED_PATTERN) $$($1_$2_DEP).raw) > $$($1_$2_DEP)
endif
+ # Create a dependency target file from the dependency file.
+ # Solution suggested by http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
+ ifneq ($$($1_$2_DEP),)
+ $(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_$2_DEP) > $$($1_$2_DEP_TARGETS)
+ endif
endif
endef
@@ -428,7 +450,7 @@
$1_BUILD_INFO := $$($1_OBJECT_DIR)/_build-info.marker
# Track variable changes for all variables that affect the compilation command
- # lines for all object files in this setup. This includes at least all the
+ # lines for all object files in this setup. This includes at least all the
# variables used in the call to add_native_source below.
$1_COMPILE_VARDEPS := $$($1_CFLAGS) $$($1_EXTRA_CFLAGS) $(SYSROOT_CFLAGS) \
$$($1_CXXFLAGS) $$($1_EXTRA_CXXFLAGS) \
@@ -452,7 +474,10 @@
ifeq ($$(wildcard $$($1_TARGET)),)
$(ECHO) 'Creating $$($1_BASENAME) from $$(words $$(filter-out %.vardeps, $$?)) file(s)'
else
- $(ECHO) 'Updating $$($1_BASENAME) from $$(words $$(filter-out %.vardeps, $$?)) file(s)'
+ $(ECHO) $$(strip 'Updating $$($1_BASENAME)' \
+ $$(if $$(filter-out %.vardeps, $$?), \
+ 'from $$(words $$(filter-out %.vardeps, $$?)) file(s)') \
+ $$(if $$(filter %.vardeps, $$?), 'due to makefile changes'))
endif
$(TOUCH) $$@
@@ -461,7 +486,9 @@
ifneq (,$$($1_VERSIONINFO_RESOURCE))
$1_RES:=$$($1_OBJECT_DIR)/$$($1_BASENAME).res
$1_RES_DEP:=$$($1_RES).d
+ $1_RES_DEP_TARGETS:=$$($1_RES).d.targets
-include $$($1_RES_DEP)
+ -include $$($1_RES_DEP_TARGETS)
$1_RES_VARDEPS := $(RC) $$($1_RC_FLAGS)
$1_RES_VARDEPS_FILE := $$(call DependOnVariable, $1_RES_VARDEPS, \
@@ -469,12 +496,14 @@
$$($1_RES): $$($1_VERSIONINFO_RESOURCE) $$($1_RES_VARDEPS_FILE)
$(ECHO) $(LOG_INFO) "Compiling resource $$(notdir $$($1_VERSIONINFO_RESOURCE)) (for $$(notdir $$($1_TARGET)))"
- $(RC) $$($1_RC_FLAGS) $(CC_OUT_OPTION)$$@ $$($1_VERSIONINFO_RESOURCE)
+ $(RC) $$($1_RC_FLAGS) $(SYSROOT_CFLAGS) $(CC_OUT_OPTION)$$@ \
+ $$($1_VERSIONINFO_RESOURCE)
# Windows RC compiler does not support -showIncludes, so we mis-use CL for this.
- $(CC) $$($1_RC_FLAGS) -showIncludes -nologo -TC \
+ $(CC) $$($1_RC_FLAGS) $(SYSROOT_CFLAGS) -showIncludes -nologo -TC \
$(CC_OUT_OPTION)$$($1_RES_DEP).obj $$($1_VERSIONINFO_RESOURCE) > $$($1_RES_DEP).raw 2>&1 || exit 0
($(ECHO) $$($1_RES): \\ \
&& $(SED) $(WINDOWS_SHOWINCLUDE_SED_PATTERN) $$($1_RES_DEP).raw) > $$($1_RES_DEP)
+ $(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_RES_DEP) > $$($1_RES_DEP_TARGETS)
endif
ifneq (,$$($1_MANIFEST))
$1_GEN_MANIFEST:=$$($1_OBJECT_DIR)/$$($1_PROGRAM).manifest
--- a/nashorn/.hgtags Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/.hgtags Wed Jul 05 20:19:27 2017 +0200
@@ -283,3 +283,4 @@
29046d42a95e5b9f105ab086a628bbd7f81c915d jdk9-b47
f08660f30051ba0b38ad00e692979b37d107c9c4 jdk9-b48
2ae58b5f05f803a469f0f6c1ed72c6b5313f4ff0 jdk9-b49
+32e48a0d59e186df8a041e1e5f8bfb0b8d2bc4cd jdk9-b50
--- a/nashorn/make/build.xml Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/make/build.xml Wed Jul 05 20:19:27 2017 +0200
@@ -504,7 +504,7 @@
<testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
- <jvmarg line="${ext.class.path}"/>
+ <jvmarg line="${boot.class.path}"/>
<jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} -Dbuild.dir=${build.dir}"/>
<propertyset>
<propertyref prefix="testjfx-test-sys-prop."/>
@@ -524,7 +524,7 @@
<testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
- <jvmarg line="${ext.class.path}"/>
+ <jvmarg line="${boot.class.path}"/>
<jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -Dbuild.dir=${build.dir}"/>
<propertyset>
<propertyref prefix="testmarkdown-test-sys-prop."/>
@@ -543,7 +543,7 @@
<testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
- <jvmarg line="${ext.class.path}"/>
+ <jvmarg line="${boot.class.path}"/>
<jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -Dbuild.dir=${build.dir}"/>
<propertyset>
<propertyref prefix="nashorn."/>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/samples/getclassnpe.js Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,122 @@
+#// Usage: jjs getclassnpe.js -- <directory>
+
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * java.lang.Object.getClass() is sometimes used to do null check. This
+ * obfuscating Object.getClass() check relies on non-related intrinsic
+ * performance, which is potentially not available everywhere.
+ * See also http://cr.openjdk.java.net/~shade/scratch/NullChecks.java
+ * This nashorn script checks for such uses in your .java files in the
+ * given directory (recursively).
+ */
+
+if (arguments.length == 0) {
+ print("Usage: jjs getclassnpe.js -- <directory>");
+ exit(1);
+}
+
+// Java types used
+var File = Java.type("java.io.File");
+var Files = Java.type("java.nio.file.Files");
+var StringArray = Java.type("java.lang.String[]");
+var ToolProvider = Java.type("javax.tools.ToolProvider");
+var MethodInvocationTree = Java.type("com.sun.source.tree.MethodInvocationTree");
+var TreeScanner = Java.type("com.sun.source.util.TreeScanner");
+
+// parse a specific .java file to check if it uses
+// Object.getClass() for null check.
+function checkGetClassNPE() {
+ // get the system compiler tool
+ var compiler = ToolProvider.systemJavaCompiler;
+ // get standard file manager
+ var fileMgr = compiler.getStandardFileManager(null, null, null);
+ // Using Java.to convert script array (arguments) to a Java String[]
+ var compUnits = fileMgr.getJavaFileObjects(
+ Java.to(arguments, StringArray));
+ // create a new compilation task
+ var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);
+ // subclass SimpleTreeVisitor - to check for obj.getClass(); statements
+ var GetClassNPEChecker = Java.extend(TreeScanner);
+
+ var visitor = new GetClassNPEChecker() {
+ lineMap: null,
+ sourceFile: null,
+
+ // save compilation unit details for reporting
+ visitCompilationUnit: function(node, p) {
+ this.sourceFile = node.sourceFile;
+ this.lineMap = node.lineMap;
+ return Java.super(visitor).visitCompilationUnit(node, p);
+ },
+
+ // look for "foo.getClass();" expression statements
+ visitExpressionStatement: function(node, p) {
+ var expr = node.expression;
+ if (expr instanceof MethodInvocationTree) {
+ var name = String(expr.methodSelect.identifier);
+
+ // will match any "getClass" call with zero arguments!
+ if (name == "getClass" && expr.arguments.size() == 0) {
+ print(this.sourceFile.getName()
+ + " @ "
+ + this.lineMap.getLineNumber(node.pos)
+ + ":"
+ + this.lineMap.getColumnNumber(node.pos));
+
+ print("\t", node);
+ }
+ }
+ }
+ }
+
+ for each (var cu in task.parse()) {
+ cu.accept(visitor, null);
+ }
+}
+
+// for each ".java" file in the directory (recursively)
+function main(dir) {
+ Files.walk(dir.toPath()).
+ forEach(function(p) {
+ var name = p.toFile().absolutePath;
+ if (name.endsWith(".java")) {
+ try {
+ checkGetClassNPE(p.toFile().getAbsolutePath());
+ } catch (e) {
+ print(e);
+ }
+ }
+ });
+}
+
+main(new File(arguments[0]));
--- a/nashorn/samples/javashell.js Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/samples/javashell.js Wed Jul 05 20:19:27 2017 +0200
@@ -40,7 +40,6 @@
var Arrays = Java.type("java.util.Arrays");
var BufferedReader = Java.type("java.io.BufferedReader");
var FileWriter = Java.type("java.io.FileWriter");
-var List = Java.type("java.util.List");
var LocalDateTime = Java.type("java.time.LocalDateTime");
var InputStreamReader = Java.type("java.io.InputStreamReader");
var PrintWriter = Java.type("java.io.PrintWriter");
@@ -122,7 +121,7 @@
// execute code command
function exec(args) {
// build child process and start it!
- new ProcessBuilder(Java.to(args.split(' '), List))
+ new ProcessBuilder(Arrays.asList(args.split(' ')))
.inheritIO()
.start()
.waitFor();
--- a/nashorn/samples/shell.js Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/samples/shell.js Wed Jul 05 20:19:27 2017 +0200
@@ -42,7 +42,6 @@
var Arrays = Java.type("java.util.Arrays");
var BufferedReader = Java.type("java.io.BufferedReader");
var InputStreamReader = Java.type("java.io.InputStreamReader");
- var List = Java.type("java.util.List");
var ProcessBuilder = Java.type("java.lang.ProcessBuilder");
var System = Java.type("java.lang.System");
@@ -67,7 +66,7 @@
}
} else {
// build child process and start it!
- new ProcessBuilder(Java.to(args, List))
+ new ProcessBuilder(Arrays.asList(args))
.inheritIO()
.start()
.waitFor();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinkerFactory.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinkerFactory.java Wed Jul 05 20:19:27 2017 +0200
@@ -97,6 +97,8 @@
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.MethodHandleTransformer;
import jdk.internal.dynalink.linker.MethodTypeConversionStrategy;
import jdk.internal.dynalink.support.AutoDiscovery;
import jdk.internal.dynalink.support.BottomGuardingDynamicLinker;
@@ -132,6 +134,7 @@
private int unstableRelinkThreshold = DEFAULT_UNSTABLE_RELINK_THRESHOLD;
private GuardedInvocationFilter prelinkFilter;
private MethodTypeConversionStrategy autoConversionStrategy;
+ private MethodHandleTransformer internalObjectsFilter;
/**
* Sets the class loader for automatic discovery of available linkers. If not set explicitly, then the thread
@@ -284,6 +287,15 @@
}
/**
+ * Sets a method handle transformer that is supposed to act as the implementation of this linker factory's linkers'
+ * services {@link LinkerServices#filterInternalObjects(java.lang.invoke.MethodHandle)} method.
+ * @param internalObjectsFilter a method handle transformer filtering out internal objects, or null.
+ */
+ public void setInternalObjectsFilter(final MethodHandleTransformer internalObjectsFilter) {
+ this.internalObjectsFilter = internalObjectsFilter;
+ }
+
+ /**
* Creates a new dynamic linker consisting of all the prioritized, autodiscovered, and fallback linkers as well as
* the pre-link filter.
*
@@ -350,8 +362,8 @@
}
return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters,
- autoConversionStrategy), composite), prelinkFilter, runtimeContextArgCount, syncOnRelink,
- unstableRelinkThreshold);
+ autoConversionStrategy), composite, internalObjectsFilter), prelinkFilter, runtimeContextArgCount,
+ syncOnRelink, unstableRelinkThreshold);
}
private static ClassLoader getThreadContextClassLoader() {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/AbstractJavaLinker.java Wed Jul 05 20:19:27 2017 +0200
@@ -570,7 +570,7 @@
private static final MethodHandle CONSTANT_NULL_DROP_ANNOTATED_METHOD = MethodHandles.dropArguments(
MethodHandles.constant(Object.class, null), 0, AnnotatedDynamicMethod.class);
private static final MethodHandle GET_ANNOTATED_METHOD = privateLookup.findVirtual(AnnotatedDynamicMethod.class,
- "getTarget", MethodType.methodType(MethodHandle.class, MethodHandles.Lookup.class));
+ "getTarget", MethodType.methodType(MethodHandle.class, MethodHandles.Lookup.class, LinkerServices.class));
private static final MethodHandle GETTER_INVOKER = MethodHandles.invoker(MethodType.methodType(Object.class, Object.class));
private GuardedInvocationComponent getPropertyGetter(final CallSiteDescriptor callSiteDescriptor,
@@ -593,7 +593,7 @@
final MethodHandle typedGetter = linkerServices.asType(getPropertyGetterHandle, type.changeReturnType(
AnnotatedDynamicMethod.class));
final MethodHandle callSiteBoundMethodGetter = MethodHandles.insertArguments(
- GET_ANNOTATED_METHOD, 1, callSiteDescriptor.getLookup());
+ GET_ANNOTATED_METHOD, 1, callSiteDescriptor.getLookup(), linkerServices);
final MethodHandle callSiteBoundInvoker = MethodHandles.filterArguments(GETTER_INVOKER, 0,
callSiteBoundMethodGetter);
// Object(AnnotatedDynamicMethod, Object)->Object(AnnotatedDynamicMethod, T0)
@@ -873,8 +873,8 @@
}
@SuppressWarnings("unused")
- MethodHandle getTarget(final MethodHandles.Lookup lookup) {
- final MethodHandle inv = method.getTarget(lookup);
+ MethodHandle getTarget(final MethodHandles.Lookup lookup, final LinkerServices linkerServices) {
+ final MethodHandle inv = linkerServices.filterInternalObjects(method.getTarget(lookup));
assert inv != null;
return inv;
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/BeanLinker.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/BeanLinker.java Wed Jul 05 20:19:27 2017 +0200
@@ -165,6 +165,10 @@
private static MethodHandle LIST_GUARD = Guards.getInstanceOfGuard(List.class);
private static MethodHandle MAP_GUARD = Guards.getInstanceOfGuard(Map.class);
+ private enum CollectionType {
+ ARRAY, LIST, MAP
+ };
+
private GuardedInvocationComponent getElementGetter(final CallSiteDescriptor callSiteDescriptor,
final LinkerServices linkerServices, final List<String> operations) throws Exception {
final MethodType callSiteType = callSiteDescriptor.getMethodType();
@@ -178,27 +182,27 @@
// Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers
// in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices.
final GuardedInvocationComponent gic;
- final boolean isMap;
+ final CollectionType collectionType;
if(declaredType.isArray()) {
- gic = new GuardedInvocationComponent(MethodHandles.arrayElementGetter(declaredType));
- isMap = false;
+ gic = createInternalFilteredGuardedInvocationComponent(MethodHandles.arrayElementGetter(declaredType), linkerServices);
+ collectionType = CollectionType.ARRAY;
} else if(List.class.isAssignableFrom(declaredType)) {
- gic = new GuardedInvocationComponent(GET_LIST_ELEMENT);
- isMap = false;
+ gic = createInternalFilteredGuardedInvocationComponent(GET_LIST_ELEMENT, linkerServices);
+ collectionType = CollectionType.LIST;
} else if(Map.class.isAssignableFrom(declaredType)) {
- gic = new GuardedInvocationComponent(GET_MAP_ELEMENT);
- isMap = true;
+ gic = createInternalFilteredGuardedInvocationComponent(GET_MAP_ELEMENT, linkerServices);
+ collectionType = CollectionType.MAP;
} else if(clazz.isArray()) {
- gic = getClassGuardedInvocationComponent(MethodHandles.arrayElementGetter(clazz), callSiteType);
- isMap = false;
+ gic = getClassGuardedInvocationComponent(linkerServices.filterInternalObjects(MethodHandles.arrayElementGetter(clazz)), callSiteType);
+ collectionType = CollectionType.ARRAY;
} else if(List.class.isAssignableFrom(clazz)) {
- gic = new GuardedInvocationComponent(GET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class,
- ValidationType.INSTANCE_OF);
- isMap = false;
+ gic = createInternalFilteredGuardedInvocationComponent(GET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class, ValidationType.INSTANCE_OF,
+ linkerServices);
+ collectionType = CollectionType.LIST;
} else if(Map.class.isAssignableFrom(clazz)) {
- gic = new GuardedInvocationComponent(GET_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType), Map.class,
- ValidationType.INSTANCE_OF);
- isMap = true;
+ gic = createInternalFilteredGuardedInvocationComponent(GET_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType), Map.class, ValidationType.INSTANCE_OF,
+ linkerServices);
+ collectionType = CollectionType.MAP;
} else {
// Can't retrieve elements for objects that are neither arrays, nor list, nor maps.
return nextComponent;
@@ -208,7 +212,7 @@
final String fixedKey = getFixedKey(callSiteDescriptor);
// Convert the key to a number if we're working with a list or array
final Object typedFixedKey;
- if(!isMap && fixedKey != null) {
+ if(collectionType != CollectionType.MAP && fixedKey != null) {
typedFixedKey = convertKeyToInteger(fixedKey, linkerServices);
if(typedFixedKey == null) {
// key is not numeric, it can never succeed
@@ -227,15 +231,21 @@
}
final MethodHandle checkGuard;
- if(invocation == GET_LIST_ELEMENT) {
+ switch(collectionType) {
+ case LIST:
checkGuard = convertArgToInt(RANGE_CHECK_LIST, linkerServices, callSiteDescriptor);
- } else if(invocation == GET_MAP_ELEMENT) {
+ break;
+ case MAP:
// TODO: A more complex solution could be devised for maps, one where we do a get() first, and fold it
// into a GWT that tests if it returned null, and if it did, do another GWT with containsKey()
// that returns constant null (on true), or falls back to next component (on false)
- checkGuard = CONTAINS_MAP;
- } else {
+ checkGuard = linkerServices.filterInternalObjects(CONTAINS_MAP);
+ break;
+ case ARRAY:
checkGuard = convertArgToInt(RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
+ break;
+ default:
+ throw new AssertionError();
}
final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation),
nextComponent.getGuardedInvocation().getInvocation());
@@ -243,6 +253,18 @@
gic.getValidatorClass(), gic.getValidationType());
}
+ private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
+ final MethodHandle invocation, final LinkerServices linkerServices) {
+ return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation));
+ }
+
+ private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
+ final MethodHandle invocation, final MethodHandle guard, final Class<?> validatorClass,
+ final ValidationType validationType, final LinkerServices linkerServices) {
+ return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation), guard,
+ validatorClass, validationType);
+ }
+
private static String getFixedKey(final CallSiteDescriptor callSiteDescriptor) {
return callSiteDescriptor.getNameTokenCount() == 2 ? null : callSiteDescriptor.getNameToken(
CallSiteDescriptor.NAME_OPERAND);
@@ -381,37 +403,38 @@
// dealing with an array, or a list or map, but hey...
// Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers
// in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices.
- final boolean isMap;
+ final CollectionType collectionType;
if(declaredType.isArray()) {
- gic = new GuardedInvocationComponent(MethodHandles.arrayElementSetter(declaredType));
- isMap = false;
+ gic = createInternalFilteredGuardedInvocationComponent(MethodHandles.arrayElementSetter(declaredType), linkerServices);
+ collectionType = CollectionType.ARRAY;
} else if(List.class.isAssignableFrom(declaredType)) {
- gic = new GuardedInvocationComponent(SET_LIST_ELEMENT);
- isMap = false;
+ gic = createInternalFilteredGuardedInvocationComponent(SET_LIST_ELEMENT, linkerServices);
+ collectionType = CollectionType.LIST;
} else if(Map.class.isAssignableFrom(declaredType)) {
- gic = new GuardedInvocationComponent(PUT_MAP_ELEMENT);
- isMap = true;
+ gic = createInternalFilteredGuardedInvocationComponent(PUT_MAP_ELEMENT, linkerServices);
+ collectionType = CollectionType.MAP;
} else if(clazz.isArray()) {
- gic = getClassGuardedInvocationComponent(MethodHandles.arrayElementSetter(clazz), callSiteType);
- isMap = false;
+ gic = getClassGuardedInvocationComponent(linkerServices.filterInternalObjects(
+ MethodHandles.arrayElementSetter(clazz)), callSiteType);
+ collectionType = CollectionType.ARRAY;
} else if(List.class.isAssignableFrom(clazz)) {
- gic = new GuardedInvocationComponent(SET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class,
- ValidationType.INSTANCE_OF);
- isMap = false;
+ gic = createInternalFilteredGuardedInvocationComponent(SET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class, ValidationType.INSTANCE_OF,
+ linkerServices);
+ collectionType = CollectionType.LIST;
} else if(Map.class.isAssignableFrom(clazz)) {
- gic = new GuardedInvocationComponent(PUT_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType), Map.class,
- ValidationType.INSTANCE_OF);
- isMap = true;
+ gic = createInternalFilteredGuardedInvocationComponent(PUT_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType),
+ Map.class, ValidationType.INSTANCE_OF, linkerServices);
+ collectionType = CollectionType.MAP;
} else {
// Can't set elements for objects that are neither arrays, nor list, nor maps.
gic = null;
- isMap = false;
+ collectionType = null;
}
// In contrast to, say, getElementGetter, we only compute the nextComponent if the target object is not a map,
// as maps will always succeed in setting the element and will never need to fall back to the next component
// operation.
- final GuardedInvocationComponent nextComponent = isMap ? null : getGuardedInvocationComponent(
+ final GuardedInvocationComponent nextComponent = collectionType == CollectionType.MAP ? null : getGuardedInvocationComponent(
callSiteDescriptor, linkerServices, operations);
if(gic == null) {
return nextComponent;
@@ -421,7 +444,7 @@
final String fixedKey = getFixedKey(callSiteDescriptor);
// Convert the key to a number if we're working with a list or array
final Object typedFixedKey;
- if(!isMap && fixedKey != null) {
+ if(collectionType != CollectionType.MAP && fixedKey != null) {
typedFixedKey = convertKeyToInteger(fixedKey, linkerServices);
if(typedFixedKey == null) {
// key is not numeric, it can never succeed
@@ -439,7 +462,8 @@
return gic.replaceInvocation(binder.bind(invocation));
}
- final MethodHandle checkGuard = convertArgToInt(invocation == SET_LIST_ELEMENT ? RANGE_CHECK_LIST :
+ assert collectionType == CollectionType.LIST || collectionType == CollectionType.ARRAY;
+ final MethodHandle checkGuard = convertArgToInt(collectionType == CollectionType.LIST ? RANGE_CHECK_LIST :
RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation),
nextComponent.getGuardedInvocation().getInvocation());
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/OverloadedMethod.java Wed Jul 05 20:19:27 2017 +0200
@@ -139,7 +139,8 @@
final MethodHandle bound = SELECT_METHOD.bindTo(this);
final MethodHandle collecting = SingleDynamicMethod.collectArguments(bound, argNum).asType(
callSiteType.changeReturnType(MethodHandle.class));
- invoker = MethodHandles.foldArguments(MethodHandles.exactInvoker(this.callSiteType), collecting);
+ invoker = linkerServices.asTypeLosslessReturn(MethodHandles.foldArguments(
+ MethodHandles.exactInvoker(this.callSiteType), collecting), callSiteType);
}
MethodHandle getInvoker() {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/SingleDynamicMethod.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/beans/SingleDynamicMethod.java Wed Jul 05 20:19:27 2017 +0200
@@ -165,10 +165,11 @@
* @return the adapted method handle.
*/
static MethodHandle getInvocation(final MethodHandle target, final MethodType callSiteType, final LinkerServices linkerServices) {
- final MethodType methodType = target.type();
+ final MethodHandle filteredTarget = linkerServices.filterInternalObjects(target);
+ final MethodType methodType = filteredTarget.type();
final int paramsLen = methodType.parameterCount();
final boolean varArgs = target.isVarargsCollector();
- final MethodHandle fixTarget = varArgs ? target.asFixedArity() : target;
+ final MethodHandle fixTarget = varArgs ? filteredTarget.asFixedArity() : filteredTarget;
final int fixParamsLen = varArgs ? paramsLen - 1 : paramsLen;
final int argsLen = callSiteType.parameterCount();
if(argsLen < fixParamsLen) {
@@ -204,7 +205,7 @@
if(varArgType.isAssignableFrom(callSiteLastArgType)) {
// Call site signature guarantees we'll always be passed a single compatible array; just link directly
// to the method, introducing necessary conversions. Also, preserve it being a variable arity method.
- return createConvertingInvocation(target, linkerServices, callSiteType).asVarargsCollector(
+ return createConvertingInvocation(filteredTarget, linkerServices, callSiteType).asVarargsCollector(
callSiteLastArgType);
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkerServices.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/LinkerServices.java Wed Jul 05 20:19:27 2017 +0200
@@ -181,6 +181,15 @@
public Comparison compareConversion(Class<?> sourceType, Class<?> targetType1, Class<?> targetType2);
/**
+ * Modifies the method handle so that any parameters that can receive potentially internal language runtime objects
+ * will have a filter added on them to prevent them from escaping, potentially by wrapping them.
+ * It can also potentially add an unwrapping filter to the return value.
+ * @param target the target method handle
+ * @return a method handle with parameters and/or return type potentially filtered for wrapping and unwrapping.
+ */
+ public MethodHandle filterInternalObjects(final MethodHandle target);
+
+ /**
* If we could just use Java 8 constructs, then {@code asTypeSafeReturn} would be a method with default
* implementation. Since we can't do that, we extract common default implementations into this static class.
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/linker/MethodHandleTransformer.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file, and Oracle licenses the original version of this file under the BSD
+ * license:
+ */
+/*
+ Copyright 2009-2015 Attila Szegedi
+
+ Licensed under both the Apache License, Version 2.0 (the "Apache License")
+ and the BSD License (the "BSD License"), with licensee being free to
+ choose either of the two at their discretion.
+
+ You may not use this file except in compliance with either the Apache
+ License or the BSD License.
+
+ If you choose to use this file in compliance with the Apache License, the
+ following notice applies to you:
+
+ You may obtain a copy of the Apache License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ If you choose to use this file in compliance with the BSD License, the
+ following notice applies to you:
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the copyright holder nor the names of
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package jdk.internal.dynalink.linker;
+
+import java.lang.invoke.MethodHandle;
+
+/**
+ * A generic interface describing operations that transform method handles.
+ */
+public interface MethodHandleTransformer {
+ /**
+ * Transforms a method handle.
+ * @param target the method handle being transformed.
+ * @return transformed method handle.
+ */
+ public MethodHandle transform(final MethodHandle target);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/DefaultInternalObjectFilter.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file, and Oracle licenses the original version of this file under the BSD
+ * license:
+ */
+/*
+ Copyright 2009-2015 Attila Szegedi
+
+ Licensed under both the Apache License, Version 2.0 (the "Apache License")
+ and the BSD License (the "BSD License"), with licensee being free to
+ choose either of the two at their discretion.
+
+ You may not use this file except in compliance with either the Apache
+ License or the BSD License.
+
+ If you choose to use this file in compliance with the Apache License, the
+ following notice applies to you:
+
+ You may obtain a copy of the Apache License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ If you choose to use this file in compliance with the BSD License, the
+ following notice applies to you:
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the copyright holder nor the names of
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package jdk.internal.dynalink.support;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.DynamicLinkerFactory;
+import jdk.internal.dynalink.linker.MethodHandleTransformer;
+
+/**
+ * Default implementation for a {@link DynamicLinkerFactory#setInternalObjectsFilter(MethodHandleTransformer)}.
+ * Given a method handle of {@code Object(Object)} type for filtering parameter and another one of the same type for
+ * filtering return values, applies them to passed method handles where their parameter types and/or return value types
+ * are declared to be {@link Object}.
+ */
+public class DefaultInternalObjectFilter implements MethodHandleTransformer {
+ private static final MethodHandle FILTER_VARARGS = new Lookup(MethodHandles.lookup()).findStatic(
+ DefaultInternalObjectFilter.class, "filterVarArgs", MethodType.methodType(Object[].class, MethodHandle.class, Object[].class));
+
+ private final MethodHandle parameterFilter;
+ private final MethodHandle returnFilter;
+ private final MethodHandle varArgFilter;
+
+ /**
+ * Creates a new filter.
+ * @param parameterFilter the filter for method parameters. Must be of type {@code Object(Object)}, or null.
+ * @param returnFilter the filter for return values. Must be of type {@code Object(Object)}, or null.
+ * @throws IllegalArgumentException if one or both filters are not of the expected type.
+ */
+ public DefaultInternalObjectFilter(final MethodHandle parameterFilter, final MethodHandle returnFilter) {
+ this.parameterFilter = checkHandle(parameterFilter, "parameterFilter");
+ this.returnFilter = checkHandle(returnFilter, "returnFilter");
+ this.varArgFilter = parameterFilter == null ? null : FILTER_VARARGS.bindTo(parameterFilter);
+ }
+
+ @Override
+ public MethodHandle transform(final MethodHandle target) {
+ assert target != null;
+ MethodHandle[] filters = null;
+ final MethodType type = target.type();
+ final boolean isVarArg = target.isVarargsCollector();
+ final int paramCount = type.parameterCount();
+ final MethodHandle paramsFiltered;
+ // Filter parameters
+ if (parameterFilter != null) {
+ int firstFilter = -1;
+ // Ignore receiver, start from argument 1
+ for(int i = 1; i < paramCount; ++i) {
+ final Class<?> paramType = type.parameterType(i);
+ final boolean filterVarArg = isVarArg && i == paramCount - 1 && paramType == Object[].class;
+ if (filterVarArg || paramType == Object.class) {
+ if (filters == null) {
+ firstFilter = i;
+ filters = new MethodHandle[paramCount - firstFilter];
+ }
+ filters[i - firstFilter] = filterVarArg ? varArgFilter : parameterFilter;
+ }
+ }
+ paramsFiltered = filters != null ? MethodHandles.filterArguments(target, firstFilter, filters) : target;
+ } else {
+ paramsFiltered = target;
+ }
+ // Filter return value if needed
+ final MethodHandle returnFiltered = returnFilter != null && type.returnType() == Object.class ? MethodHandles.filterReturnValue(paramsFiltered, returnFilter) : paramsFiltered;
+ // Preserve varargs collector state
+ return isVarArg && !returnFiltered.isVarargsCollector() ? returnFiltered.asVarargsCollector(type.parameterType(paramCount - 1)) : returnFiltered;
+
+ }
+
+ private static MethodHandle checkHandle(final MethodHandle handle, final String handleKind) {
+ if (handle != null) {
+ final MethodType objectObjectType = MethodType.methodType(Object.class, Object.class);
+ if (!handle.type().equals(objectObjectType)) {
+ throw new IllegalArgumentException("Method type for " + handleKind + " must be " + objectObjectType);
+ }
+ }
+ return handle;
+ }
+
+ @SuppressWarnings("unused")
+ private static Object[] filterVarArgs(final MethodHandle parameterFilter, final Object[] args) throws Throwable {
+ Object[] newArgs = null;
+ for(int i = 0; i < args.length; ++i) {
+ final Object arg = args[i];
+ final Object newArg = parameterFilter.invokeExact(arg);
+ if (arg != newArg) {
+ if (newArgs == null) {
+ newArgs = args.clone();
+ }
+ newArgs[i] = newArg;
+ }
+ }
+ return newArgs == null ? args : newArgs;
+ }
+}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/LinkerServicesImpl.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/support/LinkerServicesImpl.java Wed Jul 05 20:19:27 2017 +0200
@@ -90,6 +90,7 @@
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.MethodHandleTransformer;
/**
* Default implementation of the {@link LinkerServices} interface.
@@ -103,17 +104,21 @@
private final TypeConverterFactory typeConverterFactory;
private final GuardingDynamicLinker topLevelLinker;
+ private final MethodHandleTransformer internalObjectsFilter;
/**
* Creates a new linker services object.
*
* @param typeConverterFactory the type converter factory exposed by the services.
* @param topLevelLinker the top level linker used by the services.
+ * @param internalObjectsFilter a method handle transformer that is supposed to act as the implementation of this
+ * services' {@link #filterInternalObjects(java.lang.invoke.MethodHandle)} method.
*/
public LinkerServicesImpl(final TypeConverterFactory typeConverterFactory,
- final GuardingDynamicLinker topLevelLinker) {
+ final GuardingDynamicLinker topLevelLinker, final MethodHandleTransformer internalObjectsFilter) {
this.typeConverterFactory = typeConverterFactory;
this.topLevelLinker = topLevelLinker;
+ this.internalObjectsFilter = internalObjectsFilter;
}
@Override
@@ -152,6 +157,11 @@
}
}
+ @Override
+ public MethodHandle filterInternalObjects(final MethodHandle target) {
+ return internalObjectsFilter != null ? internalObjectsFilter.transform(target) : target;
+ }
+
/**
* Returns the currently processed link request, or null if the method is invoked outside of the linking process.
* @return the currently processed link request, or null.
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptObjectMirror.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptObjectMirror.java Wed Jul 05 20:19:27 2017 +0200
@@ -448,7 +448,7 @@
checkKey(key);
return inGlobal(new Callable<Object>() {
@Override public Object call() {
- return wrap(sobj.remove(key, strict), global);
+ return translateUndefined(wrap(sobj.remove(key, strict), global));
}
});
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java Wed Jul 05 20:19:27 2017 +0200
@@ -38,6 +38,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* Contains utility methods for calculating the memory usage of objects. It
@@ -150,7 +151,7 @@
* @param memoryLayoutSpecification a description of the JVM memory layout.
*/
public ObjectSizeCalculator(final MemoryLayoutSpecification memoryLayoutSpecification) {
- memoryLayoutSpecification.getClass();
+ Objects.requireNonNull(memoryLayoutSpecification);
arrayHeaderSize = memoryLayoutSpecification.getArrayHeaderSize();
objectHeaderSize = memoryLayoutSpecification.getObjectHeaderSize();
objectPadding = memoryLayoutSpecification.getObjectPadding();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Wed Jul 05 20:19:27 2017 +0200
@@ -119,6 +119,7 @@
return unboxReturnType(target, newType);
}
});
+ factory.setInternalObjectsFilter(NashornBeansLinker.createHiddenObjectFilter());
final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", NASHORN_DEFAULT_UNSTABLE_RELINK_THRESHOLD);
if (relinkThreshold > -1) {
factory.setUnstableRelinkThreshold(relinkThreshold);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Wed Jul 05 20:19:27 2017 +0200
@@ -40,10 +40,11 @@
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.linker.MethodHandleTransformer;
+import jdk.internal.dynalink.support.DefaultInternalObjectFilter;
import jdk.internal.dynalink.support.Guards;
import jdk.internal.dynalink.support.Lookup;
import jdk.nashorn.api.scripting.ScriptUtils;
-import jdk.nashorn.internal.objects.NativeArray;
import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ScriptObject;
@@ -52,10 +53,14 @@
/**
* This linker delegates to a {@code BeansLinker} but passes it a special linker services object that has a modified
- * {@code asType} method that will ensure that we never pass internal engine objects that should not be externally
- * observable (currently ConsString and ScriptObject) to Java APIs, but rather that we flatten it into a String. We can't just add
- * this functionality as custom converters via {@code GuaardingTypeConverterFactory}, since they are not consulted when
- * the target method handle parameter signature is {@code Object}.
+ * {@code compareConversion} method that favors conversion of {@link ConsString} to either {@link String} or
+ * {@link CharSequence}. It also provides a {@link #createHiddenObjectFilter()} method for use with bootstrap that will
+ * ensure that we never pass internal engine objects that should not be externally observable (currently ConsString and
+ * ScriptObject) to Java APIs, but rather that we flatten it into a String. We can't just add this functionality as
+ * custom converters via {@code GuaardingTypeConverterFactory}, since they are not consulted when
+ * the target method handle parameter signature is {@code Object}. This linker also makes sure that primitive
+ * {@link String} operations can be invoked on a {@link ConsString}, and allows invocation of objects implementing
+ * the {@link FunctionalInterface} attribute.
*/
public class NashornBeansLinker implements GuardingDynamicLinker {
// System property to control whether to wrap ScriptObject->ScriptObjectMirror for
@@ -63,16 +68,12 @@
private static final boolean MIRROR_ALWAYS = Options.getBooleanProperty("nashorn.mirror.always", true);
private static final MethodHandle EXPORT_ARGUMENT;
- private static final MethodHandle EXPORT_NATIVE_ARRAY;
- private static final MethodHandle EXPORT_SCRIPT_OBJECT;
private static final MethodHandle IMPORT_RESULT;
private static final MethodHandle FILTER_CONSSTRING;
static {
final Lookup lookup = new Lookup(MethodHandles.lookup());
EXPORT_ARGUMENT = lookup.findOwnStatic("exportArgument", Object.class, Object.class);
- EXPORT_NATIVE_ARRAY = lookup.findOwnStatic("exportNativeArray", Object.class, NativeArray.class);
- EXPORT_SCRIPT_OBJECT = lookup.findOwnStatic("exportScriptObject", Object.class, ScriptObject.class);
IMPORT_RESULT = lookup.findOwnStatic("importResult", Object.class, Object.class);
FILTER_CONSSTRING = lookup.findOwnStatic("consStringFilter", Object.class, Object.class);
}
@@ -115,9 +116,10 @@
}
return new GuardedInvocation(
// drop 'thiz' passed from the script.
- MH.dropArguments(desc.getLookup().unreflect(m), 1, callType.parameterType(1)),
- Guards.getInstanceOfGuard(m.getDeclaringClass())).asTypeSafeReturn(
- new NashornBeansLinkerServices(linkerServices), callType);
+ MH.dropArguments(linkerServices.filterInternalObjects(desc.getLookup().unreflect(m)), 1,
+ callType.parameterType(1)), Guards.getInstanceOfGuard(
+ m.getDeclaringClass())).asTypeSafeReturn(
+ new NashornBeansLinkerServices(linkerServices), callType);
}
}
return getGuardedInvocation(beansLinker, linkRequest, linkerServices);
@@ -141,21 +143,6 @@
return exportArgument(arg, MIRROR_ALWAYS);
}
- @SuppressWarnings("unused")
- private static Object exportNativeArray(final NativeArray arg) {
- return exportArgument(arg, MIRROR_ALWAYS);
- }
-
- @SuppressWarnings("unused")
- private static Object exportScriptObject(final ScriptObject arg) {
- return exportArgument(arg, MIRROR_ALWAYS);
- }
-
- @SuppressWarnings("unused")
- private static Object exportScriptArray(final NativeArray arg) {
- return exportArgument(arg, MIRROR_ALWAYS);
- }
-
static Object exportArgument(final Object arg, final boolean mirrorAlways) {
if (arg instanceof ConsString) {
return arg.toString();
@@ -208,6 +195,10 @@
return FUNCTIONAL_IFACE_METHOD.get(clazz);
}
+ static MethodHandleTransformer createHiddenObjectFilter() {
+ return new DefaultInternalObjectFilter(EXPORT_ARGUMENT, MIRROR_ALWAYS ? IMPORT_RESULT : null);
+ }
+
private static class NashornBeansLinkerServices implements LinkerServices {
private final LinkerServices linkerServices;
@@ -217,50 +208,7 @@
@Override
public MethodHandle asType(final MethodHandle handle, final MethodType fromType) {
- final MethodType handleType = handle.type();
- final int paramCount = handleType.parameterCount();
- assert fromType.parameterCount() == handleType.parameterCount();
-
- MethodType newFromType = fromType;
- MethodHandle[] filters = null;
- for(int i = 0; i < paramCount; ++i) {
- final MethodHandle filter = argConversionFilter(handleType.parameterType(i), fromType.parameterType(i));
- if (filter != null) {
- if (filters == null) {
- filters = new MethodHandle[paramCount];
- }
- // "erase" specific type with Object type or else we'll get filter mismatch
- newFromType = newFromType.changeParameterType(i, Object.class);
- filters[i] = filter;
- }
- }
-
- final MethodHandle typed = linkerServices.asType(handle, newFromType);
- MethodHandle result = filters != null ? MethodHandles.filterArguments(typed, 0, filters) : typed;
- // Filter Object typed return value for possible ScriptObjectMirror. We convert
- // ScriptObjectMirror as ScriptObject (if it is mirror from current global).
- if (MIRROR_ALWAYS && areBothObjects(handleType.returnType(), fromType.returnType())) {
- result = MethodHandles.filterReturnValue(result, IMPORT_RESULT);
- }
-
- return result;
- }
-
- private static MethodHandle argConversionFilter(final Class<?> handleType, final Class<?> fromType) {
- if (handleType == Object.class) {
- if (fromType == Object.class) {
- return EXPORT_ARGUMENT;
- } else if (fromType == NativeArray.class) {
- return EXPORT_NATIVE_ARRAY;
- } else if (fromType == ScriptObject.class) {
- return EXPORT_SCRIPT_OBJECT;
- }
- }
- return null;
- }
-
- private static boolean areBothObjects(final Class<?> handleType, final Class<?> fromType) {
- return handleType == Object.class && fromType == Object.class;
+ return linkerServices.asType(handle, fromType);
}
@Override
@@ -296,5 +244,10 @@
}
return linkerServices.compareConversion(sourceType, targetType1, targetType2);
}
+
+ @Override
+ public MethodHandle filterInternalObjects(MethodHandle target) {
+ return linkerServices.filterInternalObjects(target);
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8072596.js Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8072596: Arrays.asList results in ClassCastException with a JS array
+ *
+ * @test
+ * @run
+ */
+var arr = java.util.Arrays.asList("hello world".split(' '));
+// We split it into a list of two elements: [hello, world]
+Assert.assertTrue(arr instanceof java.util.List);
+Assert.assertEquals(arr.length, 2);
+Assert.assertEquals(arr[0], "hello");
+Assert.assertEquals(arr[1], "world");
+
+var Jdk8072596TestSubject = Java.type("jdk.nashorn.test.models.Jdk8072596TestSubject");
+var testSubject = new Jdk8072596TestSubject({bar: 0});
+testSubject.test1(true, {foo: 1}, {bar: 2});
+testSubject.test2(true, {foo: 1}, {bar: 2}, {baz: 3}, {bing: 4});
+var h = "h";
+var ello = "ello";
+testSubject.test3(true, {foo: 5}, /* ConsString, why not */ h + ello, [6, 7], 8);
+Jdk8072596TestSubject.test4({foo: 9});
+
+// Test wrapping setters arguments and unwrapping getters return values on list.
+var list = new java.util.ArrayList();
+list.add(null);
+var obj0 = {valueOf: function() { return 0; }};
+var obj1 = {foo: 10};
+list[obj0] = obj1;
+testSubject.testListHasWrappedObject(list);
+// NOTE: can't use Assert.assertSame(obj1, list[obj0]), as the arguments would end up being wrapped...
+Assert.assertTrue(obj1 === list[obj0]);
+
+// Test wrapping setters arguments and unwrapping getters return values on array.
+var arr2 = new (Java.type("java.lang.Object[]"))(1);
+var obj2 = {bar: 11};
+arr2[obj0] = obj2;
+testSubject.testArrayHasWrappedObject(arr2);
+Assert.assertTrue(obj2 === arr2[obj0]);
+
+// Test wrapping setters index and arguments and getters index, and unwrapping getters return values on map.
+// Since ScriptObjectMirror.equals() uses underlying ScriptObject identity, using them as map keys works.
+var map = new java.util.HashMap();
+var obj3 = {bar: 12};
+map[obj0] = obj3;
+testSubject.testMapHasWrappedObject(map, obj0);
+Assert.assertTrue(obj3 === map[obj0]);
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -706,4 +706,74 @@
}
}
+ // @bug 8071678: NashornScriptEngine returns javax.script.ScriptContext instance
+ // with get/setAttribute methods insonsistent for GLOBAL_SCOPE
+ @Test
+ public void testGlobalScopeSearch() throws Exception {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final ScriptContext c = e.getContext();
+ c.setAttribute("name1234", "value", ScriptContext.GLOBAL_SCOPE);
+ assertEquals(c.getAttribute("name1234"), "value");
+ assertEquals(c.getAttributesScope("name1234"),
+ ScriptContext.GLOBAL_SCOPE);
+ }
+
+ // @bug 8071594: NashornScriptEngine returns javax.script.ScriptContext instance
+ // which doesn't completely conform to the spec regarding exceptions throwing
+ @Test
+ public void testScriptContext_NPE_IAE() throws Exception {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final ScriptContext c = e.getContext();
+ try {
+ c.getAttribute("");
+ throw new AssertionError("should have thrown IAE");
+ } catch (IllegalArgumentException iae1) {}
+
+ try {
+ c.getAttribute(null);
+ throw new AssertionError("should have thrown NPE");
+ } catch (NullPointerException npe1) {}
+
+ try {
+ c.getAttribute("", ScriptContext.ENGINE_SCOPE);
+ throw new AssertionError("should have thrown IAE");
+ } catch (IllegalArgumentException iae2) {}
+
+ try {
+ c.getAttribute(null, ScriptContext.ENGINE_SCOPE);
+ throw new AssertionError("should have thrown NPE");
+ } catch (NullPointerException npe2) {}
+
+ try {
+ c.removeAttribute("", ScriptContext.ENGINE_SCOPE);
+ throw new AssertionError("should have thrown IAE");
+ } catch (IllegalArgumentException iae3) {}
+
+ try {
+ c.removeAttribute(null, ScriptContext.ENGINE_SCOPE);
+ throw new AssertionError("should have thrown NPE");
+ } catch (NullPointerException npe3) {}
+
+ try {
+ c.setAttribute("", "value", ScriptContext.ENGINE_SCOPE);
+ throw new AssertionError("should have thrown IAE");
+ } catch (IllegalArgumentException iae4) {}
+
+ try {
+ c.setAttribute(null, "value", ScriptContext.ENGINE_SCOPE);
+ throw new AssertionError("should have thrown NPE");
+ } catch (NullPointerException npe4) {}
+
+ try {
+ c.getAttributesScope("");
+ throw new AssertionError("should have thrown IAE");
+ } catch (IllegalArgumentException iae5) {}
+
+ try {
+ c.getAttributesScope(null);
+ throw new AssertionError("should have thrown NPE");
+ } catch (NullPointerException npe5) {}
+ }
}
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Thu Feb 12 16:23:24 2015 -0800
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Jul 05 20:19:27 2017 +0200
@@ -852,6 +852,17 @@
}
}
+ // @bug 8071989: NashornScriptEngine returns javax.script.ScriptContext instance
+ // with insonsistent get/remove methods behavior for undefined attributes
+ @Test
+ public void testScriptContextGetRemoveUndefined() throws Exception {
+ final ScriptEngineManager manager = new ScriptEngineManager();
+ final ScriptEngine e = manager.getEngineByName("nashorn");
+ final ScriptContext ctx = e.getContext();
+ assertNull(ctx.getAttribute("undefinedname", ScriptContext.ENGINE_SCOPE));
+ assertNull(ctx.removeAttribute("undefinedname", ScriptContext.ENGINE_SCOPE));
+ }
+
private static void checkProperty(final ScriptEngine e, final String name)
throws ScriptException {
final String value = System.getProperty(name);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/test/models/Jdk8072596TestSubject.java Wed Jul 05 20:19:27 2017 +0200
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. 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.
+ */
+
+package jdk.nashorn.test.models;
+
+import java.util.List;
+import java.util.Map;
+import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import org.testng.Assert;
+
+public class Jdk8072596TestSubject {
+
+ public Jdk8072596TestSubject(final Object x) {
+ Assert.assertTrue(x instanceof ScriptObjectMirror);
+ Assert.assertEquals(((ScriptObjectMirror)x).get("bar"), 0);
+ }
+
+ // Test having to wrap some arguments but not others
+ public void test1(final String x, final Object y, final ScriptObject w) {
+ Assert.assertEquals(x, "true");
+
+ Assert.assertTrue(y instanceof ScriptObjectMirror);
+ Assert.assertEquals(((ScriptObjectMirror)y).get("foo"), 1);
+
+ Assert.assertEquals(w.get("bar"), 2);
+ }
+
+ // Test having to wrap some arguments but not others, and a vararg array
+ public void test2(String x, final Object y, final ScriptObject w, final Object... z) {
+ test1(x, y, w);
+
+ Assert.assertEquals(z.length, 2);
+
+ Assert.assertTrue(z[0] instanceof ScriptObjectMirror);
+ Assert.assertEquals(((ScriptObjectMirror)z[0]).get("baz"), 3);
+
+ Assert.assertTrue(z[1] instanceof ScriptObjectMirror);
+ Assert.assertEquals(((ScriptObjectMirror)z[1]).get("bing"), 4);
+ }
+
+ // Test mixed (wrappable and non-wrappable) elements in a vararg array
+ public void test3(final Object... z) {
+ Assert.assertEquals(z.length, 5);
+
+ Assert.assertEquals(z[0], true);
+
+ Assert.assertTrue(z[1] instanceof ScriptObjectMirror);
+ Assert.assertEquals(((ScriptObjectMirror)z[1]).get("foo"), 5);
+
+ Assert.assertEquals(z[2], "hello");
+
+ Assert.assertTrue(z[3] instanceof ScriptObjectMirror);
+ Assert.assertEquals(((ScriptObjectMirror)z[3]).getSlot(0), 6);
+ Assert.assertEquals(((ScriptObjectMirror)z[3]).getSlot(1), 7);
+
+ Assert.assertEquals(z[4], 8);
+ }
+
+ // test wrapping the first argument of a static method
+ public static void test4(final Object x) {
+ Assert.assertTrue(x instanceof ScriptObjectMirror);
+ Assert.assertEquals(((ScriptObjectMirror)x).get("foo"), 9);
+ }
+
+ public void testListHasWrappedObject(final List<?> l) {
+ Assert.assertEquals(l.size(), 1);
+ Assert.assertTrue(l.get(0) instanceof ScriptObjectMirror);
+ Assert.assertEquals(((ScriptObjectMirror)l.get(0)).get("foo"), 10);
+ }
+
+ public void testArrayHasWrappedObject(final Object[] a) {
+ Assert.assertEquals(a.length, 1);
+ Assert.assertTrue(a[0] instanceof ScriptObjectMirror);
+ Assert.assertEquals(((ScriptObjectMirror)a[0]).get("bar"), 11);
+ }
+
+ public void testMapHasWrappedObject(final Map<?, ?> m, final Object key) {
+ Assert.assertEquals(m.size(), 1);
+ Assert.assertTrue(key instanceof ScriptObjectMirror);
+ Assert.assertTrue(m.get(key) instanceof ScriptObjectMirror);
+ Assert.assertEquals(((ScriptObjectMirror)m.get(key)).get("bar"), 12);
+ }
+}