# HG changeset patch # User duke # Date 1499285760 -7200 # Node ID 552748e3d506c1f194da0049b53e1caa1a3c78c0 # Parent 8ced0dd94a6e44aa482b3214a430c61865c46d48# Parent ce8892c57791f4db6dfb66f7271d0e46dd08881f Merge diff -r 8ced0dd94a6e -r 552748e3d506 .hgtags-top-repo --- a/.hgtags-top-repo Thu Sep 22 16:41:14 2016 +0000 +++ b/.hgtags-top-repo Wed Jul 05 22:16:00 2017 +0200 @@ -379,3 +379,4 @@ 065724348690eda41fc69112278d8da6dcde548c jdk-9+134 82b94cb5f342319d2cda77f9fa59703ad7fde576 jdk-9+135 3ec350f5f32af249b59620d7e37b54bdcd77b233 jdk-9+136 +d7f519b004254b19e384131d9f0d0e40e31a0fd3 jdk-9+137 diff -r 8ced0dd94a6e -r 552748e3d506 Makefile --- a/Makefile Thu Sep 22 16:41:14 2016 +0000 +++ b/Makefile Wed Jul 05 22:16:00 2017 +0200 @@ -28,8 +28,8 @@ ### It also performs some sanity checks on make. ### -# The shell code below will be executed on /usr/ccs/bin/make on Solaris, but not in GNU Make. -# /usr/ccs/bin/make lacks basically every other flow control mechanism. +# The shell code below will be executed on /usr/bin/make on Solaris, but not in GNU Make. +# /usr/bin/make lacks basically every other flow control mechanism. .TEST_FOR_NON_GNUMAKE:sh=echo You are not using GNU Make/gmake, this is a requirement. Check your path. 1>&2 && exit 1 # The .FEATURES variable is likely to be unique for GNU Make. diff -r 8ced0dd94a6e -r 552748e3d506 README-builds.html --- a/README-builds.html Thu Sep 22 16:41:14 2016 +0000 +++ b/README-builds.html Wed Jul 05 22:16:00 2017 +0200 @@ -626,8 +626,7 @@

The Common UNIX Printing System (CUPS) Headers are required for building the OpenJDK on Solaris and Linux. The Solaris header files can be obtained by - installing the package SFWcups from the Solaris Software Companion - CD/DVD, these often will be installed into the directory /opt/sfw/cups.

+ installing the package print/cups.

The CUPS header files can always be downloaded from www.cups.org.

@@ -1111,8 +1110,7 @@
  • Place the location of the GNU make binary in the PATH.
  • Solaris: Do NOT use /usr/bin/make on Solaris. If your Solaris system has the software from the Solaris Developer Companion CD installed, you -should try and use gmake which will be located in either the /usr/bin, -/opt/sfw/bin or /usr/sfw/bin directory.
  • +should try and use /usr/bin/gmake or /usr/gnu/bin/make.
  • Windows: Make sure you start your build inside a bash shell.
  • Mac OS X: The XCode "command line tools" must be installed on your Mac.
  • diff -r 8ced0dd94a6e -r 552748e3d506 README-builds.md --- a/README-builds.md Thu Sep 22 16:41:14 2016 +0000 +++ b/README-builds.md Wed Jul 05 22:16:00 2017 +0200 @@ -560,8 +560,7 @@ > The Common UNIX Printing System (CUPS) Headers are required for building the OpenJDK on Solaris and Linux. The Solaris header files can be obtained by - installing the package **SFWcups** from the Solaris Software Companion - CD/DVD, these often will be installed into the directory `/opt/sfw/cups`. + installing the package **print/cups**. > The CUPS header files can always be downloaded from [www.cups.org](http://www.cups.org). @@ -1017,8 +1016,7 @@ * Place the location of the GNU make binary in the `PATH`. * **Solaris:** Do NOT use `/usr/bin/make` on Solaris. If your Solaris system has the software from the Solaris Developer Companion CD installed, you - should try and use `gmake` which will be located in either the `/usr/bin`, - `/opt/sfw/bin` or `/usr/sfw/bin` directory. + should try and use `/usr/bin/gmake` or `/usr/gnu/bin/make`. * **Windows:** Make sure you start your build inside a bash shell. * **Mac OS X:** The XCode "command line tools" must be installed on your Mac. diff -r 8ced0dd94a6e -r 552748e3d506 common/autoconf/basics.m4 --- a/common/autoconf/basics.m4 Thu Sep 22 16:41:14 2016 +0000 +++ b/common/autoconf/basics.m4 Wed Jul 05 22:16:00 2017 +0200 @@ -750,11 +750,6 @@ # Prepend the extra path to the global path BASIC_PREPEND_TO_PATH([PATH],$EXTRA_PATH) - if test "x$OPENJDK_BUILD_OS" = "xsolaris"; then - # Add extra search paths on solaris for utilities like ar, as, dtrace etc... - PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin:/usr/sbin" - fi - AC_MSG_CHECKING([for sysroot]) AC_MSG_RESULT([$SYSROOT]) AC_MSG_CHECKING([for toolchain path]) diff -r 8ced0dd94a6e -r 552748e3d506 common/autoconf/flags.m4 --- a/common/autoconf/flags.m4 Thu Sep 22 16:41:14 2016 +0000 +++ b/common/autoconf/flags.m4 Wed Jul 05 22:16:00 2017 +0200 @@ -88,8 +88,7 @@ # inlining of system functions and intrinsics. $1SYSROOT_CFLAGS="-I-xbuiltin -I[$]$1SYSROOT/usr/include" $1SYSROOT_LDFLAGS="-L[$]$1SYSROOT/usr/lib$OPENJDK_TARGET_CPU_ISADIR \ - -L[$]$1SYSROOT/lib$OPENJDK_TARGET_CPU_ISADIR \ - -L[$]$1SYSROOT/usr/ccs/lib$OPENJDK_TARGET_CPU_ISADIR" + -L[$]$1SYSROOT/lib$OPENJDK_TARGET_CPU_ISADIR" fi elif test "x$TOOLCHAIN_TYPE" = xgcc; then $1SYSROOT_CFLAGS="--sysroot=[$]$1SYSROOT" diff -r 8ced0dd94a6e -r 552748e3d506 common/autoconf/generated-configure.sh --- a/common/autoconf/generated-configure.sh Thu Sep 22 16:41:14 2016 +0000 +++ b/common/autoconf/generated-configure.sh Wed Jul 05 22:16:00 2017 +0200 @@ -926,9 +926,7 @@ INCLUDE_SA UNLIMITED_CRYPTO CACERTS_FILE -BUILD_HEADLESS -SUPPORT_HEADFUL -SUPPORT_HEADLESS +ENABLE_HEADLESS_ONLY DEFAULT_MAKE_TARGET OS_VERSION_MICRO OS_VERSION_MINOR @@ -1153,7 +1151,7 @@ with_conf_name with_output_sync with_default_make_target -enable_headful +enable_headless_only with_cacerts_file enable_unlimited_crypto with_copyright_year @@ -1976,8 +1974,7 @@ [disabled] --enable-debug set the debug level to fastdebug (shorthand for --with-debug-level=fastdebug) [disabled] - --disable-headful disable building headful support (graphical UI - support) [enabled] + --enable-headless-only only build headless (no GUI) support [disabled] --enable-unlimited-crypto Enable unlimited crypto policy [disabled] --disable-keep-packaged-modules @@ -5095,7 +5092,7 @@ #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1472718471 +DATE_WHEN_GENERATED=1474894604 ############################################################################### # @@ -17213,11 +17210,6 @@ fi - if test "x$OPENJDK_BUILD_OS" = "xsolaris"; then - # Add extra search paths on solaris for utilities like ar, as, dtrace etc... - PATH="$PATH:/usr/ccs/bin:/usr/sfw/bin:/opt/csw/bin:/usr/sbin" - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SYSROOT" >&5 @@ -24197,36 +24189,30 @@ # We need build & target for this. - # Should we build a JDK/JVM with headful support (ie a graphical ui)? - # We always build headless support. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking headful support" >&5 -$as_echo_n "checking headful support... " >&6; } - # Check whether --enable-headful was given. -if test "${enable_headful+set}" = set; then : - enableval=$enable_headful; SUPPORT_HEADFUL=${enable_headful} -else - SUPPORT_HEADFUL=yes -fi - - - SUPPORT_HEADLESS=yes - BUILD_HEADLESS="BUILD_HEADLESS:=true" - - if test "x$SUPPORT_HEADFUL" = xyes; then - # We are building both headful and headless. - headful_msg="include support for both headful and headless" - fi - - if test "x$SUPPORT_HEADFUL" = xno; then - # Thus we are building headless only. - BUILD_HEADLESS="BUILD_HEADLESS:=true" - headful_msg="headless only" - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $headful_msg" >&5 -$as_echo "$headful_msg" >&6; } - - + # Should we build a JDK without a graphical UI? + { $as_echo "$as_me:${as_lineno-$LINENO}: checking headless only" >&5 +$as_echo_n "checking headless only... " >&6; } + # Check whether --enable-headless-only was given. +if test "${enable_headless_only+set}" = set; then : + enableval=$enable_headless_only; +fi + + + if test "x$enable_headless_only" = "xyes"; then + ENABLE_HEADLESS_ONLY="true" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + elif test "x$enable_headless_only" = "xno"; then + ENABLE_HEADLESS_ONLY="false" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + elif test "x$enable_headless_only" = "x"; then + ENABLE_HEADLESS_ONLY="false" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + else + as_fn_error $? "--enable-headless-only can only take yes or no" "$LINENO" 5 + fi @@ -31475,8 +31461,7 @@ # inlining of system functions and intrinsics. SYSROOT_CFLAGS="-I-xbuiltin -I$SYSROOT/usr/include" SYSROOT_LDFLAGS="-L$SYSROOT/usr/lib$OPENJDK_TARGET_CPU_ISADIR \ - -L$SYSROOT/lib$OPENJDK_TARGET_CPU_ISADIR \ - -L$SYSROOT/usr/ccs/lib$OPENJDK_TARGET_CPU_ISADIR" + -L$SYSROOT/lib$OPENJDK_TARGET_CPU_ISADIR" fi elif test "x$TOOLCHAIN_TYPE" = xgcc; then SYSROOT_CFLAGS="--sysroot=$SYSROOT" @@ -32992,14 +32977,6 @@ fi - # For solaris we really need solaris tools, and not the GNU equivalent. - # The build tools on Solaris reside in /usr/ccs (C Compilation System), - # so add that to path before starting to probe. - # FIXME: This was originally only done for AS,NM,GNM,STRIP,OBJCOPY,OBJDUMP. - if test "x$OPENJDK_BUILD_OS" = xsolaris; then - PATH="/usr/ccs/bin:$PATH" - fi - # Finally add TOOLCHAIN_PATH at the beginning, to allow --with-tools-dir to # override all other locations. if test "x$TOOLCHAIN_PATH" != x; then @@ -44000,8 +43977,7 @@ # inlining of system functions and intrinsics. BUILD_SYSROOT_CFLAGS="-I-xbuiltin -I$BUILD_SYSROOT/usr/include" BUILD_SYSROOT_LDFLAGS="-L$BUILD_SYSROOT/usr/lib$OPENJDK_TARGET_CPU_ISADIR \ - -L$BUILD_SYSROOT/lib$OPENJDK_TARGET_CPU_ISADIR \ - -L$BUILD_SYSROOT/usr/ccs/lib$OPENJDK_TARGET_CPU_ISADIR" + -L$BUILD_SYSROOT/lib$OPENJDK_TARGET_CPU_ISADIR" fi elif test "x$TOOLCHAIN_TYPE" = xgcc; then BUILD_SYSROOT_CFLAGS="--sysroot=$BUILD_SYSROOT" @@ -53060,13 +53036,9 @@ # No X11 support on windows or macosx NEEDS_LIB_X11=false else - if test "x$SUPPORT_HEADFUL" = xno; then - # No X11 support if building headless-only - NEEDS_LIB_X11=false - else - # All other instances need X11 - NEEDS_LIB_X11=true - fi + # All other instances need X11, even if building headless only, libawt still + # needs X11 headers. + NEEDS_LIB_X11=true fi # Check if cups is needed @@ -56730,9 +56702,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then OPENWIN_HOME="/usr/openwin" X_CFLAGS="-I$SYSROOT$OPENWIN_HOME/include -I$SYSROOT$OPENWIN_HOME/include/X11/extensions" - X_LIBS="-L$SYSROOT$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ - -L$SYSROOT$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR \ - -R$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ + X_LIBS="-L$SYSROOT$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR \ -R$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR" fi @@ -56911,23 +56881,6 @@ fi if test "x$CUPS_FOUND" = xno; then - # Getting nervous now? Lets poke around for standard Solaris third-party - # package installation locations. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cups headers" >&5 -$as_echo_n "checking for cups headers... " >&6; } - if test -s $SYSROOT/opt/sfw/cups/include/cups/cups.h; then - # An SFW package seems to be installed! - CUPS_FOUND=yes - CUPS_CFLAGS="-I$SYSROOT/opt/sfw/cups/include" - elif test -s $SYSROOT/opt/csw/include/cups/cups.h; then - # A CSW package seems to be installed! - CUPS_FOUND=yes - CUPS_CFLAGS="-I$SYSROOT/opt/csw/include" - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CUPS_FOUND" >&5 -$as_echo "$CUPS_FOUND" >&6; } - fi - if test "x$CUPS_FOUND" = xno; then # Print a helpful message on how to acquire the necessary build dependency. # cups is the help tag: freetype, cups, alsa etc @@ -61167,346 +61120,6 @@ fi if test "x$FOUND_FREETYPE" != xyes; then - FREETYPE_BASE_DIR="$SYSROOT/usr/sfw" - - POTENTIAL_FREETYPE_INCLUDE_PATH="$FREETYPE_BASE_DIR/include" - POTENTIAL_FREETYPE_LIB_PATH="$FREETYPE_BASE_DIR/lib" - METHOD="well-known location" - - # Let's start with an optimistic view of the world :-) - FOUND_FREETYPE=yes - - # First look for the canonical freetype main include file ft2build.h. - if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # Oh no! Let's try in the freetype2 directory. This is needed at least at Mac OS X Yosemite. - POTENTIAL_FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH/freetype2" - if ! test -s "$POTENTIAL_FREETYPE_INCLUDE_PATH/ft2build.h"; then - # Fail. - FOUND_FREETYPE=no - fi - fi - - if test "x$FOUND_FREETYPE" = xyes; then - # Include file found, let's continue the sanity check. - { $as_echo "$as_me:${as_lineno-$LINENO}: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&5 -$as_echo "$as_me: Found freetype include files at $POTENTIAL_FREETYPE_INCLUDE_PATH using $METHOD" >&6;} - - # Reset to default value - FREETYPE_BASE_NAME=freetype - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then - if test "x$OPENJDK_TARGET_OS" = xmacosx \ - && test -s "$POTENTIAL_FREETYPE_LIB_PATH/${LIBRARY_PREFIX}freetype.6${SHARED_LIBRARY_SUFFIX}"; then - # On Mac OS X Yosemite, the symlink from libfreetype.dylib to libfreetype.6.dylib disappeared. Check - # for the .6 version explicitly. - FREETYPE_BASE_NAME=freetype.6 - FREETYPE_LIB_NAME="${LIBRARY_PREFIX}${FREETYPE_BASE_NAME}${SHARED_LIBRARY_SUFFIX}" - { $as_echo "$as_me:${as_lineno-$LINENO}: Compensating for missing symlink by using version 6 explicitly" >&5 -$as_echo "$as_me: Compensating for missing symlink by using version 6 explicitly" >&6;} - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location." >&6;} - FOUND_FREETYPE=no - fi - else - if test "x$OPENJDK_TARGET_OS" = xwindows; then - # On Windows, we will need both .lib and .dll file. - if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&5 -$as_echo "$as_me: Could not find $POTENTIAL_FREETYPE_LIB_PATH/${FREETYPE_BASE_NAME}.lib. Ignoring location." >&6;} - FOUND_FREETYPE=no - fi - elif test "x$OPENJDK_TARGET_OS" = xsolaris \ - && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then - # Found lib in isa dir, use that instead. - POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&5 -$as_echo "$as_me: Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead" >&6;} - fi - fi - fi - - if test "x$FOUND_FREETYPE" = xyes; then - - # Only process if variable expands to non-empty - - if test "x$POTENTIAL_FREETYPE_INCLUDE_PATH" != x; then - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - - # Input might be given as Windows format, start by converting to - # unix format. - path="$POTENTIAL_FREETYPE_INCLUDE_PATH" - 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 POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Cannot locate the the path of POTENTIAL_FREETYPE_INCLUDE_PATH" "$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-style (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 - POTENTIAL_FREETYPE_INCLUDE_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting POTENTIAL_FREETYPE_INCLUDE_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting POTENTIAL_FREETYPE_INCLUDE_PATH to \"$new_path\"" >&6;} - fi - - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - - path="$POTENTIAL_FREETYPE_INCLUDE_PATH" - 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 - POTENTIAL_FREETYPE_INCLUDE_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting POTENTIAL_FREETYPE_INCLUDE_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting POTENTIAL_FREETYPE_INCLUDE_PATH 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="$POTENTIAL_FREETYPE_INCLUDE_PATH" - has_space=`$ECHO "$path" | $GREP " "` - if test "x$has_space" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of POTENTIAL_FREETYPE_INCLUDE_PATH, 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 POTENTIAL_FREETYPE_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 - fi - - if test -d "$path"; then - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" - else - dir="`$DIRNAME "$path"`" - base="`$BASENAME "$path"`" - POTENTIAL_FREETYPE_INCLUDE_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" - fi - fi - fi - - - # Only process if variable expands to non-empty - - if test "x$POTENTIAL_FREETYPE_LIB_PATH" != x; then - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - - # Input might be given as Windows format, start by converting to - # unix format. - path="$POTENTIAL_FREETYPE_LIB_PATH" - 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 POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Cannot locate the the path of POTENTIAL_FREETYPE_LIB_PATH" "$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-style (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 - POTENTIAL_FREETYPE_LIB_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting POTENTIAL_FREETYPE_LIB_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting POTENTIAL_FREETYPE_LIB_PATH to \"$new_path\"" >&6;} - fi - - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - - path="$POTENTIAL_FREETYPE_LIB_PATH" - 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 - POTENTIAL_FREETYPE_LIB_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting POTENTIAL_FREETYPE_LIB_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting POTENTIAL_FREETYPE_LIB_PATH 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="$POTENTIAL_FREETYPE_LIB_PATH" - has_space=`$ECHO "$path" | $GREP " "` - if test "x$has_space" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of POTENTIAL_FREETYPE_LIB_PATH, 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 POTENTIAL_FREETYPE_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 - fi - - if test -d "$path"; then - POTENTIAL_FREETYPE_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" - else - dir="`$DIRNAME "$path"`" - base="`$BASENAME "$path"`" - POTENTIAL_FREETYPE_LIB_PATH="`cd "$dir"; $THEPWDCMD -L`/$base" - fi - fi - fi - - - FREETYPE_INCLUDE_PATH="$POTENTIAL_FREETYPE_INCLUDE_PATH" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetype includes" >&5 -$as_echo_n "checking for freetype includes... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FREETYPE_INCLUDE_PATH" >&5 -$as_echo "$FREETYPE_INCLUDE_PATH" >&6; } - FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for freetype libraries" >&5 -$as_echo_n "checking for freetype libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FREETYPE_LIB_PATH" >&5 -$as_echo "$FREETYPE_LIB_PATH" >&6; } - fi - - fi - - if test "x$FOUND_FREETYPE" != xyes; then FREETYPE_BASE_DIR="$SYSROOT/usr" if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then diff -r 8ced0dd94a6e -r 552748e3d506 common/autoconf/jdk-options.m4 --- a/common/autoconf/jdk-options.m4 Thu Sep 22 16:41:14 2016 +0000 +++ b/common/autoconf/jdk-options.m4 Wed Jul 05 22:16:00 2017 +0200 @@ -134,32 +134,25 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_OPTIONS], [ - # Should we build a JDK/JVM with headful support (ie a graphical ui)? - # We always build headless support. - AC_MSG_CHECKING([headful support]) - AC_ARG_ENABLE([headful], [AS_HELP_STRING([--disable-headful], - [disable building headful support (graphical UI support) @<:@enabled@:>@])], - [SUPPORT_HEADFUL=${enable_headful}], [SUPPORT_HEADFUL=yes]) + # Should we build a JDK without a graphical UI? + AC_MSG_CHECKING([headless only]) + AC_ARG_ENABLE([headless-only], [AS_HELP_STRING([--enable-headless-only], + [only build headless (no GUI) support @<:@disabled@:>@])]) - SUPPORT_HEADLESS=yes - BUILD_HEADLESS="BUILD_HEADLESS:=true" - - if test "x$SUPPORT_HEADFUL" = xyes; then - # We are building both headful and headless. - headful_msg="include support for both headful and headless" + if test "x$enable_headless_only" = "xyes"; then + ENABLE_HEADLESS_ONLY="true" + AC_MSG_RESULT([yes]) + elif test "x$enable_headless_only" = "xno"; then + ENABLE_HEADLESS_ONLY="false" + AC_MSG_RESULT([no]) + elif test "x$enable_headless_only" = "x"; then + ENABLE_HEADLESS_ONLY="false" + AC_MSG_RESULT([no]) + else + AC_MSG_ERROR([--enable-headless-only can only take yes or no]) fi - if test "x$SUPPORT_HEADFUL" = xno; then - # Thus we are building headless only. - BUILD_HEADLESS="BUILD_HEADLESS:=true" - headful_msg="headless only" - fi - - AC_MSG_RESULT([$headful_msg]) - - AC_SUBST(SUPPORT_HEADLESS) - AC_SUBST(SUPPORT_HEADFUL) - AC_SUBST(BUILD_HEADLESS) + AC_SUBST(ENABLE_HEADLESS_ONLY) # Choose cacerts source file AC_ARG_WITH(cacerts-file, [AS_HELP_STRING([--with-cacerts-file], diff -r 8ced0dd94a6e -r 552748e3d506 common/autoconf/lib-cups.m4 --- a/common/autoconf/lib-cups.m4 Thu Sep 22 16:41:14 2016 +0000 +++ b/common/autoconf/lib-cups.m4 Wed Jul 05 22:16:00 2017 +0200 @@ -76,21 +76,6 @@ ]) fi if test "x$CUPS_FOUND" = xno; then - # Getting nervous now? Lets poke around for standard Solaris third-party - # package installation locations. - AC_MSG_CHECKING([for cups headers]) - if test -s $SYSROOT/opt/sfw/cups/include/cups/cups.h; then - # An SFW package seems to be installed! - CUPS_FOUND=yes - CUPS_CFLAGS="-I$SYSROOT/opt/sfw/cups/include" - elif test -s $SYSROOT/opt/csw/include/cups/cups.h; then - # A CSW package seems to be installed! - CUPS_FOUND=yes - CUPS_CFLAGS="-I$SYSROOT/opt/csw/include" - fi - AC_MSG_RESULT([$CUPS_FOUND]) - fi - if test "x$CUPS_FOUND" = xno; then HELP_MSG_MISSING_DEPENDENCY([cups]) AC_MSG_ERROR([Could not find cups! $HELP_MSG ]) fi diff -r 8ced0dd94a6e -r 552748e3d506 common/autoconf/lib-freetype.m4 --- a/common/autoconf/lib-freetype.m4 Thu Sep 22 16:41:14 2016 +0000 +++ b/common/autoconf/lib-freetype.m4 Wed Jul 05 22:16:00 2017 +0200 @@ -358,11 +358,6 @@ fi if test "x$FOUND_FREETYPE" != xyes; then - FREETYPE_BASE_DIR="$SYSROOT/usr/sfw" - LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib], [well-known location]) - fi - - if test "x$FOUND_FREETYPE" != xyes; then FREETYPE_BASE_DIR="$SYSROOT/usr" if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then LIB_CHECK_POTENTIAL_FREETYPE([$FREETYPE_BASE_DIR/include], [$FREETYPE_BASE_DIR/lib/x86_64-linux-gnu], [well-known location]) diff -r 8ced0dd94a6e -r 552748e3d506 common/autoconf/lib-x11.m4 --- a/common/autoconf/lib-x11.m4 Thu Sep 22 16:41:14 2016 +0000 +++ b/common/autoconf/lib-x11.m4 Wed Jul 05 22:16:00 2017 +0200 @@ -91,9 +91,7 @@ if test "x$OPENJDK_TARGET_OS" = xsolaris; then OPENWIN_HOME="/usr/openwin" X_CFLAGS="-I$SYSROOT$OPENWIN_HOME/include -I$SYSROOT$OPENWIN_HOME/include/X11/extensions" - X_LIBS="-L$SYSROOT$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ - -L$SYSROOT$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR \ - -R$OPENWIN_HOME/sfw/lib$OPENJDK_TARGET_CPU_ISADIR \ + X_LIBS="-L$SYSROOT$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR \ -R$OPENWIN_HOME/lib$OPENJDK_TARGET_CPU_ISADIR" fi diff -r 8ced0dd94a6e -r 552748e3d506 common/autoconf/libraries.m4 --- a/common/autoconf/libraries.m4 Thu Sep 22 16:41:14 2016 +0000 +++ b/common/autoconf/libraries.m4 Wed Jul 05 22:16:00 2017 +0200 @@ -42,13 +42,9 @@ # No X11 support on windows or macosx NEEDS_LIB_X11=false else - if test "x$SUPPORT_HEADFUL" = xno; then - # No X11 support if building headless-only - NEEDS_LIB_X11=false - else - # All other instances need X11 - NEEDS_LIB_X11=true - fi + # All other instances need X11, even if building headless only, libawt still + # needs X11 headers. + NEEDS_LIB_X11=true fi # Check if cups is needed diff -r 8ced0dd94a6e -r 552748e3d506 common/autoconf/spec.gmk.in --- a/common/autoconf/spec.gmk.in Thu Sep 22 16:41:14 2016 +0000 +++ b/common/autoconf/spec.gmk.in Wed Jul 05 22:16:00 2017 +0200 @@ -241,12 +241,8 @@ # Control use of precompiled header in hotspot libjvm build USE_PRECOMPILED_HEADER := @USE_PRECOMPILED_HEADER@ -# Should we compile support for running with a graphical UI? (ie headful) -# Should we compile support for running without? (ie headless) -SUPPORT_HEADFUL:=@SUPPORT_HEADFUL@ -SUPPORT_HEADLESS:=@SUPPORT_HEADLESS@ -# Legacy defines controlled by the SUPPORT_HEADLESS and SUPPORT_HEADFUL options. -@BUILD_HEADLESS@ +# Only build headless support or not +ENABLE_HEADLESS_ONLY := @ENABLE_HEADLESS_ONLY@ # Legacy support USE_NEW_HOTSPOT_BUILD:=@USE_NEW_HOTSPOT_BUILD@ diff -r 8ced0dd94a6e -r 552748e3d506 common/autoconf/toolchain.m4 --- a/common/autoconf/toolchain.m4 Thu Sep 22 16:41:14 2016 +0000 +++ b/common/autoconf/toolchain.m4 Wed Jul 05 22:16:00 2017 +0200 @@ -294,14 +294,6 @@ fi AC_SUBST(TOOLCHAIN_VERSION) - # For solaris we really need solaris tools, and not the GNU equivalent. - # The build tools on Solaris reside in /usr/ccs (C Compilation System), - # so add that to path before starting to probe. - # FIXME: This was originally only done for AS,NM,GNM,STRIP,OBJCOPY,OBJDUMP. - if test "x$OPENJDK_BUILD_OS" = xsolaris; then - PATH="/usr/ccs/bin:$PATH" - fi - # Finally add TOOLCHAIN_PATH at the beginning, to allow --with-tools-dir to # override all other locations. if test "x$TOOLCHAIN_PATH" != x; then diff -r 8ced0dd94a6e -r 552748e3d506 common/conf/jib-profiles.js --- a/common/conf/jib-profiles.js Thu Sep 22 16:41:14 2016 +0000 +++ b/common/conf/jib-profiles.js Wed Jul 05 22:16:00 2017 +0200 @@ -224,6 +224,23 @@ common.configure_args_slowdebug = ["--with-debug-level=slowdebug"], common.organization = "jpg.infra.builddeps" + var boot_jdk_revision = "8"; + var boot_jdk_subdirpart = "1.8.0"; + // JDK 8 does not work on sparc M7 cpus, need a newer update when building + // on such hardware. + if (input.build_cpu == "sparcv9") { + var cpu_brand = $EXEC("bash -c \"kstat -m cpu_info | grep brand | head -n1 | awk '{ print \$2 }'\""); + if (cpu_brand.trim() == 'SPARC-M7') { + boot_jdk_revision = "8u20"; + boot_jdk_subdirpart = "1.8.0_20"; + } + } + common.boot_jdk_revision = boot_jdk_revision; + common.boot_jdk_subdirpart = boot_jdk_subdirpart; + common.boot_jdk_home = input.get("boot_jdk", "home_path") + "/jdk" + + common.boot_jdk_subdirpart + + (input.build_os == "macosx" ? ".jdk/Contents/Home" : ""); + return common; }; @@ -333,8 +350,11 @@ "run-test": { target_os: input.build_os, target_cpu: input.build_cpu, - dependencies: [ "jtreg", "gnumake" ], - labels: "test" + dependencies: [ "jtreg", "gnumake", "boot_jdk" ], + labels: "test", + environment: { + "JT_JAVA": common.boot_jdk_home + } } }; profiles = concatObjects(profiles, testOnlyProfiles); @@ -357,18 +377,6 @@ var boot_jdk_platform = input.build_os + "-" + (input.build_cpu == "x86" ? "i586" : input.build_cpu); - var boot_jdk_revision = "8"; - var boot_jdk_subdirpart = "1.8.0"; - // JDK 8 does not work on sparc M7 cpus, need a newer update when building - // on such hardware. - if (input.build_cpu == "sparcv9") { - var cpu_brand = $EXEC("bash -c \"kstat -m cpu_info | grep brand | head -n1 | awk '{ print \$2 }'\""); - if (cpu_brand.trim() == 'SPARC-M7') { - boot_jdk_revision = "8u20"; - boot_jdk_subdirpart = "1.8.0_20"; - } - } - var devkit_platform_revisions = { linux_x64: "gcc4.9.2-OEL6.4+1.0", macosx_x64: "Xcode6.3-MacOSX10.9+1.0", @@ -386,12 +394,12 @@ boot_jdk: { server: "javare", module: "jdk", - revision: boot_jdk_revision, + revision: common.boot_jdk_revision, checksum_file: boot_jdk_platform + "/MD5_VALUES", - file: boot_jdk_platform + "/jdk-" + boot_jdk_revision + "-" + boot_jdk_platform + ".tar.gz", - configure_args: (input.build_os == "macosx" - ? "--with-boot-jdk=" + input.get("boot_jdk", "install_path") + "/jdk" + boot_jdk_subdirpart + ".jdk/Contents/Home" - : "--with-boot-jdk=" + input.get("boot_jdk", "install_path") + "/jdk" + boot_jdk_subdirpart) + file: boot_jdk_platform + "/jdk-" + common.boot_jdk_revision + + "-" + boot_jdk_platform + ".tar.gz", + configure_args: "--with-boot-jdk=" + common.boot_jdk_home, + environment_path: common.boot_jdk_home }, devkit: { @@ -420,7 +428,8 @@ build_number: "b03", checksum_file: "MD5_VALUES", file: "jtreg_bin-4.2.zip", - environment_name: "JT_HOME" + environment_name: "JT_HOME", + environment_path: input.get("jtreg", "install_path") + "/jtreg/bin" }, gnumake: { diff -r 8ced0dd94a6e -r 552748e3d506 corba/.hgtags --- a/corba/.hgtags Thu Sep 22 16:41:14 2016 +0000 +++ b/corba/.hgtags Wed Jul 05 22:16:00 2017 +0200 @@ -379,3 +379,4 @@ 1a497f5ca0cfd88115cc7daa8af8a62b8741caf2 jdk-9+134 094d0db606db976045f594dba47d4593b715cc81 jdk-9+135 aa053a3faf266c12b4fd5272da431a3e08e4a3e3 jdk-9+136 +258cf18fa7fc59359b874f8743b7168dc48baf73 jdk-9+137 diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/.hgtags --- a/hotspot/.hgtags Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/.hgtags Wed Jul 05 22:16:00 2017 +0200 @@ -539,3 +539,4 @@ b8b694c6b4d2ab0939aed7adaf0eec1ac321a085 jdk-9+134 3b1c4562953db47e36b237a500f368d5c9746d47 jdk-9+135 a20da289f646ee44440695b81abc0548330e4ca7 jdk-9+136 +dfcbf839e299e7e2bba1da69bdb347617ea4c7e8 jdk-9+137 diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/make/test/JtregNative.gmk --- a/hotspot/make/test/JtregNative.gmk Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/make/test/JtregNative.gmk Wed Jul 05 22:16:00 2017 +0200 @@ -44,6 +44,7 @@ $(HOTSPOT_TOPDIR)/test/native_sanity \ $(HOTSPOT_TOPDIR)/test/runtime/jni/8025979 \ $(HOTSPOT_TOPDIR)/test/runtime/jni/8033445 \ + $(HOTSPOT_TOPDIR)/test/runtime/jni/checked \ $(HOTSPOT_TOPDIR)/test/runtime/jni/ToStringInInterfaceTest \ $(HOTSPOT_TOPDIR)/test/runtime/modules/getModuleJNI \ $(HOTSPOT_TOPDIR)/test/runtime/SameObject \ diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp --- a/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/aarch64/vm/interp_masm_aarch64.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -326,7 +326,8 @@ } void InterpreterMacroAssembler::push_l(Register r) { - str(r, pre(esp, 2 * -wordSize)); + str(zr, pre(esp, -wordSize)); + str(r, pre(esp, -wordsize)); } void InterpreterMacroAssembler::pop_f(FloatRegister r) { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp --- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -2041,6 +2041,11 @@ __ verify_oop(r0); } + if (CheckJNICalls) { + // clear_pending_jni_exception_check + __ str(zr, Address(rthread, JavaThread::pending_jni_exception_check_fn_offset())); + } + if (!is_critical_native) { // reset handle block __ ldr(r2, Address(rthread, JavaThread::active_handles_offset())); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp --- a/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -1355,6 +1355,11 @@ // reset_last_Java_frame __ reset_last_Java_frame(true); + if (CheckJNICalls) { + // clear_pending_jni_exception_check + __ str(zr, Address(rthread, JavaThread::pending_jni_exception_check_fn_offset())); + } + // reset handle block __ ldr(t, Address(rthread, JavaThread::active_handles_offset())); __ str(zr, Address(t, JNIHandleBlock::top_offset_in_bytes())); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/sparc/vm/globals_sparc.hpp --- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -57,10 +57,12 @@ #ifdef _LP64 // Stack slots are 2X larger in LP64 than in the 32 bit VM. +define_pd_global(intx, CompilerThreadStackSize, 1024); define_pd_global(intx, ThreadStackSize, 1024); define_pd_global(intx, VMThreadStackSize, 1024); #define DEFAULT_STACK_SHADOW_PAGES (20 DEBUG_ONLY(+2)) #else +define_pd_global(intx, CompilerThreadStackSize, 512); define_pd_global(intx, ThreadStackSize, 512); define_pd_global(intx, VMThreadStackSize, 512); #define DEFAULT_STACK_SHADOW_PAGES (6 DEBUG_ONLY(+2)) diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -359,7 +359,7 @@ #ifdef _LP64 stx(l, r1, offset); // store something more useful here - debug_only(stx(G0, r1, offset+Interpreter::stackElementSize);) + stx(G0, r1, offset+Interpreter::stackElementSize); #else st(l, r1, offset); st(l->successor(), r1, offset + Interpreter::stackElementSize); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -2765,6 +2765,11 @@ __ verify_oop(I0); } + if (CheckJNICalls) { + // clear_pending_jni_exception_check + __ st_ptr(G0, G2_thread, JavaThread::pending_jni_exception_check_fn_offset()); + } + if (!is_critical_native) { // reset handle block __ ld_ptr(G2_thread, in_bytes(JavaThread::active_handles_offset()), L5); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/sparc/vm/sparc.ad --- a/hotspot/src/cpu/sparc/vm/sparc.ad Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/sparc/vm/sparc.ad Wed Jul 05 22:16:00 2017 +0200 @@ -2921,6 +2921,26 @@ __ cmp( Rold, O7 ); %} + // raw int cas without using tmp register for compareAndExchange + enc_class enc_casi_exch( iRegP mem, iRegL old, iRegL new) %{ + Register Rmem = reg_to_register_object($mem$$reg); + Register Rold = reg_to_register_object($old$$reg); + Register Rnew = reg_to_register_object($new$$reg); + + MacroAssembler _masm(&cbuf); + __ cas(Rmem, Rold, Rnew); + %} + + // 64-bit cas without using tmp register for compareAndExchange + enc_class enc_casx_exch( iRegP mem, iRegL old, iRegL new) %{ + Register Rmem = reg_to_register_object($mem$$reg); + Register Rold = reg_to_register_object($old$$reg); + Register Rnew = reg_to_register_object($new$$reg); + + MacroAssembler _masm(&cbuf); + __ casx(Rmem, Rold, Rnew); + %} + enc_class enc_lflags_ne_to_boolean( iRegI res ) %{ Register Rres = reg_to_register_object($res$$reg); @@ -7105,6 +7125,7 @@ instruct compareAndSwapL_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ predicate(VM_Version::supports_cx8()); match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); + match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); effect( USE mem_ptr, KILL ccr, KILL tmp1); format %{ "MOV $newval,O7\n\t" @@ -7121,6 +7142,7 @@ instruct compareAndSwapI_bool(iRegP mem_ptr, iRegI oldval, iRegI newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); + match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); effect( USE mem_ptr, KILL ccr, KILL tmp1); format %{ "MOV $newval,O7\n\t" @@ -7139,6 +7161,7 @@ predicate(VM_Version::supports_cx8()); #endif match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); + match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); effect( USE mem_ptr, KILL ccr, KILL tmp1); format %{ "MOV $newval,O7\n\t" @@ -7159,6 +7182,7 @@ instruct compareAndSwapN_bool(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{ match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); + match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); effect( USE mem_ptr, KILL ccr, KILL tmp1); format %{ "MOV $newval,O7\n\t" @@ -7172,6 +7196,54 @@ ins_pipe( long_memory_op ); %} +instruct compareAndExchangeI(iRegP mem_ptr, iRegI oldval, iRegI newval) +%{ + match(Set newval (CompareAndExchangeI mem_ptr (Binary oldval newval))); + effect( USE mem_ptr ); + + format %{ + "CASA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr] and set $newval=[$mem_ptr]\n\t" + %} + ins_encode( enc_casi_exch(mem_ptr, oldval, newval) ); + ins_pipe( long_memory_op ); +%} + +instruct compareAndExchangeL(iRegP mem_ptr, iRegL oldval, iRegL newval) +%{ + match(Set newval (CompareAndExchangeL mem_ptr (Binary oldval newval))); + effect( USE mem_ptr ); + + format %{ + "CASXA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr] and set $newval=[$mem_ptr]\n\t" + %} + ins_encode( enc_casx_exch(mem_ptr, oldval, newval) ); + ins_pipe( long_memory_op ); +%} + +instruct compareAndExchangeP(iRegP mem_ptr, iRegP oldval, iRegP newval) +%{ + match(Set newval (CompareAndExchangeP mem_ptr (Binary oldval newval))); + effect( USE mem_ptr ); + + format %{ + "CASXA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr] and set $newval=[$mem_ptr]\n\t" + %} + ins_encode( enc_casx_exch(mem_ptr, oldval, newval) ); + ins_pipe( long_memory_op ); +%} + +instruct compareAndExchangeN(iRegP mem_ptr, iRegN oldval, iRegN newval) +%{ + match(Set newval (CompareAndExchangeN mem_ptr (Binary oldval newval))); + effect( USE mem_ptr ); + + format %{ + "CASA [$mem_ptr],$oldval,$newval\t! If $oldval==[$mem_ptr] Then store $newval into [$mem_ptr] and set $newval=[$mem_ptr]\n\t" + %} + ins_encode( enc_casi_exch(mem_ptr, oldval, newval) ); + ins_pipe( long_memory_op ); +%} + instruct xchgI( memory mem, iRegI newval) %{ match(Set newval (GetAndSetI mem newval)); format %{ "SWAP [$mem],$newval" %} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -1487,6 +1487,11 @@ __ set(_thread_in_Java, G3_scratch); __ st(G3_scratch, thread_state); + if (CheckJNICalls) { + // clear_pending_jni_exception_check + __ st_ptr(G0, G2_thread, JavaThread::pending_jni_exception_check_fn_offset()); + } + // reset handle block __ ld_ptr(G2_thread, JavaThread::active_handles_offset(), G3_scratch); __ st(G0, G3_scratch, JNIHandleBlock::top_offset_in_bytes()); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/x86/vm/interp_masm_x86.cpp --- a/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -611,7 +611,8 @@ void InterpreterMacroAssembler::push_l(Register r) { subptr(rsp, 2 * wordSize); - movq(Address(rsp, 0), r); + movptr(Address(rsp, Interpreter::expr_offset_in_bytes(0)), r ); + movptr(Address(rsp, Interpreter::expr_offset_in_bytes(1)), NULL_WORD ); } void InterpreterMacroAssembler::pop(TosState state) { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp --- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -8131,8 +8131,7 @@ jmp(FALSE_LABEL); clear_vector_masking(); // closing of the stub context for programming mask registers - } - else { + } else { movl(result, len); // copy if (UseAVX == 2 && UseSSE >= 2) { @@ -8169,8 +8168,7 @@ bind(COMPARE_TAIL); // len is zero movl(len, result); // Fallthru to tail compare - } - else if (UseSSE42Intrinsics) { + } else if (UseSSE42Intrinsics) { // With SSE4.2, use double quad vector compare Label COMPARE_WIDE_VECTORS, COMPARE_TAIL; @@ -10748,7 +10746,10 @@ // save length for return push(len); + // 8165287: EVEX version disabled for now, needs to be refactored as + // it is returning incorrect results. if ((UseAVX > 2) && // AVX512 + 0 && VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()) { @@ -11067,10 +11068,11 @@ bind(below_threshold); bind(copy_new_tail); - if (UseAVX > 2) { + if ((UseAVX > 2) && + VM_Version::supports_avx512vlbw() && + VM_Version::supports_bmi2()) { movl(tmp2, len); - } - else { + } else { movl(len, tmp2); } andl(tmp2, 0x00000007); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -2236,6 +2236,11 @@ __ verify_oop(rax); } + if (CheckJNICalls) { + // clear_pending_jni_exception_check + __ movptr(Address(thread, JavaThread::pending_jni_exception_check_fn_offset()), NULL_WORD); + } + if (!is_critical_native) { // reset handle block __ movptr(rcx, Address(thread, JavaThread::active_handles_offset())); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -2589,6 +2589,11 @@ __ verify_oop(rax); } + if (CheckJNICalls) { + // clear_pending_jni_exception_check + __ movptr(Address(r15_thread, JavaThread::pending_jni_exception_check_fn_offset()), NULL_WORD); + } + if (!is_critical_native) { // reset handle block __ movptr(rcx, Address(r15_thread, JavaThread::active_handles_offset())); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp --- a/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -1169,6 +1169,11 @@ // reset_last_Java_frame __ reset_last_Java_frame(thread, true); + if (CheckJNICalls) { + // clear_pending_jni_exception_check + __ movptr(Address(thread, JavaThread::pending_jni_exception_check_fn_offset()), NULL_WORD); + } + // reset handle block __ movptr(t, Address(thread, JavaThread::active_handles_offset())); __ movl(Address(t, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/GrowableArray.java --- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/GrowableArray.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/GrowableArray.java Wed Jul 05 22:16:00 2017 +0200 @@ -65,4 +65,7 @@ super(addr); virtualConstructor = v; } + public Address getData() { + return dataField.getValue(getAddress()); + } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Jul 05 22:16:00 2017 +0200 @@ -366,8 +366,8 @@ * {@code exactReceiver}. * * @param caller the caller or context type used to perform access checks - * @return the link-time resolved method (might be abstract) or {@code 0} if it can not be - * linked + * @return the link-time resolved method (might be abstract) or {@code null} if it is either a + * signature polymorphic method or can not be linked. */ native HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl exactReceiver, HotSpotResolvedJavaMethodImpl method, HotSpotResolvedObjectTypeImpl caller); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Wed Jul 05 22:16:00 2017 +0200 @@ -722,7 +722,7 @@ /** * Determines if {@code type} contains signature polymorphic methods. */ - private static boolean isSignaturePolymorphicHolder(final HotSpotResolvedObjectTypeImpl type) { + static boolean isSignaturePolymorphicHolder(final ResolvedJavaType type) { String name = type.getName(); if (signaturePolymorphicHolders == null) { signaturePolymorphicHolders = compilerToVM().getSignaturePolymorphicHolders(); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Wed Jul 05 22:16:00 2017 +0200 @@ -24,6 +24,7 @@ import static java.util.Objects.requireNonNull; import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM; +import static jdk.vm.ci.hotspot.HotSpotConstantPool.isSignaturePolymorphicHolder; import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; @@ -426,7 +427,7 @@ // Methods can only be resolved against concrete types return null; } - if (method.isConcrete() && method.getDeclaringClass().equals(this) && method.isPublic()) { + if (method.isConcrete() && method.getDeclaringClass().equals(this) && method.isPublic() && !isSignaturePolymorphicHolder(method.getDeclaringClass())) { return method; } if (!method.getDeclaringClass().isAssignableFrom(this)) { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java --- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java Wed Jul 05 22:16:00 2017 +0200 @@ -209,8 +209,8 @@ * * @param method the method to select the implementation of * @param callerType the caller or context type used to perform access checks - * @return the method that would be selected at runtime (might be abstract) or {@code null} if - * it can not be resolved + * @return the link-time resolved method (might be abstract) or {@code null} if it is either a + * signature polymorphic method or can not be linked. */ ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os/aix/vm/os_aix.cpp --- a/hotspot/src/os/aix/vm/os_aix.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -847,7 +847,8 @@ return 0; } -bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { +bool os::create_thread(Thread* thread, ThreadType thr_type, + size_t req_stack_size) { assert(thread->osthread() == NULL, "caller responsible"); @@ -880,37 +881,12 @@ guarantee(pthread_attr_setsuspendstate_np(&attr, PTHREAD_CREATE_SUSPENDED_NP) == 0, "???"); // calculate stack size if it's not specified by caller - if (stack_size == 0) { - stack_size = os::Aix::default_stack_size(thr_type); - - switch (thr_type) { - case os::java_thread: - // Java threads use ThreadStackSize whose default value can be changed with the flag -Xss. - assert(JavaThread::stack_size_at_create() > 0, "this should be set"); - stack_size = JavaThread::stack_size_at_create(); - break; - case os::compiler_thread: - if (CompilerThreadStackSize > 0) { - stack_size = (size_t)(CompilerThreadStackSize * K); - break; - } // else fall through: - // use VMThreadStackSize if CompilerThreadStackSize is not defined - case os::vm_thread: - case os::pgc_thread: - case os::cgc_thread: - case os::watcher_thread: - if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K); - break; - } - } - - stack_size = MAX2(stack_size, os::Aix::min_stack_allowed); + size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size); pthread_attr_setstacksize(&attr, stack_size); pthread_t tid; int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread); - char buf[64]; if (ret == 0) { log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ", @@ -3593,32 +3569,11 @@ Aix::signal_sets_init(); Aix::install_signal_handlers(); - // Check minimum allowable stack size for thread creation and to initialize - // the java system classes, including StackOverflowError - depends on page - // size. Add two 4K pages for compiler2 recursion in main thread. - // Add in 4*BytesPerWord 4K pages to account for VM stack during - // class initialization depending on 32 or 64 bit VM. - os::Aix::min_stack_allowed = MAX2(os::Aix::min_stack_allowed, - JavaThread::stack_guard_zone_size() + - JavaThread::stack_shadow_zone_size() + - (4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K); - - os::Aix::min_stack_allowed = align_size_up(os::Aix::min_stack_allowed, os::vm_page_size()); - - size_t threadStackSizeInBytes = ThreadStackSize * K; - if (threadStackSizeInBytes != 0 && - threadStackSizeInBytes < os::Aix::min_stack_allowed) { - tty->print_cr("\nThe stack size specified is too small, " - "Specify at least %dk", - os::Aix::min_stack_allowed / K); + // Check and sets minimum stack sizes against command line options + if (Posix::set_minimum_stack_sizes() == JNI_ERR) { return JNI_ERR; } - // Make the stack size a multiple of the page size so that - // the yellow/red zones can be guarded. - // Note that this can be 0, if no default stacksize was set. - JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, vm_page_size())); - if (UseNUMA) { UseNUMA = false; warning("NUMA optimizations are not available on this OS."); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os/aix/vm/os_aix.hpp --- a/hotspot/src/os/aix/vm/os_aix.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os/aix/vm/os_aix.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -140,14 +140,6 @@ // libpthread version string static void libpthread_init(); - // Minimum stack size a thread can be created with (allowing - // the VM to completely create the thread and enter user code) - static size_t min_stack_allowed; - - // Return default stack size or guard size for the specified thread type - static size_t default_stack_size(os::ThreadType thr_type); - static size_t default_guard_size(os::ThreadType thr_type); - // Function returns true if we run on OS/400 (pase), false if we run // on AIX. static bool on_pase() { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -734,7 +734,8 @@ return 0; } -bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { +bool os::create_thread(Thread* thread, ThreadType thr_type, + size_t req_stack_size) { assert(thread->osthread() == NULL, "caller responsible"); // Allocate the OSThread object @@ -757,32 +758,7 @@ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // calculate stack size if it's not specified by caller - if (stack_size == 0) { - stack_size = os::Bsd::default_stack_size(thr_type); - - switch (thr_type) { - case os::java_thread: - // Java threads use ThreadStackSize which default value can be - // changed with the flag -Xss - assert(JavaThread::stack_size_at_create() > 0, "this should be set"); - stack_size = JavaThread::stack_size_at_create(); - break; - case os::compiler_thread: - if (CompilerThreadStackSize > 0) { - stack_size = (size_t)(CompilerThreadStackSize * K); - break; - } // else fall through: - // use VMThreadStackSize if CompilerThreadStackSize is not defined - case os::vm_thread: - case os::pgc_thread: - case os::cgc_thread: - case os::watcher_thread: - if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K); - break; - } - } - - stack_size = MAX2(stack_size, os::Bsd::min_stack_allowed); + size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size); pthread_attr_setstacksize(&attr, stack_size); ThreadState state; @@ -3502,32 +3478,11 @@ Bsd::signal_sets_init(); Bsd::install_signal_handlers(); - // Check minimum allowable stack size for thread creation and to initialize - // the java system classes, including StackOverflowError - depends on page - // size. Add two 4K pages for compiler2 recursion in main thread. - // Add in 4*BytesPerWord 4K pages to account for VM stack during - // class initialization depending on 32 or 64 bit VM. - os::Bsd::min_stack_allowed = MAX2(os::Bsd::min_stack_allowed, - JavaThread::stack_guard_zone_size() + - JavaThread::stack_shadow_zone_size() + - (4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K); - - os::Bsd::min_stack_allowed = align_size_up(os::Bsd::min_stack_allowed, os::vm_page_size()); - - size_t threadStackSizeInBytes = ThreadStackSize * K; - if (threadStackSizeInBytes != 0 && - threadStackSizeInBytes < os::Bsd::min_stack_allowed) { - tty->print_cr("\nThe stack size specified is too small, " - "Specify at least %dk", - os::Bsd::min_stack_allowed/ K); + // Check and sets minimum stack sizes against command line options + if (Posix::set_minimum_stack_sizes() == JNI_ERR) { return JNI_ERR; } - // Make the stack size a multiple of the page size so that - // the yellow/red zones can be guarded. - JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, - vm_page_size())); - if (MaxFDLimit) { // set the number of file descriptors to max. print out error // if getrlimit/setrlimit fails but continue regardless. diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os/bsd/vm/os_bsd.hpp --- a/hotspot/src/os/bsd/vm/os_bsd.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os/bsd/vm/os_bsd.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -120,14 +120,6 @@ static struct sigaction *get_chained_signal_action(int sig); static bool chained_handler(int sig, siginfo_t* siginfo, void* context); - // Minimum stack size a thread can be created with (allowing - // the VM to completely create the thread and enter user code) - static size_t min_stack_allowed; - - // Return default stack size or guard size for the specified thread type - static size_t default_stack_size(os::ThreadType thr_type); - static size_t default_guard_size(os::ThreadType thr_type); - // Real-time clock functions static void clock_init(void); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -701,7 +701,7 @@ } bool os::create_thread(Thread* thread, ThreadType thr_type, - size_t stack_size) { + size_t req_stack_size) { assert(thread->osthread() == NULL, "caller responsible"); // Allocate the OSThread object @@ -723,34 +723,8 @@ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - // stack size // calculate stack size if it's not specified by caller - if (stack_size == 0) { - stack_size = os::Linux::default_stack_size(thr_type); - - switch (thr_type) { - case os::java_thread: - // Java threads use ThreadStackSize which default value can be - // changed with the flag -Xss - assert(JavaThread::stack_size_at_create() > 0, "this should be set"); - stack_size = JavaThread::stack_size_at_create(); - break; - case os::compiler_thread: - if (CompilerThreadStackSize > 0) { - stack_size = (size_t)(CompilerThreadStackSize * K); - break; - } // else fall through: - // use VMThreadStackSize if CompilerThreadStackSize is not defined - case os::vm_thread: - case os::pgc_thread: - case os::cgc_thread: - case os::watcher_thread: - if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K); - break; - } - } - - stack_size = MAX2(stack_size, os::Linux::min_stack_allowed); + size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size); pthread_attr_setstacksize(&attr, stack_size); // glibc guard page @@ -956,10 +930,9 @@ // bogus value for initial thread. void os::Linux::capture_initial_stack(size_t max_size) { // stack size is the easy part, get it from RLIMIT_STACK - size_t stack_size; struct rlimit rlim; getrlimit(RLIMIT_STACK, &rlim); - stack_size = rlim.rlim_cur; + size_t stack_size = rlim.rlim_cur; // 6308388: a bug in ld.so will relocate its own .data section to the // lower end of primordial stack; reduce ulimit -s value a little bit @@ -4793,32 +4766,10 @@ Linux::signal_sets_init(); Linux::install_signal_handlers(); - // Check minimum allowable stack size for thread creation and to initialize - // the java system classes, including StackOverflowError - depends on page - // size. Add two 4K pages for compiler2 recursion in main thread. - // Add in 4*BytesPerWord 4K pages to account for VM stack during - // class initialization depending on 32 or 64 bit VM. - os::Linux::min_stack_allowed = MAX2(os::Linux::min_stack_allowed, - JavaThread::stack_guard_zone_size() + - JavaThread::stack_shadow_zone_size() + - (4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K); - - os::Linux::min_stack_allowed = align_size_up(os::Linux::min_stack_allowed, os::vm_page_size()); - - size_t threadStackSizeInBytes = ThreadStackSize * K; - if (threadStackSizeInBytes != 0 && - threadStackSizeInBytes < os::Linux::min_stack_allowed) { - tty->print_cr("\nThe stack size specified is too small, " - "Specify at least " SIZE_FORMAT "k", - os::Linux::min_stack_allowed/ K); + // Check and sets minimum stack sizes against command line options + if (Posix::set_minimum_stack_sizes() == JNI_ERR) { return JNI_ERR; } - - // Make the stack size a multiple of the page size so that - // the yellow/red zones can be guarded. - JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, - vm_page_size())); - Linux::capture_initial_stack(JavaThread::stack_size_at_create()); #if defined(IA32) diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os/linux/vm/os_linux.hpp --- a/hotspot/src/os/linux/vm/os_linux.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os/linux/vm/os_linux.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -170,12 +170,8 @@ static void libpthread_init(); static bool libnuma_init(); static void* libnuma_dlsym(void* handle, const char* name); - // Minimum stack size a thread can be created with (allowing - // the VM to completely create the thread and enter user code) - static size_t min_stack_allowed; - // Return default stack size or guard size for the specified thread type - static size_t default_stack_size(os::ThreadType thr_type); + // Return default guard size for the specified thread type static size_t default_guard_size(os::ThreadType thr_type); static void capture_initial_stack(size_t max_size); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os/posix/vm/os_posix.cpp --- a/hotspot/src/os/posix/vm/os_posix.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os/posix/vm/os_posix.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -1099,6 +1099,123 @@ return buf; } +// Check minimum allowable stack sizes for thread creation and to initialize +// the java system classes, including StackOverflowError - depends on page +// size. Add two 4K pages for compiler2 recursion in main thread. +// Add in 4*BytesPerWord 4K pages to account for VM stack during +// class initialization depending on 32 or 64 bit VM. +jint os::Posix::set_minimum_stack_sizes() { + _java_thread_min_stack_allowed = MAX2(_java_thread_min_stack_allowed, + JavaThread::stack_guard_zone_size() + + JavaThread::stack_shadow_zone_size() + + (4 * BytesPerWord COMPILER2_PRESENT(+ 2)) * 4 * K); + + _java_thread_min_stack_allowed = align_size_up(_java_thread_min_stack_allowed, vm_page_size()); + + size_t stack_size_in_bytes = ThreadStackSize * K; + if (stack_size_in_bytes != 0 && + stack_size_in_bytes < _java_thread_min_stack_allowed) { + // The '-Xss' and '-XX:ThreadStackSize=N' options both set + // ThreadStackSize so we go with "Java thread stack size" instead + // of "ThreadStackSize" to be more friendly. + tty->print_cr("\nThe Java thread stack size specified is too small. " + "Specify at least " SIZE_FORMAT "k", + _java_thread_min_stack_allowed / K); + return JNI_ERR; + } + +#ifdef SOLARIS + // For 64kbps there will be a 64kb page size, which makes + // the usable default stack size quite a bit less. Increase the + // stack for 64kb (or any > than 8kb) pages, this increases + // virtual memory fragmentation (since we're not creating the + // stack on a power of 2 boundary. The real fix for this + // should be to fix the guard page mechanism. + + if (vm_page_size() > 8*K) { + stack_size_in_bytes = (stack_size_in_bytes != 0) + ? stack_size_in_bytes + + JavaThread::stack_red_zone_size() + + JavaThread::stack_yellow_zone_size() + : 0; + ThreadStackSize = stack_size_in_bytes/K; + } +#endif // SOLARIS + + // Make the stack size a multiple of the page size so that + // the yellow/red zones can be guarded. + JavaThread::set_stack_size_at_create(round_to(stack_size_in_bytes, + vm_page_size())); + + _compiler_thread_min_stack_allowed = align_size_up(_compiler_thread_min_stack_allowed, vm_page_size()); + + stack_size_in_bytes = CompilerThreadStackSize * K; + if (stack_size_in_bytes != 0 && + stack_size_in_bytes < _compiler_thread_min_stack_allowed) { + tty->print_cr("\nThe CompilerThreadStackSize specified is too small. " + "Specify at least " SIZE_FORMAT "k", + _compiler_thread_min_stack_allowed / K); + return JNI_ERR; + } + + _vm_internal_thread_min_stack_allowed = align_size_up(_vm_internal_thread_min_stack_allowed, vm_page_size()); + + stack_size_in_bytes = VMThreadStackSize * K; + if (stack_size_in_bytes != 0 && + stack_size_in_bytes < _vm_internal_thread_min_stack_allowed) { + tty->print_cr("\nThe VMThreadStackSize specified is too small. " + "Specify at least " SIZE_FORMAT "k", + _vm_internal_thread_min_stack_allowed / K); + return JNI_ERR; + } + return JNI_OK; +} + +// Called when creating the thread. The minimum stack sizes have already been calculated +size_t os::Posix::get_initial_stack_size(ThreadType thr_type, size_t req_stack_size) { + size_t stack_size; + if (req_stack_size == 0) { + stack_size = default_stack_size(thr_type); + } else { + stack_size = req_stack_size; + } + + switch (thr_type) { + case os::java_thread: + // Java threads use ThreadStackSize which default value can be + // changed with the flag -Xss + if (req_stack_size == 0 && JavaThread::stack_size_at_create() > 0) { + // no requested size and we have a more specific default value + stack_size = JavaThread::stack_size_at_create(); + } + stack_size = MAX2(stack_size, + _java_thread_min_stack_allowed); + break; + case os::compiler_thread: + if (req_stack_size == 0 && CompilerThreadStackSize > 0) { + // no requested size and we have a more specific default value + stack_size = (size_t)(CompilerThreadStackSize * K); + } + stack_size = MAX2(stack_size, + _compiler_thread_min_stack_allowed); + break; + case os::vm_thread: + case os::pgc_thread: + case os::cgc_thread: + case os::watcher_thread: + default: // presume the unknown thr_type is a VM internal + if (req_stack_size == 0 && VMThreadStackSize > 0) { + // no requested size and we have a more specific default value + stack_size = (size_t)(VMThreadStackSize * K); + } + + stack_size = MAX2(stack_size, + _vm_internal_thread_min_stack_allowed); + break; + } + + return stack_size; +} os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os/posix/vm/os_posix.hpp --- a/hotspot/src/os/posix/vm/os_posix.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os/posix/vm/os_posix.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,18 @@ static void print_libversion_info(outputStream* st); static void print_load_average(outputStream* st); + // Minimum stack size a thread can be created with (allowing + // the VM to completely create the thread and enter user code) + static size_t _compiler_thread_min_stack_allowed; + static size_t _java_thread_min_stack_allowed; + static size_t _vm_internal_thread_min_stack_allowed; + public: + // Return default stack size for the specified thread type + static size_t default_stack_size(os::ThreadType thr_type); + // Check and sets minimum stack sizes + static jint set_minimum_stack_sizes(); + static size_t get_initial_stack_size(ThreadType thr_type, size_t req_stack_size); // Returns true if signal is valid. static bool is_valid_signal(int sig); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -917,8 +917,15 @@ return buf; } +// return default stack size for thr_type +size_t os::Posix::default_stack_size(os::ThreadType thr_type) { + // default stack size when not specified by caller is 1M (2M for LP64) + size_t s = (BytesPerWord >> 2) * K * K; + return s; +} + bool os::create_thread(Thread* thread, ThreadType thr_type, - size_t stack_size) { + size_t req_stack_size) { // Allocate the OSThread object OSThread* osthread = new OSThread(NULL, NULL); if (osthread == NULL) { @@ -953,31 +960,8 @@ tty->print_cr("In create_thread, creating a %s thread\n", thrtyp); } - // Calculate stack size if it's not specified by caller. - if (stack_size == 0) { - // The default stack size 1M (2M for LP64). - stack_size = (BytesPerWord >> 2) * K * K; - - switch (thr_type) { - case os::java_thread: - // Java threads use ThreadStackSize which default value can be changed with the flag -Xss - if (JavaThread::stack_size_at_create() > 0) stack_size = JavaThread::stack_size_at_create(); - break; - case os::compiler_thread: - if (CompilerThreadStackSize > 0) { - stack_size = (size_t)(CompilerThreadStackSize * K); - break; - } // else fall through: - // use VMThreadStackSize if CompilerThreadStackSize is not defined - case os::vm_thread: - case os::pgc_thread: - case os::cgc_thread: - case os::watcher_thread: - if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K); - break; - } - } - stack_size = MAX2(stack_size, os::Solaris::min_stack_allowed); + // calculate stack size if it's not specified by caller + size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size); // Initial state is ALLOCATED but not INITIALIZED osthread->set_state(ALLOCATED); @@ -4400,7 +4384,12 @@ // Constant minimum stack size allowed. It must be at least // the minimum of what the OS supports (thr_min_stack()), and // enough to allow the thread to get to user bytecode execution. - Solaris::min_stack_allowed = MAX2(thr_min_stack(), Solaris::min_stack_allowed); + Posix::_compiler_thread_min_stack_allowed = MAX2(thr_min_stack(), + Posix::_compiler_thread_min_stack_allowed); + Posix::_java_thread_min_stack_allowed = MAX2(thr_min_stack(), + Posix::_java_thread_min_stack_allowed); + Posix::_vm_internal_thread_min_stack_allowed = MAX2(thr_min_stack(), + Posix::_vm_internal_thread_min_stack_allowed); // dynamic lookup of functions that may not be available in our lowest // supported Solaris release @@ -4445,47 +4434,11 @@ log_info(os)("Memory Serialize Page address: " INTPTR_FORMAT, p2i(mem_serialize_page)); } - // Check minimum allowable stack size for thread creation and to initialize - // the java system classes, including StackOverflowError - depends on page - // size. Add two 4K pages for compiler2 recursion in main thread. - // Add in 4*BytesPerWord 4K pages to account for VM stack during - // class initialization depending on 32 or 64 bit VM. - os::Solaris::min_stack_allowed = MAX2(os::Solaris::min_stack_allowed, - JavaThread::stack_guard_zone_size() + - JavaThread::stack_shadow_zone_size() + - (4*BytesPerWord COMPILER2_PRESENT(+2)) * 4 * K); - - os::Solaris::min_stack_allowed = align_size_up(os::Solaris::min_stack_allowed, os::vm_page_size()); - - size_t threadStackSizeInBytes = ThreadStackSize * K; - if (threadStackSizeInBytes != 0 && - threadStackSizeInBytes < os::Solaris::min_stack_allowed) { - tty->print_cr("\nThe stack size specified is too small, Specify at least %dk", - os::Solaris::min_stack_allowed/K); + // Check and sets minimum stack sizes against command line options + if (Posix::set_minimum_stack_sizes() == JNI_ERR) { return JNI_ERR; } - // For 64kbps there will be a 64kb page size, which makes - // the usable default stack size quite a bit less. Increase the - // stack for 64kb (or any > than 8kb) pages, this increases - // virtual memory fragmentation (since we're not creating the - // stack on a power of 2 boundary. The real fix for this - // should be to fix the guard page mechanism. - - if (vm_page_size() > 8*K) { - threadStackSizeInBytes = (threadStackSizeInBytes != 0) - ? threadStackSizeInBytes + - JavaThread::stack_red_zone_size() + - JavaThread::stack_yellow_zone_size() - : 0; - ThreadStackSize = threadStackSizeInBytes/K; - } - - // Make the stack size a multiple of the page size so that - // the yellow/red zones can be guarded. - JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, - vm_page_size())); - Solaris::libthread_init(); if (UseNUMA) { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os/solaris/vm/os_solaris.hpp --- a/hotspot/src/os/solaris/vm/os_solaris.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os/solaris/vm/os_solaris.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -292,10 +292,6 @@ static jint _os_thread_limit; static volatile jint _os_thread_count; - // Minimum stack size a thread can be created with (allowing - // the VM to completely create the thread and enter user code) - - static size_t min_stack_allowed; // Stack overflow handling diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -4215,7 +4215,7 @@ min_stack_allowed = align_size_up(min_stack_allowed, os::vm_page_size()); if (actual_reserve_size < min_stack_allowed) { - tty->print_cr("\nThe stack size specified is too small, " + tty->print_cr("\nThe Java thread stack size specified is too small. " "Specify at least %dk", min_stack_allowed / K); return JNI_ERR; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/aix_ppc/vm/globals_aix_ppc.hpp --- a/hotspot/src/os_cpu/aix_ppc/vm/globals_aix_ppc.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/aix_ppc/vm/globals_aix_ppc.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,10 +33,6 @@ define_pd_global(intx, ThreadStackSize, 2048); // 0 => use system default define_pd_global(intx, VMThreadStackSize, 2048); -// if we set CompilerThreadStackSize to a value different than 0, it will -// be used in os::create_thread(). Otherwise, due the strange logic in os::create_thread(), -// the stack size for compiler threads will default to VMThreadStackSize, although it -// is defined to 4M in os::Aix::default_stack_size()! define_pd_global(intx, CompilerThreadStackSize, 4096); // Allow extra space in DEBUG builds for asserts. diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp --- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -192,8 +192,10 @@ intptr_t* csp = (intptr_t*) *((intptr_t*) os::current_stack_pointer()); // hack. frame topframe(csp, (address)0x8); - // return sender of current topframe which hopefully has pc != NULL. - return os::get_sender_for_C_frame(&topframe); + // Return sender of sender of current topframe which hopefully + // both have pc != NULL. + frame tmp = os::get_sender_for_C_frame(&topframe); + return os::get_sender_for_C_frame(&tmp); } // Utility functions @@ -533,23 +535,17 @@ //////////////////////////////////////////////////////////////////////////////// // thread stack -size_t os::Aix::min_stack_allowed = 128*K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 128 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K; // return default stack size for thr_type -size_t os::Aix::default_stack_size(os::ThreadType thr_type) { +size_t os::Posix::default_stack_size(os::ThreadType thr_type) { // default stack size (compiler thread needs larger stack) - // Notice that the setting for compiler threads here have no impact - // because of the strange 'fallback logic' in os::create_thread(). - // Better set CompilerThreadStackSize in globals_.hpp if you want to - // specify a different stack size for compiler threads! size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); return s; } -size_t os::Aix::default_guard_size(os::ThreadType thr_type) { - return 2 * page_size(); -} - ///////////////////////////////////////////////////////////////////////////// // helper functions for fatal error handler diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp --- a/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,9 +31,11 @@ // define_pd_global(bool, DontYieldALot, false); #ifdef AMD64 +define_pd_global(intx, CompilerThreadStackSize, 1024); define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default define_pd_global(intx, VMThreadStackSize, 1024); #else +define_pd_global(intx, CompilerThreadStackSize, 512); // ThreadStackSize 320 allows a couple of test cases to run while // keeping the number of threads that can be created high. System // default ThreadStackSize appears to be 512 which is too big. @@ -41,7 +43,6 @@ define_pd_global(intx, VMThreadStackSize, 512); #endif // AMD64 -define_pd_global(intx, CompilerThreadStackSize, 0); define_pd_global(size_t, JVMInvokeMethodSlack, 8192); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp --- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -838,9 +838,13 @@ // thread stack #ifdef AMD64 -size_t os::Bsd::min_stack_allowed = 64 * K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K; #else -size_t os::Bsd::min_stack_allowed = (48 DEBUG_ONLY(+4))*K; +size_t os::Posix::_compiler_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K; +size_t os::Posix::_java_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K; #ifdef __GNUC__ #define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;}) @@ -849,7 +853,7 @@ #endif // AMD64 // return default stack size for thr_type -size_t os::Bsd::default_stack_size(os::ThreadType thr_type) { +size_t os::Posix::default_stack_size(os::ThreadType thr_type) { // default stack size (compiler thread needs larger stack) #ifdef AMD64 size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); @@ -859,11 +863,6 @@ return s; } -size_t os::Bsd::default_guard_size(os::ThreadType thr_type) { - // Creating guard page is very expensive. Java thread has HotSpot - // guard page, only enable glibc guard page for non-Java threads. - return (thr_type == java_thread ? 0 : page_size()); -} // Java thread: // diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp --- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -282,9 +282,11 @@ /////////////////////////////////////////////////////////////////////////////// // thread stack -size_t os::Bsd::min_stack_allowed = 64 * K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K; -size_t os::Bsd::default_stack_size(os::ThreadType thr_type) { +size_t os::Posix::default_stack_size(os::ThreadType thr_type) { #ifdef _LP64 size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); #else @@ -293,12 +295,6 @@ return s; } -size_t os::Bsd::default_guard_size(os::ThreadType thr_type) { - // Only enable glibc guard pages for non-Java threads - // (Java threads have HotSpot guard pages) - return (thr_type == java_thread ? 0 : page_size()); -} - static void current_stack_region(address *bottom, size_t *size) { address stack_bottom; address stack_top; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/linux_aarch64/vm/globals_linux_aarch64.hpp --- a/hotspot/src/os_cpu/linux_aarch64/vm/globals_linux_aarch64.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/linux_aarch64/vm/globals_linux_aarch64.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,7 +33,7 @@ define_pd_global(intx, ThreadStackSize, 2048); // 0 => use system default define_pd_global(intx, VMThreadStackSize, 2048); -define_pd_global(intx, CompilerThreadStackSize, 0); +define_pd_global(intx, CompilerThreadStackSize, 2048); define_pd_global(uintx,JVMInvokeMethodSlack, 8192); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp --- a/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -473,10 +473,12 @@ //////////////////////////////////////////////////////////////////////////////// // thread stack -size_t os::Linux::min_stack_allowed = 64 * K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K; // return default stack size for thr_type -size_t os::Linux::default_stack_size(os::ThreadType thr_type) { +size_t os::Posix::default_stack_size(os::ThreadType thr_type) { // default stack size (compiler thread needs larger stack) size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); return s; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp --- a/hotspot/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/linux_ppc/vm/globals_linux_ppc.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -33,10 +33,6 @@ define_pd_global(intx, ThreadStackSize, 2048); // 0 => use system default define_pd_global(intx, VMThreadStackSize, 2048); -// if we set CompilerThreadStackSize to a value different than 0, it will -// be used in os::create_thread(). Otherwise, due the strange logic in os::create_thread(), -// the stack size for compiler threads will default to VMThreadStackSize, although it -// is defined to 4M in os::Linux::default_stack_size()! define_pd_global(intx, CompilerThreadStackSize, 4096); // Allow extra space in DEBUG builds for asserts. diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp --- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -205,8 +205,10 @@ intptr_t* csp = (intptr_t*) *((intptr_t*) os::current_stack_pointer()); // hack. frame topframe(csp, (address)0x8); - // return sender of current topframe which hopefully has pc != NULL. - return os::get_sender_for_C_frame(&topframe); + // Return sender of sender of current topframe which hopefully + // both have pc != NULL. + frame tmp = os::get_sender_for_C_frame(&topframe); + return os::get_sender_for_C_frame(&tmp); } // Utility functions @@ -533,15 +535,13 @@ //////////////////////////////////////////////////////////////////////////////// // thread stack -size_t os::Linux::min_stack_allowed = 128*K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 128 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K; // return default stack size for thr_type -size_t os::Linux::default_stack_size(os::ThreadType thr_type) { +size_t os::Posix::default_stack_size(os::ThreadType thr_type) { // default stack size (compiler thread needs larger stack) - // Notice that the setting for compiler threads here have no impact - // because of the strange 'fallback logic' in os::create_thread(). - // Better set CompilerThreadStackSize in globals_.hpp if you want to - // specify a different stack size for compiler threads! size_t s = (thr_type == os::compiler_thread ? 4 * M : 1024 * K); return s; } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp --- a/hotspot/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/linux_sparc/vm/globals_linux_sparc.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,6 @@ // define_pd_global(size_t, JVMInvokeMethodSlack, 12288); -define_pd_global(intx, CompilerThreadStackSize, 0); // Used on 64 bit platforms for UseCompressedOops base address define_pd_global(size_t, HeapBaseMinAddress, CONST64(4)*G); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp --- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -726,10 +726,12 @@ /////////////////////////////////////////////////////////////////////////////// // thread stack -size_t os::Linux::min_stack_allowed = 128 * K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 128 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K; // return default stack size for thr_type -size_t os::Linux::default_stack_size(os::ThreadType thr_type) { +size_t os::Posix::default_stack_size(os::ThreadType thr_type) { // default stack size (compiler thread needs larger stack) size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); return s; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp --- a/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/linux_x86/vm/globals_linux_x86.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,9 +30,11 @@ define_pd_global(bool, DontYieldALot, false); #ifdef AMD64 +define_pd_global(intx, CompilerThreadStackSize, 1024); define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default define_pd_global(intx, VMThreadStackSize, 1024); #else +define_pd_global(intx, CompilerThreadStackSize, 512); // ThreadStackSize 320 allows a couple of test cases to run while // keeping the number of threads that can be created high. System // default ThreadStackSize appears to be 512 which is too big. @@ -40,8 +42,6 @@ define_pd_global(intx, VMThreadStackSize, 512); #endif // AMD64 -define_pd_global(intx, CompilerThreadStackSize, 0); - define_pd_global(size_t, JVMInvokeMethodSlack, 8192); // Used on 64 bit platforms for UseCompressedOops base address diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -676,13 +676,17 @@ // thread stack #ifdef AMD64 -size_t os::Linux::min_stack_allowed = 64 * K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K; #else -size_t os::Linux::min_stack_allowed = (48 DEBUG_ONLY(+4))*K; +size_t os::Posix::_compiler_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K; +size_t os::Posix::_java_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = (48 DEBUG_ONLY(+ 4)) * K; #endif // AMD64 // return default stack size for thr_type -size_t os::Linux::default_stack_size(os::ThreadType thr_type) { +size_t os::Posix::default_stack_size(os::ThreadType thr_type) { // default stack size (compiler thread needs larger stack) #ifdef AMD64 size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp --- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -307,9 +307,11 @@ /////////////////////////////////////////////////////////////////////////////// // thread stack -size_t os::Linux::min_stack_allowed = 64 * K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K; -size_t os::Linux::default_stack_size(os::ThreadType thr_type) { +size_t os::Posix::default_stack_size(os::ThreadType thr_type) { #ifdef _LP64 size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); #else diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp --- a/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/globals_solaris_sparc.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,6 @@ // define_pd_global(size_t, JVMInvokeMethodSlack, 12288); -define_pd_global(intx, CompilerThreadStackSize, 0); // Used on 64 bit platforms for UseCompressedOops base address #ifdef _LP64 diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp --- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -84,9 +84,13 @@ // Minimum stack size for the VM. It's easier to document a constant // but it's different for x86 and sparc because the page sizes are different. #ifdef _LP64 -size_t os::Solaris::min_stack_allowed = 128*K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 128 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 128 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 128 * K; #else -size_t os::Solaris::min_stack_allowed = 96*K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 96 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 96 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 96 * K; #endif int os::Solaris::max_register_window_saves_before_flushing() { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp --- a/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/solaris_x86/vm/globals_solaris_x86.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,10 +30,12 @@ define_pd_global(bool, DontYieldALot, true); // Determined in the design center #ifdef AMD64 +define_pd_global(intx, CompilerThreadStackSize, 1024); define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default define_pd_global(intx, VMThreadStackSize, 1024); define_pd_global(size_t, JVMInvokeMethodSlack, 8*K); #else +define_pd_global(intx, CompilerThreadStackSize, 512); // ThreadStackSize 320 allows a couple of test cases to run while // keeping the number of threads that can be created high. define_pd_global(intx, ThreadStackSize, 320); @@ -41,7 +43,6 @@ define_pd_global(size_t, JVMInvokeMethodSlack, 10*K); #endif // AMD64 -define_pd_global(intx, CompilerThreadStackSize, 0); // Used on 64 bit platforms for UseCompressedOops base address define_pd_global(size_t, HeapBaseMinAddress, 2*G); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp --- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -86,15 +86,19 @@ #define MAX_PATH (2 * K) -// Minimum stack size for the VM. It's easier to document a constant value +// Minimum stack sizes for the VM. It's easier to document a constant value // but it's different for x86 and sparc because the page sizes are different. #ifdef AMD64 -size_t os::Solaris::min_stack_allowed = 224*K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 394 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 224 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 224 * K; #define REG_SP REG_RSP #define REG_PC REG_RIP #define REG_FP REG_RBP #else -size_t os::Solaris::min_stack_allowed = 64*K; +size_t os::Posix::_compiler_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_java_thread_min_stack_allowed = 64 * K; +size_t os::Posix::_vm_internal_thread_min_stack_allowed = 64 * K; #define REG_SP UESP #define REG_PC EIP #define REG_FP EBP diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -2410,6 +2410,15 @@ #endif // INCLUDE_ALL_GCS if (x->is_volatile() && os::is_MP()) __ membar_acquire(); + + /* Normalize boolean value returned by unsafe operation, i.e., value != 0 ? value = true : value false. */ + if (type == T_BOOLEAN) { + LabelObj* equalZeroLabel = new LabelObj(); + __ cmp(lir_cond_equal, value, 0); + __ branch(lir_cond_equal, T_BOOLEAN, equalZeroLabel->label()); + __ move(LIR_OprFact::intConst(1), value); + __ branch_destination(equalZeroLabel->label()); + } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/c1/c1_Runtime1.cpp --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -576,9 +576,8 @@ // normal bytecode execution. thread->clear_exception_oop_and_pc(); - Handle original_exception(thread, exception()); - - continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false); + bool recursive_exception = false; + continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false, recursive_exception); // If an exception was thrown during exception dispatch, the exception oop may have changed thread->set_exception_oop(exception()); thread->set_exception_pc(pc); @@ -586,8 +585,9 @@ // the exception cache is used only by non-implicit exceptions // Update the exception cache only when there didn't happen // another exception during the computation of the compiled - // exception handler. - if (continuation != NULL && original_exception() == exception()) { + // exception handler. Checking for exception oop equality is not + // sufficient because some exceptions are pre-allocated and reused. + if (continuation != NULL && !recursive_exception) { nm->add_handler_for_exception_and_pc(exception, pc, continuation); } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/classfile/verificationType.hpp --- a/hotspot/src/share/vm/classfile/verificationType.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/classfile/verificationType.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,7 +95,8 @@ Category2_2nd = (Category2_2ndFlag << 1 * BitsPerByte) | Primitive, // Primitive values (type descriminator stored in most-signifcant bytes) - Bogus = (ITEM_Bogus << 2 * BitsPerByte) | Category1, + // Bogus needs the " | Primitive". Else, is_reference(Bogus) returns TRUE. + Bogus = (ITEM_Bogus << 2 * BitsPerByte) | Primitive, Boolean = (ITEM_Boolean << 2 * BitsPerByte) | Category1, Byte = (ITEM_Byte << 2 * BitsPerByte) | Category1, Short = (ITEM_Short << 2 * BitsPerByte) | Category1, diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/code/codeCache.cpp --- a/hotspot/src/share/vm/code/codeCache.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/code/codeCache.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -1305,7 +1305,7 @@ event.set_entryCount(heap->blob_count()); event.set_methodCount(heap->nmethod_count()); event.set_adaptorCount(heap->adapter_count()); - event.set_unallocatedCapacity(heap->unallocated_capacity()/K); + event.set_unallocatedCapacity(heap->unallocated_capacity()); event.set_fullCount(heap->full_count()); event.commit(); } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/gc/g1/g1CollectionSet.cpp --- a/hotspot/src/share/vm/gc/g1/g1CollectionSet.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/gc/g1/g1CollectionSet.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -32,6 +32,7 @@ #include "gc/g1/heapRegionSet.hpp" #include "logging/logStream.hpp" #include "utilities/debug.hpp" +#include "utilities/quickSort.hpp" G1CollectorState* G1CollectionSet::collector_state() { return _g1->collector_state(); @@ -396,6 +397,16 @@ return time_remaining_ms; } +static int compare_region_idx(const uint a, const uint b) { + if (a > b) { + return 1; + } else if (a == b) { + return 0; + } else { + return -1; + } +} + void G1CollectionSet::finalize_old_part(double time_remaining_ms) { double non_young_start_time_sec = os::elapsedTime(); double predicted_old_time_ms = 0.0; @@ -493,6 +504,8 @@ double non_young_end_time_sec = os::elapsedTime(); phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0); + + QuickSort::sort(_collection_set_regions, (int)_collection_set_cur_length, compare_region_idx, true); } #ifdef ASSERT diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -1904,7 +1904,8 @@ assert(_g1h->is_in_g1_reserved(finger), "invariant"); HeapRegion* curr_region = _g1h->heap_region_containing(finger); - + // Make sure that the reads below do not float before loading curr_region. + OrderAccess::loadload(); // Above heap_region_containing may return NULL as we always scan claim // until the end of the heap. In this case, just jump to the next region. HeapWord* end = curr_region != NULL ? curr_region->end() : finger + HeapRegion::GrainWords; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp --- a/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -132,9 +132,16 @@ MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations); { G1RootProcessor root_processor(g1h, 1); - root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure, - &GenMarkSweep::follow_cld_closure, - &follow_code_closure); + if (ClassUnloading) { + root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure, + &GenMarkSweep::follow_cld_closure, + &follow_code_closure); + } else { + root_processor.process_all_roots_no_string_table( + &GenMarkSweep::follow_root_closure, + &GenMarkSweep::follow_cld_closure, + &follow_code_closure); + } } { @@ -157,7 +164,7 @@ // This is the point where the entire marking should have completed. assert(GenMarkSweep::_marking_stack.is_empty(), "Marking should have completed"); - { + if (ClassUnloading) { GCTraceTime(Debug, gc, phases) trace("Class Unloading", gc_timer()); // Unload classes and purge the SystemDictionary. diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp --- a/hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/gc/g1/g1RootProcessor.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -83,6 +83,7 @@ } process_vm_roots(closures, phase_times, worker_i); + process_string_table_roots(closures, phase_times, worker_i); { // Now the CM ref_processor roots. @@ -191,19 +192,34 @@ void G1RootProcessor::process_all_roots(OopClosure* oops, CLDClosure* clds, - CodeBlobClosure* blobs) { + CodeBlobClosure* blobs, + bool process_string_table) { AllRootsClosures closures(oops, clds); process_java_roots(&closures, NULL, 0); process_vm_roots(&closures, NULL, 0); - if (!_process_strong_tasks.is_task_claimed(G1RP_PS_CodeCache_oops_do)) { - CodeCache::blobs_do(blobs); + if (process_string_table) { + process_string_table_roots(&closures, NULL, 0); } + process_code_cache_roots(blobs, NULL, 0); _process_strong_tasks.all_tasks_completed(n_workers()); } +void G1RootProcessor::process_all_roots(OopClosure* oops, + CLDClosure* clds, + CodeBlobClosure* blobs) { + process_all_roots(oops, clds, blobs, true); +} + +void G1RootProcessor::process_all_roots_no_string_table(OopClosure* oops, + CLDClosure* clds, + CodeBlobClosure* blobs) { + assert(!ClassUnloading, "Should only be used when class unloading is disabled"); + process_all_roots(oops, clds, blobs, false); +} + void G1RootProcessor::process_java_roots(G1RootClosures* closures, G1GCPhaseTimes* phase_times, uint worker_i) { @@ -280,14 +296,23 @@ SystemDictionary::roots_oops_do(strong_roots, weak_roots); } } +} - { - G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::StringTableRoots, worker_i); - // All threads execute the following. A specific chunk of buckets - // from the StringTable are the individual tasks. - if (weak_roots != NULL) { - StringTable::possibly_parallel_oops_do(weak_roots); - } +void G1RootProcessor::process_string_table_roots(G1RootClosures* closures, + G1GCPhaseTimes* phase_times, + uint worker_i) { + assert(closures->weak_oops() != NULL, "Should only be called when all roots are processed"); + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::StringTableRoots, worker_i); + // All threads execute the following. A specific chunk of buckets + // from the StringTable are the individual tasks. + StringTable::possibly_parallel_oops_do(closures->weak_oops()); +} + +void G1RootProcessor::process_code_cache_roots(CodeBlobClosure* code_closure, + G1GCPhaseTimes* phase_times, + uint worker_i) { + if (!_process_strong_tasks.is_task_claimed(G1RP_PS_CodeCache_oops_do)) { + CodeCache::blobs_do(code_closure); } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/gc/g1/g1RootProcessor.hpp --- a/hotspot/src/share/vm/gc/g1/g1RootProcessor.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/gc/g1/g1RootProcessor.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -73,6 +73,11 @@ void worker_has_discovered_all_strong_classes(); void wait_until_all_strong_classes_discovered(); + void process_all_roots(OopClosure* oops, + CLDClosure* clds, + CodeBlobClosure* blobs, + bool process_string_table); + void process_java_roots(G1RootClosures* closures, G1GCPhaseTimes* phase_times, uint worker_i); @@ -81,6 +86,14 @@ G1GCPhaseTimes* phase_times, uint worker_i); + void process_string_table_roots(G1RootClosures* closures, + G1GCPhaseTimes* phase_times, + uint worker_i); + + void process_code_cache_roots(CodeBlobClosure* code_closure, + G1GCPhaseTimes* phase_times, + uint worker_i); + public: G1RootProcessor(G1CollectedHeap* g1h, uint n_workers); @@ -99,6 +112,13 @@ CLDClosure* clds, CodeBlobClosure* blobs); + // Apply oops, clds and blobs to strongly and weakly reachable roots in the system, + // the only thing different from process_all_roots is that we skip the string table + // to avoid keeping every string live when doing class unloading. + void process_all_roots_no_string_table(OopClosure* oops, + CLDClosure* clds, + CodeBlobClosure* blobs); + // Number of worker threads used by the root processor. uint n_workers() const; }; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/gc/g1/heapRegionManager.cpp --- a/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/gc/g1/heapRegionManager.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -123,6 +123,7 @@ for (uint i = start; i < start + num_regions; i++) { if (_regions.get_by_index(i) == NULL) { HeapRegion* new_hr = new_heap_region(i); + OrderAccess::storestore(); _regions.set_by_index(i, new_hr); _allocated_heapregions_length = MAX2(_allocated_heapregions_length, i + 1); } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/gc/shared/gcTrace.cpp --- a/hotspot/src/share/vm/gc/shared/gcTrace.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/gc/shared/gcTrace.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -185,8 +185,10 @@ } #if INCLUDE_ALL_GCS -void G1MMUTracer::report_mmu(double timeSlice, double gcTime, double maxTime) { - send_g1_mmu_event(timeSlice, gcTime, maxTime); +void G1MMUTracer::report_mmu(double time_slice_sec, double gc_time_sec, double max_time_sec) { + send_g1_mmu_event(time_slice_sec * MILLIUNITS, + gc_time_sec * MILLIUNITS, + max_time_sec * MILLIUNITS); } void G1NewTracer::report_yc_type(G1YCType type) { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/gc/shared/gcTrace.hpp --- a/hotspot/src/share/vm/gc/shared/gcTrace.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/gc/shared/gcTrace.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -235,10 +235,10 @@ #if INCLUDE_ALL_GCS class G1MMUTracer : public AllStatic { - static void send_g1_mmu_event(double timeSlice, double gcTime, double maxTime); + static void send_g1_mmu_event(double time_slice_ms, double gc_time_ms, double max_time_ms); public: - static void report_mmu(double timeSlice, double gcTime, double maxTime); + static void report_mmu(double time_slice_sec, double gc_time_sec, double max_time_sec); }; class G1NewTracer : public YoungGCTracer { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/gc/shared/gcTraceSend.cpp --- a/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/gc/shared/gcTraceSend.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -200,13 +200,13 @@ } } -void G1MMUTracer::send_g1_mmu_event(double timeSlice, double gcTime, double maxTime) { +void G1MMUTracer::send_g1_mmu_event(double time_slice_ms, double gc_time_ms, double max_time_ms) { EventG1MMU e; if (e.should_commit()) { e.set_gcId(GCId::current()); - e.set_timeSlice(timeSlice); - e.set_gcTime(gcTime); - e.set_maxGcTime(maxTime); + e.set_timeSlice(time_slice_ms); + e.set_gcTime(gc_time_ms); + e.set_pauseTarget(max_time_ms); e.commit(); } } @@ -281,10 +281,10 @@ evt.set_targetOccupancy(target_occupancy); evt.set_thresholdPercentage(target_occupancy > 0 ? ((double)threshold / target_occupancy) : 0.0); evt.set_currentOccupancy(current_occupancy); - evt.set_lastAllocationSize(last_allocation_size); - evt.set_lastAllocationDuration(last_allocation_duration); - evt.set_lastAllocationRate(last_allocation_duration != 0.0 ? last_allocation_size / last_allocation_duration : 0.0); - evt.set_lastMarkingLength(last_marking_length); + evt.set_recentMutatorAllocationSize(last_allocation_size); + evt.set_recentMutatorDuration(last_allocation_duration * MILLIUNITS); + evt.set_recentAllocationRate(last_allocation_duration != 0.0 ? last_allocation_size / last_allocation_duration : 0.0); + evt.set_lastMarkingDuration(last_marking_length * MILLIUNITS); evt.commit(); } } @@ -301,11 +301,11 @@ evt.set_gcId(GCId::current()); evt.set_threshold(threshold); evt.set_thresholdPercentage(internal_target_occupancy > 0 ? ((double)threshold / internal_target_occupancy) : 0.0); - evt.set_internalTargetOccupancy(internal_target_occupancy); + evt.set_ihopTargetOccupancy(internal_target_occupancy); evt.set_currentOccupancy(current_occupancy); evt.set_additionalBufferSize(additional_buffer_size); evt.set_predictedAllocationRate(predicted_allocation_rate); - evt.set_predictedMarkingLength(predicted_marking_length); + evt.set_predictedMarkingDuration(predicted_marking_length * MILLIUNITS); evt.set_predictionActive(prediction_active); evt.commit(); } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/gc/shared/workerManager.hpp --- a/hotspot/src/share/vm/gc/shared/workerManager.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/gc/shared/workerManager.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/interpreter/interpreterRuntime.cpp --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -576,27 +576,39 @@ // compute auxiliary field attributes TosState state = as_TosState(info.field_type()); - // Put instructions on final fields are not resolved. This is required so we throw - // exceptions at the correct place (when the instruction is actually invoked). + // Resolution of put instructions on final fields is delayed. That is required so that + // exceptions are thrown at the correct place (when the instruction is actually invoked). // If we do not resolve an instruction in the current pass, leaving the put_code // set to zero will cause the next put instruction to the same field to reresolve. + + // Resolution of put instructions to final instance fields with invalid updates (i.e., + // to final instance fields with updates originating from a method different than ) + // is inhibited. A putfield instruction targeting an instance final field must throw + // an IllegalAccessError if the instruction is not in an instance + // initializer method . If resolution were not inhibited, a putfield + // in an initializer method could be resolved in the initializer. Subsequent + // putfield instructions to the same field would then use cached information. + // As a result, those instructions would not pass through the VM. That is, + // checks in resolve_field_access() would not be executed for those instructions + // and the required IllegalAccessError would not be thrown. // // Also, we need to delay resolving getstatic and putstatic instructions until the // class is initialized. This is required so that access to the static // field will call the initialization function every time until the class // is completely initialized ala. in 2.17.5 in JVM Specification. InstanceKlass* klass = InstanceKlass::cast(info.field_holder()); - bool uninitialized_static = ((bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic) && - !klass->is_initialized()); - - Bytecodes::Code put_code = (Bytecodes::Code)0; - if (is_put && !info.access_flags().is_final() && !uninitialized_static) { - put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield); - } + bool uninitialized_static = is_static && !klass->is_initialized(); + bool has_initialized_final_update = info.field_holder()->major_version() >= 53 && + info.has_initialized_final_update(); + assert(!(has_initialized_final_update && !info.access_flags().is_final()), "Fields with initialized final updates must be final"); Bytecodes::Code get_code = (Bytecodes::Code)0; + Bytecodes::Code put_code = (Bytecodes::Code)0; if (!uninitialized_static) { get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield); + if ((is_put && !has_initialized_final_update) || !info.access_flags().is_final()) { + put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield); + } } cp_cache_entry->set_field( diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp --- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -768,6 +768,11 @@ Symbol* h_name = method->name(); Symbol* h_signature = method->signature(); + if (MethodHandles::is_signature_polymorphic_method(method())) { + // Signature polymorphic methods are already resolved, JVMCI just returns NULL in this case. + return NULL; + } + LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass); methodHandle m; // Only do exact lookup if receiver klass has been linked. Otherwise, @@ -782,7 +787,7 @@ } if (m.is_null()) { - // Return NULL only if there was a problem with lookup (uninitialized class, etc.) + // Return NULL if there was a problem with lookup (uninitialized class, etc.) return NULL; } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/jvmci/jvmciRuntime.cpp --- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -313,13 +313,18 @@ // normal bytecode execution. thread->clear_exception_oop_and_pc(); - continuation = SharedRuntime::compute_compiled_exc_handler(cm, pc, exception, false, false); + bool recursive_exception = false; + continuation = SharedRuntime::compute_compiled_exc_handler(cm, pc, exception, false, false, recursive_exception); // If an exception was thrown during exception dispatch, the exception oop may have changed thread->set_exception_oop(exception()); thread->set_exception_pc(pc); // the exception cache is used only by non-implicit exceptions - if (continuation != NULL && !SharedRuntime::deopt_blob()->contains(continuation)) { + // Update the exception cache only when there didn't happen + // another exception during the computation of the compiled + // exception handler. Checking for exception oop equality is not + // sufficient because some exceptions are pre-allocated and reused. + if (continuation != NULL && !recursive_exception && !SharedRuntime::deopt_blob()->contains(continuation)) { cm->add_handler_for_exception_and_pc(exception, pc, continuation); } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/oops/klass.cpp --- a/hotspot/src/share/vm/oops/klass.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/oops/klass.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -431,6 +431,12 @@ if (clean_alive_klasses && current->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(current); ik->clean_weak_instanceklass_links(is_alive); + + // JVMTI RedefineClasses creates previous versions that are not in + // the class hierarchy, so process them here. + while ((ik = ik->previous_versions()) != NULL) { + ik->clean_weak_instanceklass_links(is_alive); + } } } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/opto/graphKit.cpp --- a/hotspot/src/share/vm/opto/graphKit.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/opto/graphKit.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -2172,10 +2172,9 @@ java_bc() == Bytecodes::_instanceof || java_bc() == Bytecodes::_aastore) { ciProfileData* data = method()->method_data()->bci_to_data(bci()); - bool maybe_null = data == NULL ? true : data->as_BitData()->null_seen(); + maybe_null = data == NULL ? true : data->as_BitData()->null_seen(); } return record_profile_for_speculation(n, exact_kls, maybe_null); - return n; } /** diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/opto/library_call.cpp --- a/hotspot/src/share/vm/opto/library_call.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -2475,6 +2475,28 @@ // load value switch (type) { case T_BOOLEAN: + { + // Normalize the value returned by getBoolean in the following cases + if (mismatched || + heap_base_oop == top() || // - heap_base_oop is NULL or + (can_access_non_heap && alias_type->field() == NULL) // - heap_base_oop is potentially NULL + // and the unsafe access is made to large offset + // (i.e., larger than the maximum offset necessary for any + // field access) + ) { + IdealKit ideal = IdealKit(this); +#define __ ideal. + IdealVariable normalized_result(ideal); + __ declarations_done(); + __ set(normalized_result, p); + __ if_then(p, BoolTest::ne, ideal.ConI(0)); + __ set(normalized_result, ideal.ConI(1)); + ideal.end_if(); + final_sync(ideal); + p = __ value(normalized_result); +#undef __ + } + } case T_CHAR: case T_BYTE: case T_SHORT: diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/opto/runtime.cpp --- a/hotspot/src/share/vm/opto/runtime.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/opto/runtime.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -1349,17 +1349,23 @@ force_unwind ? NULL : nm->handler_for_exception_and_pc(exception, pc); if (handler_address == NULL) { - Handle original_exception(thread, exception()); - handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true); + bool recursive_exception = false; + handler_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception); assert (handler_address != NULL, "must have compiled handler"); // Update the exception cache only when the unwind was not forced // and there didn't happen another exception during the computation of the - // compiled exception handler. - if (!force_unwind && original_exception() == exception()) { + // compiled exception handler. Checking for exception oop equality is not + // sufficient because some exceptions are pre-allocated and reused. + if (!force_unwind && !recursive_exception) { nm->add_handler_for_exception_and_pc(exception,pc,handler_address); } } else { - assert(handler_address == SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true), "Must be the same"); +#ifdef ASSERT + bool recursive_exception = false; + address computed_address = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, force_unwind, true, recursive_exception); + vmassert(recursive_exception || (handler_address == computed_address), "Handler address inconsistency: " PTR_FORMAT " != " PTR_FORMAT, + p2i(handler_address), p2i(computed_address)); +#endif } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/prims/jvm.h --- a/hotspot/src/share/vm/prims/jvm.h Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/prims/jvm.h Wed Jul 05 22:16:00 2017 +0200 @@ -196,7 +196,8 @@ * java.lang.StackWalker */ enum { - JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x2, + JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x02, + JVM_STACKWALK_GET_CALLER_CLASS = 0x04, JVM_STACKWALK_SHOW_HIDDEN_FRAMES = 0x20, JVM_STACKWALK_FILL_LIVE_STACK_FRAMES = 0x100 }; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/prims/jvmtiEventController.cpp --- a/hotspot/src/share/vm/prims/jvmtiEventController.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/prims/jvmtiEventController.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -96,7 +96,7 @@ static const jlong THREAD_FILTERED_EVENT_BITS = INTERP_EVENT_BITS | EXCEPTION_BITS | MONITOR_BITS | BREAKPOINT_BIT | CLASS_LOAD_BIT | CLASS_PREPARE_BIT | THREAD_END_BIT; static const jlong NEED_THREAD_LIFE_EVENTS = THREAD_FILTERED_EVENT_BITS | THREAD_START_BIT; -static const jlong EARLY_EVENT_BITS = CLASS_FILE_LOAD_HOOK_BIT | +static const jlong EARLY_EVENT_BITS = CLASS_FILE_LOAD_HOOK_BIT | CLASS_LOAD_BIT | CLASS_PREPARE_BIT | VM_START_BIT | VM_INIT_BIT | VM_DEATH_BIT | NATIVE_METHOD_BIND_BIT | THREAD_START_BIT | THREAD_END_BIT | COMPILED_METHOD_LOAD_BIT | COMPILED_METHOD_UNLOAD_BIT | diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/prims/jvmtiExport.cpp diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/prims/stackwalk.cpp --- a/hotspot/src/share/vm/prims/stackwalk.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/prims/stackwalk.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -113,7 +113,10 @@ int bci = stream.bci(); if (method == NULL) continue; - if (!ShowHiddenFrames && StackWalk::skip_hidden_frames(mode)) { + + // skip hidden frames for default StackWalker option (i.e. SHOW_HIDDEN_FRAMES + // not set) and when StackWalker::getCallerClass is called + if (!ShowHiddenFrames && (skip_hidden_frames(mode) || get_caller_class(mode))) { if (method->is_hidden()) { if (TraceStackWalk) { tty->print(" hidden method: "); method->print_short_name(); @@ -139,7 +142,14 @@ Handle stackFrame(frames_array->obj_at(index)); fill_stackframe(stackFrame, method, bci); } else { - assert (use_frames_array(mode) == false, "Bad mode for get caller class"); + assert (use_frames_array(mode) == false, "Bad mode for filling in Class object"); + if (get_caller_class(mode) && index == start_index && method->caller_sensitive()) { + ResourceMark rm(THREAD); + THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), + err_msg("StackWalker::getCallerClass called from @CallerSensitive %s method", + method->name_and_sig_as_C_string())); + } + frames_array->obj_at_put(index, method->method_holder()->java_mirror()); } if (++frames_decoded >= max_nframes) break; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/prims/stackwalk.hpp --- a/hotspot/src/share/vm/prims/stackwalk.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/prims/stackwalk.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -82,6 +82,9 @@ static void fill_live_stackframe(Handle stackFrame, const methodHandle& method, int bci, javaVFrame* jvf, TRAPS); + static inline bool get_caller_class(int mode) { + return (mode & JVM_STACKWALK_GET_CALLER_CLASS) != 0; + } static inline bool skip_hidden_frames(int mode) { return (mode & JVM_STACKWALK_SHOW_HIDDEN_FRAMES) == 0; } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/prims/unsafe.cpp --- a/hotspot/src/share/vm/prims/unsafe.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/prims/unsafe.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -150,14 +150,23 @@ } template - T normalize(T x) { + T normalize_for_write(T x) { return x; } - jboolean normalize(jboolean x) { + jboolean normalize_for_write(jboolean x) { return x & 1; } + template + T normalize_for_read(T x) { + return x; + } + + jboolean normalize_for_read(jboolean x) { + return x != 0; + } + /** * Helper class to wrap memory accesses in JavaThread::doing_unsafe_access() */ @@ -196,7 +205,7 @@ T* p = (T*)addr(); - T x = *p; + T x = normalize_for_read(*p); return x; } @@ -207,7 +216,7 @@ T* p = (T*)addr(); - *p = normalize(x); + *p = normalize_for_write(x); } @@ -223,7 +232,7 @@ T x = OrderAccess::load_acquire((volatile T*)p); - return x; + return normalize_for_read(x); } template @@ -232,7 +241,7 @@ T* p = (T*)addr(); - OrderAccess::release_store_fence((volatile T*)p, normalize(x)); + OrderAccess::release_store_fence((volatile T*)p, normalize_for_write(x)); } @@ -256,7 +265,7 @@ jlong* p = (jlong*)addr(); - Atomic::store(normalize(x), p); + Atomic::store(normalize_for_write(x), p); } #endif }; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/prims/whitebox.cpp --- a/hotspot/src/share/vm/prims/whitebox.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/prims/whitebox.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -894,6 +894,7 @@ } ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI const char* flag_name = env->GetStringUTFChars(name, NULL); + CHECK_JNI_EXCEPTION_(env, false); Flag::Error result = (*TAt)(flag_name, value, true, true); env->ReleaseStringUTFChars(name, flag_name); return (result == Flag::SUCCESS); @@ -906,6 +907,7 @@ } ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI const char* flag_name = env->GetStringUTFChars(name, NULL); + CHECK_JNI_EXCEPTION_(env, false); Flag::Error result = (*TAtPut)(flag_name, value, Flag::INTERNAL); env->ReleaseStringUTFChars(name, flag_name); return (result == Flag::SUCCESS); @@ -944,6 +946,7 @@ static Flag* getVMFlag(JavaThread* thread, JNIEnv* env, jstring name) { ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI const char* flag_name = env->GetStringUTFChars(name, NULL); + CHECK_JNI_EXCEPTION_(env, NULL); Flag* result = Flag::find_flag(flag_name, strlen(flag_name), true, true); env->ReleaseStringUTFChars(name, flag_name); return result; @@ -1084,7 +1087,14 @@ WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value)) ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI - const char* ccstrValue = (value == NULL) ? NULL : env->GetStringUTFChars(value, NULL); + const char* ccstrValue; + if (value == NULL) { + ccstrValue = NULL; + } + else { + ccstrValue = env->GetStringUTFChars(value, NULL); + CHECK_JNI_EXCEPTION(env); + } ccstr ccstrResult = ccstrValue; bool needFree; { @@ -1308,6 +1318,7 @@ jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string()); CHECK_JNI_EXCEPTION_(env, NULL); result = env->NewObjectArray(blobs.length(), clazz, NULL); + CHECK_JNI_EXCEPTION_(env, NULL); if (result == NULL) { return result; } @@ -1317,6 +1328,7 @@ jobjectArray obj = codeBlob2objectArray(thread, env, *it); CHECK_JNI_EXCEPTION_(env, NULL); env->SetObjectArrayElement(result, i, obj); + CHECK_JNI_EXCEPTION_(env, NULL); ++i; } return result; @@ -1523,6 +1535,7 @@ // can't be in VM when we call JNI ThreadToNativeFromVM ttnfv(thread); const char* flag_name = env->GetStringUTFChars(name, NULL); + CHECK_JNI_EXCEPTION_(env, false); bool result = CompilerOracle::has_option_value(mh, flag_name, *value); env->ReleaseStringUTFChars(name, flag_name); return result; @@ -1678,6 +1691,7 @@ // can't be in VM when we call JNI ThreadToNativeFromVM ttnfv(thread); const char* dir = env->GetStringUTFChars(compDirect, NULL); + CHECK_JNI_EXCEPTION_(env, 0); int ret; { ThreadInVMfromNative ttvfn(thread); // back to VM diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/prims/whitebox.hpp --- a/hotspot/src/share/vm/prims/whitebox.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/prims/whitebox.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -33,9 +33,22 @@ #include "oops/symbol.hpp" #include "runtime/interfaceSupport.hpp" +// Unconditionally clear pedantic pending JNI checks +class ClearPendingJniExcCheck : public StackObj { +private: + JavaThread* _thread; +public: + ClearPendingJniExcCheck(JNIEnv* env) : _thread(JavaThread::thread_from_jni_environment(env)) {} + ~ClearPendingJniExcCheck() { + _thread->clear_pending_jni_exception_check(); + } +}; + // Entry macro to transition from JNI to VM state. -#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header) +#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header) \ + ClearPendingJniExcCheck _clearCheck(env); + #define WB_END JNI_END #define WB_METHOD_DECLARE(result_type) extern "C" result_type JNICALL diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -1308,35 +1308,13 @@ return true; } -// sets or adds a module name to the jdk.module.addmods property -bool Arguments::append_to_addmods_property(const char* module_name) { - const char* key = "jdk.module.addmods"; - const char* old_value = Arguments::get_property(key); - size_t buf_len = strlen(key) + strlen(module_name) + 2; - if (old_value != NULL) { - buf_len += strlen(old_value) + 1; - } - char* new_value = AllocateHeap(buf_len, mtArguments); - if (new_value == NULL) { - return false; - } - if (old_value == NULL) { - jio_snprintf(new_value, buf_len, "%s=%s", key, module_name); - } else { - jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name); - } - bool added = add_property(new_value, UnwriteableProperty, InternalProperty); - FreeHeap(new_value); - return added; -} - #if INCLUDE_CDS void Arguments::check_unsupported_dumping_properties() { assert(DumpSharedSpaces, "this function is only used with -Xshare:dump"); const char* unsupported_properties[5] = { "jdk.module.main", "jdk.module.path", "jdk.module.upgrade.path", - "jdk.module.addmods", + "jdk.module.addmods.0", "jdk.module.limitmods" }; const char* unsupported_options[5] = { "-m", "--module-path", @@ -1687,11 +1665,6 @@ CompactibleFreeListSpaceLAB::modify_initialization(OldPLABSize, OldPLABWeight); } - if (!ClassUnloading) { - FLAG_SET_CMDLINE(bool, CMSClassUnloadingEnabled, false); - FLAG_SET_CMDLINE(bool, ExplicitGCInvokesConcurrentAndUnloadsClasses, false); - } - log_trace(gc)("MarkStackSize: %uk MarkStackSizeMax: %uk", (unsigned int) (MarkStackSize / K), (uint) (MarkStackSizeMax / K)); } #endif // INCLUDE_ALL_GCS @@ -2019,6 +1992,13 @@ // Keeping the heap 100% free is hard ;-) so limit it to 99%. FLAG_SET_ERGO(uintx, MinHeapFreeRatio, 99); } + + // If class unloading is disabled, also disable concurrent class unloading. + if (!ClassUnloading) { + FLAG_SET_CMDLINE(bool, CMSClassUnloadingEnabled, false); + FLAG_SET_CMDLINE(bool, ClassUnloadingWithConcurrentMark, false); + FLAG_SET_CMDLINE(bool, ExplicitGCInvokesConcurrentAndUnloadsClasses, false); + } #endif // INCLUDE_ALL_GCS } @@ -2566,8 +2546,8 @@ unsigned int addreads_count = 0; unsigned int addexports_count = 0; +unsigned int addmods_count = 0; unsigned int patch_mod_count = 0; -const char* add_modules_value = NULL; bool Arguments::create_property(const char* prop_name, const char* prop_value, PropertyInternal internal) { size_t prop_len = strlen(prop_name) + strlen(prop_value) + 2; @@ -2821,7 +2801,9 @@ return JNI_ENOMEM; } } else if (match_option(option, "--add-modules=", &tail)) { - add_modules_value = tail; + if (!create_numbered_property("jdk.module.addmods", tail, addmods_count++)) { + return JNI_ENOMEM; + } } else if (match_option(option, "--limit-modules=", &tail)) { if (!create_property("jdk.module.limitmods", tail, InternalProperty)) { return JNI_ENOMEM; @@ -2873,7 +2855,7 @@ char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtArguments), tail); add_init_agent("instrument", options, false); // java agents need module java.instrument - if (!Arguments::append_to_addmods_property("java.instrument")) { + if (!create_numbered_property("jdk.module.addmods", "java.instrument", addmods_count++)) { return JNI_ENOMEM; } } @@ -3149,7 +3131,7 @@ return JNI_EINVAL; } // management agent in module java.management - if (!Arguments::append_to_addmods_property("java.management")) { + if (!create_numbered_property("jdk.module.addmods", "java.management", addmods_count++)) { return JNI_ENOMEM; } #else @@ -3560,15 +3542,6 @@ return JNI_ERR; } - // Append the value of the last --add-modules option specified on the command line. - // This needs to be done here, to prevent overwriting possible values written - // to the jdk.module.addmods property by -javaagent and other options. - if (add_modules_value != NULL) { - if (!append_to_addmods_property(add_modules_value)) { - return JNI_ENOMEM; - } - } - // This must be done after all arguments have been processed. // java_compiler() true means set to "NONE" or empty. if (java_compiler() && !xdebug_mode()) { @@ -3617,7 +3590,8 @@ #endif #if INCLUDE_JVMCI - if (EnableJVMCI && !append_to_addmods_property("jdk.vm.ci")) { + if (EnableJVMCI && + !create_numbered_property("jdk.module.addmods", "jdk.vm.ci", addmods_count++)) { return JNI_ENOMEM; } #endif diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/runtime/arguments.hpp --- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/runtime/arguments.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -489,9 +489,6 @@ static int process_patch_mod_option(const char* patch_mod_tail, bool* patch_mod_javabase); - // Miscellaneous system property setter - static bool append_to_addmods_property(const char* module_name); - // Aggressive optimization flags. static jint set_aggressive_opts_flags(); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/runtime/interfaceSupport.hpp --- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -280,6 +280,7 @@ ~ThreadToNativeFromVM() { trans_from_native(_thread_in_vm); + assert(!_thread->is_pending_jni_exception_check(), "Pending JNI Exception Check"); // We don't need to clear_walkable because it will happen automagically when we return to java } }; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/runtime/os.hpp --- a/hotspot/src/share/vm/runtime/os.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/runtime/os.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -443,7 +443,7 @@ static bool create_thread(Thread* thread, ThreadType thr_type, - size_t stack_size = 0); + size_t req_stack_size = 0); static bool create_main_thread(JavaThread* thread); static bool create_attached_thread(JavaThread* thread); static void pd_start_thread(Thread* thread); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/runtime/sharedRuntime.cpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -621,7 +621,7 @@ // ret_pc points into caller; we are returning caller's exception handler // for given exception address SharedRuntime::compute_compiled_exc_handler(CompiledMethod* cm, address ret_pc, Handle& exception, - bool force_unwind, bool top_frame_only) { + bool force_unwind, bool top_frame_only, bool& recursive_exception_occurred) { assert(cm != NULL, "must exist"); ResourceMark rm; @@ -677,6 +677,7 @@ // BCI of the exception handler which caused the exception to be // thrown (bugs 4307310 and 4546590). Set "exception" reference // argument to ensure that the correct exception is thrown (4870175). + recursive_exception_occurred = true; exception = Handle(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; if (handler_bci >= 0) { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/runtime/sharedRuntime.hpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -189,7 +189,7 @@ // exception handling and implicit exceptions static address compute_compiled_exc_handler(CompiledMethod* nm, address ret_pc, Handle& exception, - bool force_unwind, bool top_frame_only); + bool force_unwind, bool top_frame_only, bool& recursive_exception_occurred); enum ImplicitExceptionKind { IMPLICIT_NULL, IMPLICIT_DIVIDE_BY_ZERO, diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/runtime/thread.hpp --- a/hotspot/src/share/vm/runtime/thread.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/runtime/thread.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -1542,6 +1542,9 @@ static ByteSize jmp_ring_offset() { return byte_offset_of(JavaThread, _jmp_ring); } #endif // PRODUCT static ByteSize jni_environment_offset() { return byte_offset_of(JavaThread, _jni_environment); } + static ByteSize pending_jni_exception_check_fn_offset() { + return byte_offset_of(JavaThread, _pending_jni_exception_check_fn); + } static ByteSize last_Java_sp_offset() { return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_sp_offset(); } @@ -1615,7 +1618,11 @@ assert(_jni_active_critical >= 0, "JNI critical nesting problem?"); } - // Checked JNI, is the programmer required to check for exceptions, specify which function name + // Checked JNI: is the programmer required to check for exceptions, if so specify + // which function name. Returning to a Java frame should implicitly clear the + // pending check, this is done for Native->Java transitions (i.e. user JNI code). + // VM->Java transistions are not cleared, it is expected that JNI code enclosed + // within ThreadToNativeFromVM makes proper exception checks (i.e. VM internal). bool is_pending_jni_exception_check() const { return _pending_jni_exception_check_fn != NULL; } void clear_pending_jni_exception_check() { _pending_jni_exception_check_fn = NULL; } const char* get_pending_jni_exception_check() const { return _pending_jni_exception_check_fn; } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/services/diagnosticCommand.cpp diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/trace/traceevents.xml --- a/hotspot/src/share/vm/trace/traceevents.xml Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/trace/traceevents.xml Wed Jul 05 22:16:00 2017 +0200 @@ -315,9 +315,9 @@ - - - + + + @@ -377,29 +377,29 @@ - - - - - - - - - + + + + + + + + - - - - - - + + + + + - + diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/utilities/exceptions.cpp --- a/hotspot/src/share/vm/utilities/exceptions.cpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/utilities/exceptions.cpp Wed Jul 05 22:16:00 2017 +0200 @@ -80,7 +80,7 @@ if (h_exception()->klass() == SystemDictionary::StackOverflowError_klass()) { InstanceKlass* ik = InstanceKlass::cast(h_exception->klass()); assert(ik->is_initialized(), - "need to increase min_stack_allowed calculation"); + "need to increase java_thread_min_stack_allowed calculation"); } #endif // ASSERT @@ -227,7 +227,7 @@ Klass* k = SystemDictionary::StackOverflowError_klass(); oop e = InstanceKlass::cast(k)->allocate_instance(CHECK); exception = Handle(THREAD, e); // fill_in_stack trace does gc - assert(InstanceKlass::cast(k)->is_initialized(), "need to increase min_stack_allowed calculation"); + assert(InstanceKlass::cast(k)->is_initialized(), "need to increase java_thread_min_stack_allowed calculation"); if (StackTraceInThrowable) { java_lang_Throwable::fill_in_stack_trace(exception, method()); } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp --- a/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/src/share/vm/utilities/globalDefinitions_xlc.hpp Wed Jul 05 22:16:00 2017 +0200 @@ -186,6 +186,6 @@ // Inlining support #define NOINLINE -#define ALWAYSINLINE __attribute__((always_inline)) +#define ALWAYSINLINE inline __attribute__((always_inline)) #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_XLC_HPP diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/c2/Test6968348.java --- a/hotspot/test/compiler/c2/Test6968348.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/c2/Test6968348.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,15 +38,11 @@ import java.lang.reflect.Field; public class Test6968348 { - static Unsafe unsafe; + static Unsafe unsafe = Unsafe.getUnsafe(); static final long[] buffer = new long[4096]; static int array_long_base_offset; public static void main(String[] args) throws Exception { - Class c = Test6968348.class.getClassLoader().loadClass("jdk.internal.misc.Unsafe"); - Field f = c.getDeclaredField("theUnsafe"); - f.setAccessible(true); - unsafe = (Unsafe)f.get(c); array_long_base_offset = unsafe.arrayBaseOffset(long[].class); for (int n = 0; n < 100000; n++) { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/c2/cr8004867/TestIntUnsafeCAS.java --- a/hotspot/test/compiler/c2/cr8004867/TestIntUnsafeCAS.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/c2/cr8004867/TestIntUnsafeCAS.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,14 +50,10 @@ private static final int ALIGN_OFF = 8; private static final int UNALIGN_OFF = 5; - private static final Unsafe unsafe; + private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final int BASE; static { try { - Class c = TestIntUnsafeCAS.class.getClassLoader().loadClass("jdk.internal.misc.Unsafe"); - Field f = c.getDeclaredField("theUnsafe"); - f.setAccessible(true); - unsafe = (Unsafe)f.get(c); BASE = unsafe.arrayBaseOffset(int[].class); } catch (Exception e) { InternalError err = new InternalError(); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/c2/cr8004867/TestIntUnsafeOrdered.java --- a/hotspot/test/compiler/c2/cr8004867/TestIntUnsafeOrdered.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/c2/cr8004867/TestIntUnsafeOrdered.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,14 +50,10 @@ private static final int ALIGN_OFF = 8; private static final int UNALIGN_OFF = 5; - private static final Unsafe unsafe; + private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final int BASE; static { try { - Class c = Unsafe.class; - Field f = c.getDeclaredField("theUnsafe"); - f.setAccessible(true); - unsafe = (Unsafe) f.get(c); BASE = unsafe.arrayBaseOffset(int[].class); } catch (Exception e) { InternalError err = new InternalError(); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/c2/cr8004867/TestIntUnsafeVolatile.java --- a/hotspot/test/compiler/c2/cr8004867/TestIntUnsafeVolatile.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/c2/cr8004867/TestIntUnsafeVolatile.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,14 +50,10 @@ private static final int ALIGN_OFF = 8; private static final int UNALIGN_OFF = 5; - private static final Unsafe unsafe; + private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final int BASE; static { try { - Class c = TestIntUnsafeVolatile.class.getClassLoader().loadClass("jdk.internal.misc.Unsafe"); - Field f = c.getDeclaredField("theUnsafe"); - f.setAccessible(true); - unsafe = (Unsafe)f.get(c); BASE = unsafe.arrayBaseOffset(int[].class); } catch (Exception e) { InternalError err = new InternalError(); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/codecache/OverflowCodeCacheTest.java --- a/hotspot/test/compiler/codecache/OverflowCodeCacheTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/codecache/OverflowCodeCacheTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -75,6 +75,7 @@ System.out.printf("type %s%n", type); System.out.println("allocating till possible..."); ArrayList blobs = new ArrayList<>(); + int compilationActivityMode = -1; try { long addr; int size = (int) (getHeapSize() >> 7); @@ -88,13 +89,16 @@ type + " doesn't allow using " + actualType + " when overflow"); } } - Asserts.assertNotEquals(WHITE_BOX.getCompilationActivityMode(), 1 /* run_compilation*/, - "Compilation must be disabled when CodeCache(CodeHeap) overflows"); + /* now, remember compilationActivityMode to check it later, after freeing, since we + possibly have no free cache for futher work */ + compilationActivityMode = WHITE_BOX.getCompilationActivityMode(); } finally { for (Long blob : blobs) { WHITE_BOX.freeCodeBlob(blob); } } + Asserts.assertNotEquals(compilationActivityMode, 1 /* run_compilation*/, + "Compilation must be disabled when CodeCache(CodeHeap) overflows"); } private long getHeapSize() { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/cpuflags/AESIntrinsicsBase.java --- a/hotspot/test/compiler/cpuflags/AESIntrinsicsBase.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/cpuflags/AESIntrinsicsBase.java Wed Jul 05 22:16:00 2017 +0200 @@ -48,8 +48,8 @@ = {"-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintIntrinsics"}; public static final String[] TEST_AES_CMD = {"-XX:+IgnoreUnrecognizedVMOptions", "-XX:+PrintFlagsFinal", - "-Xbatch", "-DcheckOutput=true", "-Dmode=CBC", - TestAESMain.class.getName()}; + "-Xbatch", "-XX:CompileThresholdScaling=0.01", "-DcheckOutput=true", "-Dmode=CBC", + TestAESMain.class.getName(), "100", "1000"}; protected AESIntrinsicsBase(BooleanSupplier predicate) { super(predicate); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java --- a/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java Wed Jul 05 22:16:00 2017 +0200 @@ -27,11 +27,11 @@ * @library /test/lib / * @modules java.base/jdk.internal.misc * java.management - * @ignore 8146128 * @build sun.hotspot.WhiteBox * @run driver ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * @run main/othervm/timeout=600 -Xbootclasspath/a:. + * -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -Xbatch * compiler.cpuflags.TestAESIntrinsicsOnSupportedConfig */ diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/intrinsics/unsafe/TestUnsafeMismatchedArrayFieldAccess.java --- a/hotspot/test/compiler/intrinsics/unsafe/TestUnsafeMismatchedArrayFieldAccess.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/intrinsics/unsafe/TestUnsafeMismatchedArrayFieldAccess.java Wed Jul 05 22:16:00 2017 +0200 @@ -27,7 +27,6 @@ * @bug 8142386 * @summary Unsafe access to an array is wrongly marked as mismatched * @modules java.base/jdk.internal.misc - * @library /test/lib * * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:-TieredCompilation * compiler.intrinsics.unsafe.TestUnsafeMismatchedArrayFieldAccess @@ -36,11 +35,10 @@ package compiler.intrinsics.unsafe; import jdk.internal.misc.Unsafe; -import jdk.test.lib.unsafe.UnsafeHelper; public class TestUnsafeMismatchedArrayFieldAccess { - private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); static { try { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java --- a/hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -19,7 +19,6 @@ * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") * @library /test/lib / * @library ../common/patches - * @ignore 8139383 * @modules java.base/jdk.internal.misc * @modules java.base/jdk.internal.org.objectweb.asm * java.base/jdk.internal.org.objectweb.asm.tree diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java --- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -45,7 +45,6 @@ import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject; @@ -114,7 +113,7 @@ abstract HotSpotResolvedJavaMethod getResolvedJavaMethod(); } - private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private static final WhiteBox WB = WhiteBox.getWhiteBox(); private static final Field METASPACE_METHOD_FIELD; private static final Class TEST_CLASS = GetResolvedJavaMethodTest.class; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java --- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -53,7 +53,6 @@ import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; @@ -154,7 +153,7 @@ abstract HotSpotResolvedObjectType getResolvedJavaType(); } - private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private static final WhiteBox WB = WhiteBox.getWhiteBox(); private static final Class TEST_CLASS = GetResolvedJavaTypeTest.class; /* a compressed parameter for tested method is set to false because diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java --- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveFieldInPoolTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -53,7 +53,6 @@ import jdk.internal.misc.Unsafe; import jdk.internal.org.objectweb.asm.Opcodes; import jdk.test.lib.Asserts; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; import jdk.vm.ci.meta.ConstantPool; @@ -69,7 +68,7 @@ */ public class ResolveFieldInPoolTest { - private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); public static void main(String[] args) throws Exception { Map typeTests = new HashMap<>(); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java --- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -52,7 +52,6 @@ import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.Utils; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod; import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; @@ -61,7 +60,7 @@ import java.util.Set; public class ResolveMethodTest { - private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); public static void main(String args[]) { ResolveMethodTest test = new ResolveMethodTest(); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java --- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Wed Jul 05 22:16:00 2017 +0200 @@ -25,7 +25,6 @@ * @test * @requires (vm.simpleArch == "x64" | vm.simpleArch == "sparcv9" | vm.simpleArch == "aarch64") * @library ../../../../../ - * @ignore 8161550 * @modules java.base/jdk.internal.reflect * jdk.vm.ci/jdk.vm.ci.meta * jdk.vm.ci/jdk.vm.ci.runtime @@ -74,11 +73,29 @@ /** * Tests for {@link ResolvedJavaType}. */ +@SuppressWarnings("unchecked") public class TestResolvedJavaType extends TypeUniverse { + private static final Class SIGNATURE_POLYMORPHIC_CLASS = findPolymorphicSignatureClass(); public TestResolvedJavaType() { } + private static Class findPolymorphicSignatureClass() { + Class signaturePolyAnnotation = null; + try { + for (Class clazz : TestResolvedJavaType.class.getClassLoader().loadClass("java.lang.invoke.MethodHandle").getDeclaredClasses()) { + if (clazz.getName().endsWith("PolymorphicSignature") && Annotation.class.isAssignableFrom(clazz)) { + signaturePolyAnnotation = (Class) clazz; + break; + } + } + } catch (Throwable e) { + throw new AssertionError("Could not find annotation PolymorphicSignature in java.lang.invoke.MethodHandle", e); + } + assertNotNull(signaturePolyAnnotation); + return signaturePolyAnnotation; + } + @Test public void findInstanceFieldWithOffsetTest() { for (Class c : classes) { @@ -577,8 +594,14 @@ for (Method decl : decls) { ResolvedJavaMethod m = metaAccess.lookupJavaMethod(decl); if (m.isPublic()) { - ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl); - assertEquals(m.toString(), i, type.resolveMethod(m, context)); + ResolvedJavaMethod resolvedmethod = type.resolveMethod(m, context); + if (isSignaturePolymorphic(m)) { + // Signature polymorphic methods must not be resolved + assertNull(resolvedmethod); + } else { + ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl); + assertEquals(m.toString(), i, resolvedmethod); + } } } } @@ -606,8 +629,14 @@ for (Method decl : decls) { ResolvedJavaMethod m = metaAccess.lookupJavaMethod(decl); if (m.isPublic()) { - ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl); - assertEquals(i, type.resolveConcreteMethod(m, context)); + ResolvedJavaMethod resolvedMethod = type.resolveConcreteMethod(m, context); + if (isSignaturePolymorphic(m)) { + // Signature polymorphic methods must not be resolved + assertNull(String.format("Got: %s", resolvedMethod), resolvedMethod); + } else { + ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl); + assertEquals(i, resolvedMethod); + } } } } @@ -929,4 +958,8 @@ } } } + + private static boolean isSignaturePolymorphic(ResolvedJavaMethod method) { + return method.getAnnotation(SIGNATURE_POLYMORPHIC_CLASS) != null; + } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/loopopts/UseCountedLoopSafepoints.java --- a/hotspot/test/compiler/loopopts/UseCountedLoopSafepoints.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/loopopts/UseCountedLoopSafepoints.java Wed Jul 05 22:16:00 2017 +0200 @@ -22,51 +22,32 @@ * */ -/** - * @test - * @bug 6869327 - * @summary Test that C2 flag UseCountedLoopSafepoints ensures a safepoint is kept in a CountedLoop - * @library /test/lib - * @modules java.base/jdk.internal.misc - * @ignore 8146096 - * @run driver compiler.loopopts.UseCountedLoopSafepoints - */ - package compiler.loopopts; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; - -import java.util.concurrent.atomic.AtomicLong; +import java.lang.reflect.Method; +import sun.hotspot.WhiteBox; +import jdk.test.lib.Asserts; +import compiler.whitebox.CompilerWhiteBoxTest; public class UseCountedLoopSafepoints { - private static final AtomicLong _num = new AtomicLong(0); + private static final WhiteBox WB = WhiteBox.getWhiteBox(); + private static final String METHOD_NAME = "testMethod"; - // Uses the fact that an EnableBiasedLocking vmop will be started - // after 500ms, while we are still in the loop. If there is a - // safepoint in the counted loop, then we will reach safepoint - // very quickly. Otherwise SafepointTimeout will be hit. + private long accum = 0; + public static void main (String args[]) throws Exception { - if (args.length == 1) { - final int loops = Integer.parseInt(args[0]); - for (int i = 0; i < loops; i++) { - _num.addAndGet(1); - } - } else { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:+IgnoreUnrecognizedVMOptions", - "-XX:-TieredCompilation", - "-XX:+UseBiasedLocking", - "-XX:BiasedLockingStartupDelay=500", - "-XX:+SafepointTimeout", - "-XX:SafepointTimeoutDelay=2000", - "-XX:+UseCountedLoopSafepoints", - UseCountedLoopSafepoints.class.getName(), - "2000000000" - ); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldNotContain("Timeout detected"); - output.shouldHaveExitValue(0); + new UseCountedLoopSafepoints().testMethod(); + Method m = UseCountedLoopSafepoints.class.getDeclaredMethod(METHOD_NAME); + String directive = "[{ match: \"" + UseCountedLoopSafepoints.class.getName().replace('.', '/') + + "." + METHOD_NAME + "\", " + "BackgroundCompilation: false }]"; + Asserts.assertTrue(WB.addCompilerDirective(directive) == 1, "Can't add compiler directive"); + Asserts.assertTrue(WB.enqueueMethodForCompilation(m, + CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION), "Can't enqueue method"); + } + + private void testMethod() { + for (int i = 0; i < 100; i++) { + accum += accum << 5 + accum >> 4 - accum >>> 5; } } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/loopopts/UseCountedLoopSafepointsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/loopopts/UseCountedLoopSafepointsTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 6869327 + * @summary Test that C2 flag UseCountedLoopSafepoints ensures a safepoint is kept in a CountedLoop + * @library /test/lib / + * @requires vm.compMode != "Xint" & vm.flavor == "server" & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 4) + * @modules java.base/jdk.internal.misc + * @build sun.hotspot.WhiteBox + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run driver compiler.loopopts.UseCountedLoopSafepointsTest + */ + +package compiler.loopopts; + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import jdk.test.lib.Asserts; + +/* Idea of this test is to check if ideal graph has CountedLoopEnd->SafePoint edge in case + of UseCountedLoopSafepoint enabled and has no such edge in case it's disabled. Restricting + compilation to testMethod only will leave only one counted loop (the one in testedMethod) */ +public class UseCountedLoopSafepointsTest { + + public static void main (String args[]) { + check(true); // check ideal graph with UseCountedLoopSafepoint enabled + check(false); // ... and disabled + } + + private static void check(boolean enabled) { + OutputAnalyzer oa; + try { + oa = ProcessTools.executeTestJvm("-XX:+UnlockDiagnosticVMOptions", "-Xbootclasspath/a:.", + "-XX:" + (enabled ? "+" : "-") + "UseCountedLoopSafepoints", "-XX:+WhiteBoxAPI", + "-XX:-Inline", "-Xbatch", "-XX:+PrintIdeal", "-XX:LoopUnrollLimit=0", + "-XX:CompileOnly=" + UseCountedLoopSafepoints.class.getName() + "::testMethod", + UseCountedLoopSafepoints.class.getName()); + } catch (Exception e) { + throw new Error("Exception launching child for case enabled=" + enabled + " : " + e, e); + } + oa.shouldHaveExitValue(0); + // parse output in seach of SafePoint and CountedLoopEnd nodes + List safePoints = new ArrayList<>(); + List loopEnds = new ArrayList<>(); + for (String line : oa.getOutput().split("\\n")) { + int separatorIndex = line.indexOf("\t==="); + if (separatorIndex > -1) { + String header = line.substring(0, separatorIndex); + if (header.endsWith("\tSafePoint")) { + safePoints.add(new Node("SafePoint", line)); + } else if (header.endsWith("\tCountedLoopEnd")) { + loopEnds.add(new Node("CountedLoopEnd", line)); + } + } + } + // now, find CountedLoopEnd -> SafePoint edge + boolean found = false; + for (Node loopEnd : loopEnds) { + found |= loopEnd.to.stream() + .filter(id -> nodeListHasElementWithId(safePoints, id)) + .findAny() + .isPresent(); + } + Asserts.assertEQ(enabled, found, "Safepoint " + (found ? "" : "not ") + "found"); + } + + private static boolean nodeListHasElementWithId(List list, int id) { + return list.stream() + .filter(node -> node.id == id) + .findAny() + .isPresent(); + } + + private static class Node { + public final int id; + public final List from; + public final List to; + + public Node(String name, String str) { + List tmpFrom = new ArrayList<>(); + List tmpTo = new ArrayList<>(); + // parse string like: " $id $name === $to1 $to2 ... [[ $from1 $from2 ... ]] $anything" + // example: 318 SafePoint === 317 1 304 1 1 10 308 [[ 97 74 ]] ... + id = Integer.parseInt(str.substring(1, str.indexOf(name)).trim()); + Arrays.stream(str.substring(str.indexOf("===") + 4, str.indexOf("[[")).trim().split("\\s+")) + .map(Integer::parseInt) + .forEach(tmpTo::add); + Arrays.stream(str.substring(str.indexOf("[[") + 3, str.indexOf("]]")).trim().split("\\s+")) + .map(Integer::parseInt) + .forEach(tmpFrom::add); + this.from = Collections.unmodifiableList(tmpFrom); + this.to = Collections.unmodifiableList(tmpTo); + } + } +} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/loopopts/superword/TestVectorizationWithInvariant.java --- a/hotspot/test/compiler/loopopts/superword/TestVectorizationWithInvariant.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/loopopts/superword/TestVectorizationWithInvariant.java Wed Jul 05 22:16:00 2017 +0200 @@ -34,7 +34,6 @@ package compiler.loopopts.superword; import jdk.internal.misc.Unsafe; -import jdk.test.lib.unsafe.UnsafeHelper; public class TestVectorizationWithInvariant { @@ -43,7 +42,7 @@ private static final long CHAR_ARRAY_OFFSET; static { - unsafe = UnsafeHelper.getUnsafe(); + unsafe = Unsafe.getUnsafe(); BYTE_ARRAY_OFFSET = unsafe.arrayBaseOffset(byte[].class); CHAR_ARRAY_OFFSET = unsafe.arrayBaseOffset(char[].class); } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java --- a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Wed Jul 05 22:16:00 2017 +0200 @@ -49,7 +49,6 @@ import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -125,7 +124,7 @@ public static class Test implements CompilableTest { private static final int TOTAL_ITERATIONS = 10000; private static final int WARMUP_ITERATIONS = 1000; - private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private final Object monitor = new Object(); // Following field have to be static in order to avoid escape analysis. @SuppressWarnings("UnsuedDeclaration") diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java --- a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Wed Jul 05 22:16:00 2017 +0200 @@ -51,7 +51,6 @@ import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -158,7 +157,7 @@ private static int field = 0; private static final int ITERATIONS = 10000; private static final int RANGE_CHECK_AT = ITERATIONS / 2; - private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private final Object monitor = new Object(); @Override diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java --- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Wed Jul 05 22:16:00 2017 +0200 @@ -48,7 +48,6 @@ import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -133,7 +132,7 @@ } public static class Test implements CompilableTest { - private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private final Object monitor = new Object(); @Override diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java --- a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Wed Jul 05 22:16:00 2017 +0200 @@ -49,7 +49,6 @@ import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -142,7 +141,7 @@ @SuppressWarnings("UnsuedDeclaration") private static int field = 0; private static final int TOTAL_ITERATIONS = 10000; - private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private final Object monitor = new Object(); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java --- a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Wed Jul 05 22:16:00 2017 +0200 @@ -49,7 +49,6 @@ import jdk.internal.misc.Unsafe; import jdk.test.lib.Asserts; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.test.lib.cli.CommandLineOptionTest; import jdk.test.lib.cli.predicate.AndPredicate; @@ -113,7 +112,7 @@ public static class Test implements CompilableTest { private static final long TOTAL_ITERATIONS = 10000L; - private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private final Object monitor = new Object(); // Following field have to be static in order to avoid escape analysis. @SuppressWarnings("UnsuedDeclaration") diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java --- a/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/testlibrary/rtm/XAbortProvoker.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package compiler.testlibrary.rtm; import jdk.internal.misc.Unsafe; -import jdk.test.lib.unsafe.UnsafeHelper; /** * Current RTM locking implementation force transaction abort @@ -35,7 +34,7 @@ // Following field have to be static in order to avoid escape analysis. @SuppressWarnings("UnsuedDeclaration") private static int field = 0; - private static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); public XAbortProvoker() { this(new Object()); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/unsafe/UnsafeOffHeapBooleanTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/unsafe/UnsafeOffHeapBooleanTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8161720 + * @modules java.base/jdk.internal.misc + * @run main/othervm -Xint UnsafeOffHeapBooleanTest 1 + * @run main/othervm -XX:+TieredCompilation -XX:TieredStopAtLevel=3 -Xbatch UnsafeOffHeapBooleanTest 20000 + * @run main/othervm -XX:-TieredCompilation -Xbatch UnsafeOffHeapBooleanTest 20000 + */ + + +import java.lang.reflect.Field; +import jdk.internal.misc.Unsafe; + +public class UnsafeOffHeapBooleanTest { + static boolean bool0 = false, bool1 = false, result = false; + static Unsafe UNSAFE = Unsafe.getUnsafe(); + static long offHeapMemory; + + public static void test() { + // Write two bytes to the off-heap memory location, both + // bytes correspond to the boolean value 'true'. + UNSAFE.putShort(null, offHeapMemory, (short)0x0204); + + // Read two bytes from the storage allocated above (as booleans). + bool0 = UNSAFE.getBoolean(null, offHeapMemory + 0); + bool1 = UNSAFE.getBoolean(null, offHeapMemory + 1); + result = bool0 & bool1; + } + + public static void main(String args[]) { + System.out.println("### Test started"); + + if (args.length != 1) { + throw new RuntimeException("### Test failure: test called with incorrect number of arguments"); + } + + // Allocate two bytes of storage. + offHeapMemory = UNSAFE.allocateMemory(2); + + try { + for (int i = 0; i < Integer.parseInt(args[0]); i++) { + test(); + } + + // Check if the two 'true' boolean values were normalized + // (i.e., reduced from the range 1...255 to 1). + if (!bool0 || !bool1 || !result) { + System.out.println("Some of the results below are wrong"); + System.out.println("bool0 is: " + bool0); + System.out.println("bool1 is: " + bool1); + System.out.println("bool0 & bool1 is: " + result); + System.out.println("==================================="); + throw new RuntimeException("### Test failed"); + } else { + System.out.println("Test generated correct results"); + System.out.println("bool0 is: " + bool0); + System.out.println("bool1 is: " + bool1); + System.out.println("bool0 & bool1 is: " + result); + System.out.println("==================================="); + } + } catch (NumberFormatException e) { + throw new RuntimeException("### Test failure: test called with incorrectly formatted parameter"); + } + + UNSAFE.freeMemory(offHeapMemory); + + System.out.println("### Test passed"); + } +} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/unsafe/UnsafeOnHeapBooleanTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/unsafe/UnsafeOnHeapBooleanTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8161720 + * @modules java.base/jdk.internal.misc + * @run main/othervm -Xint UnsafeOnHeapBooleanTest 1 + * @run main/othervm -XX:-UseOnStackReplacement -XX:+TieredCompilation -XX:TieredStopAtLevel=3 -Xbatch UnsafeOnHeapBooleanTest 20000 + * @run main/othervm -XX:-UseOnStackReplacement -XX:-TieredCompilation -Xbatch UnsafeOnHeapBooleanTest 20000 + */ + +import java.lang.reflect.Field; +import jdk.internal.misc.Unsafe; + +public class UnsafeOnHeapBooleanTest { + static short static_v; + static boolean bool0 = false, bool1 = false, result = false; + static Unsafe UNSAFE = Unsafe.getUnsafe(); + + public static void test() { + try { + // Write two bytes into the static field + // UnsafeOnHeapBooleanTest.static_v write two values. Both + // bytes correspond to the boolean value 'true'. + Field staticVField = UnsafeOnHeapBooleanTest.class.getDeclaredField("static_v"); + Object base = UNSAFE.staticFieldBase(staticVField); + long offset = UNSAFE.staticFieldOffset(staticVField); + UNSAFE.putShort(base, offset, (short)0x0204); + + // Read two bytes from the static field + // UnsafeOnHeapBooleanTest.static_v (as booleans). + bool0 = UNSAFE.getBoolean(base, offset + 0); + bool1 = UNSAFE.getBoolean(base, offset + 1); + result = bool0 & bool1; + } catch (NoSuchFieldException e) { + throw new RuntimeException("### Test failure: static field UnsafeOnHeapBooleanTest.static_v was not found"); + } + } + + public static void main(String args[]) { + System.out.println("### Test started"); + + if (args.length != 1) { + throw new RuntimeException("### Test failure: test called with incorrect number of arguments"); + } + + try { + for (int i = 0; i < Integer.parseInt(args[0]); i++) { + test(); + } + + // Check if the two 'true' boolean values were normalized + // (i.e., reduced from the range 1...255 to 1). + if (!bool0 || !bool1 || !result) { + System.out.println("Some of the results below are wrong"); + System.out.println("bool0 is: " + bool0); + System.out.println("bool1 is: " + bool1); + System.out.println("bool0 & bool1 is: " + result); + System.out.println("==================================="); + throw new RuntimeException("### Test failed"); + } else { + System.out.println("Test generated correct results"); + System.out.println("bool0 is: " + bool0); + System.out.println("bool1 is: " + bool1); + System.out.println("bool0 & bool1 is: " + result); + System.out.println("==================================="); + } + } catch (NumberFormatException e) { + throw new RuntimeException("### Test failure: test called with incorrectly formatted parameter"); + } + + System.out.println("### Test passed"); + } +} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/unsafe/UnsafeRaw.java --- a/hotspot/test/compiler/unsafe/UnsafeRaw.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/compiler/unsafe/UnsafeRaw.java Wed Jul 05 22:16:00 2017 +0200 @@ -35,7 +35,6 @@ import jdk.internal.misc.Unsafe; import jdk.test.lib.Utils; -import jdk.test.lib.unsafe.UnsafeHelper; import java.util.Random; @@ -82,7 +81,7 @@ } public static void main(String[] args) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); final int array_size = 128; final int element_size = 4; final int magic = 0x12345678; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/compiler/unsafe/UnsafeSmallOffsetBooleanAccessTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/unsafe/UnsafeSmallOffsetBooleanAccessTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8161720 + * @modules java.base/jdk.internal.misc + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:-TieredCompilation UnsafeSmallOffsetBooleanAccessTest + * @run main/othervm -Xbatch UnsafeSmallOffsetBooleanAccessTest + */ + +import java.util.Random; +import jdk.internal.misc.Unsafe; + +public class UnsafeSmallOffsetBooleanAccessTest { + static final Unsafe UNSAFE = Unsafe.getUnsafe(); + static final long F_OFFSET; + static final Random random = new Random(); + + static { + try { + F_OFFSET = UNSAFE.objectFieldOffset(T.class.getDeclaredField("f")); + System.out.println("The offset is: " + F_OFFSET); + } catch (Exception e) { + throw new Error(e); + } + } + + static class T { + boolean f; + } + + // Always return false in a way that is not obvious to the compiler. + public static boolean myRandom() { + if (random.nextInt(101) > 134) { + return true; + } else { + return false; + } + } + + public static boolean test(T t) { + boolean result = false; + for (int i = 0; i < 20000; i++) { + boolean random = myRandom(); + // If myRandom() returns false, access t.f. + // + // If myRandom() returns true, access virtual address + // F_OFFSET. That address is most likely not mapped, + // therefore the access will most likely cause a + // crash. We're not concerned about that, though, because + // myRandom() always returns false. However, the C2 + // compiler avoids normalization of the value returned by + // getBoolean in this case. + result = UNSAFE.getBoolean(myRandom() ? null : t, F_OFFSET); + } + return result; + } + + public static void main(String[] args) { + T t = new T(); + UNSAFE.putBoolean(t, F_OFFSET, true); + System.out.println("The result for t is: " + test(t)); + } +} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java --- a/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/gc/arguments/TestMaxMinHeapFreeRatioFlags.java Wed Jul 05 22:16:00 2017 +0200 @@ -37,7 +37,6 @@ import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.Utils; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; public class TestMaxMinHeapFreeRatioFlags { @@ -134,7 +133,7 @@ */ public static class RatioVerifier { - private static final Unsafe unsafe = UnsafeHelper.getUnsafe(); + private static final Unsafe unsafe = Unsafe.getUnsafe(); // Size of byte array that will be allocated public static final int CHUNK_SIZE = 1024; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java --- a/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/gc/arguments/TestTargetSurvivorRatioFlag.java Wed Jul 05 22:16:00 2017 +0200 @@ -46,7 +46,6 @@ import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.Utils; -import jdk.test.lib.unsafe.UnsafeHelper; import sun.hotspot.WhiteBox; /* In order to test that TargetSurvivorRatio affects survivor space occupancy @@ -249,7 +248,7 @@ public static class TargetSurvivorRatioVerifier { static final WhiteBox wb = WhiteBox.getWhiteBox(); - static final Unsafe unsafe = UnsafeHelper.getUnsafe(); + static final Unsafe unsafe = Unsafe.getUnsafe(); // Desired size of memory allocated at once public static final int CHUNK_SIZE = 1024; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/gc/class_unloading/TestClassUnloadingDisabled.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/class_unloading/TestClassUnloadingDisabled.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reqserved. + * 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 + * @key gc + * @bug 8114823 + * @requires vm.gc == null + * @requires vm.opt.ExplicitGCInvokesConcurrent != true + * @requires vm.opt.ClassUnloading != true + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.management + * @build sun.hotspot.WhiteBox + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-ClassUnloading -XX:+UseG1GC TestClassUnloadingDisabled + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-ClassUnloading -XX:+UseSerialGC TestClassUnloadingDisabled + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-ClassUnloading -XX:+UseParallelGC TestClassUnloadingDisabled + * + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-ClassUnloading -XX:+UseConcMarkSweepGC TestClassUnloadingDisabled + */ + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import sun.hotspot.WhiteBox; + +import static jdk.test.lib.Asserts.*; + +public class TestClassUnloadingDisabled { + public static void main(String args[]) throws Exception { + final WhiteBox wb = WhiteBox.getWhiteBox(); + // Fetch the dir where the test class and the class + // to be loaded resides. + String classDir = TestClassUnloadingDisabled.class.getProtectionDomain().getCodeSource().getLocation().getPath(); + String className = "ClassToLoadUnload"; + + assertFalse(wb.isClassAlive(className), "Should not be loaded yet"); + + // The NoPDClassLoader handles loading classes in the test directory + // and loads them without a protection domain, which in some cases + // keeps the class live regardless of marking state. + NoPDClassLoader nopd = new NoPDClassLoader(classDir); + nopd.loadClass(className); + + assertTrue(wb.isClassAlive(className), "Class should be loaded"); + + // Clear the class-loader, class and object references to make + // class unloading possible. + nopd = null; + + System.gc(); + assertTrue(wb.isClassAlive(className), "Class should not have ben unloaded"); + } +} + +class NoPDClassLoader extends ClassLoader { + String path; + + NoPDClassLoader(String path) { + this.path = path; + } + + public Class loadClass(String name) throws ClassNotFoundException { + byte[] cls = null; + File f = new File(path,name + ".class"); + + // Delegate class loading if class not present in the given + // directory. + if (!f.exists()) { + return super.loadClass(name); + } + + try { + Path path = Paths.get(f.getAbsolutePath()); + cls = Files.readAllBytes(path); + } catch (IOException e) { + throw new ClassNotFoundException(name); + } + + // Define class with no protection domain and resolve it. + return defineClass(name, cls, 0, cls.length, null); + } +} + +class ClassToLoadUnload { +} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/jprt.config --- a/hotspot/test/jprt.config Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/jprt.config Wed Jul 05 22:16:00 2017 +0200 @@ -86,12 +86,12 @@ fi # Add basic solaris system paths - path4sdk=/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin + path4sdk=/usr/bin # Find GNU make - make=/usr/sfw/bin/gmake + make=/usr/bin/gmake if [ ! -f ${make} ] ; then - make=/opt/sfw/bin/gmake + make=/usr/gnu/bin/make if [ ! -f ${make} ] ; then make=${slashjava}/devtools/${solaris_arch}/bin/gnumake fi diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java --- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java Wed Jul 05 22:16:00 2017 +0200 @@ -89,20 +89,6 @@ excludeTestMaxRange("CICompilerCount"); /* - * JDK-8136766 - * Temporarily remove ThreadStackSize from testing because Windows can set it to 0 - * (for default OS size) but other platforms insist it must be greater than 0 - */ - excludeTestRange("ThreadStackSize"); - - /* - * Remove the flag controlling the size of the stack because the - * flag has direct influence on the physical memory usage of - * the VM. - */ - allOptionsAsMap.remove("CompilerThreadStackSize"); - - /* * Exclude MallocMaxTestWords as it is expected to exit VM at small values (>=0) */ excludeTestMinRange("MallocMaxTestWords"); @@ -124,6 +110,8 @@ excludeTestMaxRange("OldSize"); excludeTestMaxRange("ParallelGCThreads"); + excludeTestMaxRange("CompilerThreadStackSize"); + excludeTestMaxRange("ThreadStackSize"); excludeTestMaxRange("VMThreadStackSize"); /* diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java --- a/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/ErrorHandling/CreateCoredumpOnCrash.java Wed Jul 05 22:16:00 2017 +0200 @@ -34,13 +34,12 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.Platform; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; public class CreateCoredumpOnCrash { private static class Crasher { public static void main(String[] args) { - UnsafeHelper.getUnsafe().putInt(0L, 0); + Unsafe.getUnsafe().putInt(0L, 0); } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java --- a/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/ErrorHandling/ProblematicFrameTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -35,14 +35,13 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; public class ProblematicFrameTest { private static class Crasher { public static void main(String[] args) { - UnsafeHelper.getUnsafe().getInt(0); + Unsafe.getUnsafe().getInt(0); } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/LocalLong/LocalLongHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/LocalLong/LocalLongHelper.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.lang.StackWalker.StackFrame; + +public class LocalLongHelper { + static StackWalker sw; + static Method intValue; + static Method getLocals; + static Class primitiveValueClass; + static Method primitiveType; + static Method getMethodType; + static Field memberName; + static Field offset; + + public static void main(String[] args) throws Throwable { + setupReflectionStatics(); + new LocalLongHelper().longArg(0xC0FFEE, 0x1234567890ABCDEFL); + } + + // locals[2] contains the high byte of the long argument. + public long longArg(int i, long l) throws Throwable { + List frames = sw.walk(s -> s.collect(Collectors.toList())); + Object[] locals = (Object[]) getLocals.invoke(frames.get(0)); + + int locals_2 = (int) intValue.invoke(locals[2]); + if (locals_2 != 0){ + throw new RuntimeException("Expected locals_2 == 0"); + } + return l; // Don't want l to become a dead var + } + + private static void setupReflectionStatics() throws Throwable { + Class liveStackFrameClass = Class.forName("java.lang.LiveStackFrame"); + primitiveValueClass = Class.forName("java.lang.LiveStackFrame$PrimitiveValue"); + + getLocals = liveStackFrameClass.getDeclaredMethod("getLocals"); + getLocals.setAccessible(true); + + intValue = primitiveValueClass.getDeclaredMethod("intValue"); + intValue.setAccessible(true); + + Class stackFrameInfoClass = Class.forName("java.lang.StackFrameInfo"); + memberName = stackFrameInfoClass.getDeclaredField("memberName"); + memberName.setAccessible(true); + offset = stackFrameInfoClass.getDeclaredField("bci"); + offset.setAccessible(true); + getMethodType = Class.forName("java.lang.invoke.MemberName").getDeclaredMethod("getMethodType"); + getMethodType.setAccessible(true); + + Class extendedOptionClass = Class.forName("java.lang.StackWalker$ExtendedOption"); + Method ewsNI = StackWalker.class.getDeclaredMethod("newInstance", Set.class, extendedOptionClass); + ewsNI.setAccessible(true); + Field f = extendedOptionClass.getDeclaredField("LOCALS_AND_OPERANDS"); + f.setAccessible(true); + Object localsAndOperandsOption = f.get(null); + + primitiveType = primitiveValueClass.getDeclaredMethod("type"); + primitiveType.setAccessible(true); + + sw = (StackWalker) ewsNI.invoke(null, java.util.Collections.emptySet(), localsAndOperandsOption); + } + + private static String type(Object o) throws Throwable { + if (primitiveValueClass.isInstance(o)) { + final char c = (char) primitiveType.invoke(o); + return String.valueOf(c); + } else if (o != null) { + return o.getClass().getName(); + } else { + return "null"; + } + } +} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/LocalLong/LocalLongTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/LocalLong/LocalLongTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/* + * @test LocalLongTest + * @bug 8163014 + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @compile LocalLongHelper.java + * @run driver LocalLongTest + */ + +import jdk.test.lib.Platform; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class LocalLongTest { + public static void main(String... args) throws Exception { + if (Platform.is64bit()) { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xint", + "LocalLongHelper"); + OutputAnalyzer o = new OutputAnalyzer(pb.start()); + o.shouldHaveExitValue(0); + } + }; +} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/NMT/CheckForProperDetailStackTrace.java --- a/hotspot/test/runtime/NMT/CheckForProperDetailStackTrace.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/NMT/CheckForProperDetailStackTrace.java Wed Jul 05 22:16:00 2017 +0200 @@ -57,11 +57,6 @@ private static String expectedSymbol = "locked_create_entry_or_null"; - private static final String jdkDebug = System.getProperty("jdk.debug"); - private static boolean isSlowDebugBuild() { - return (jdkDebug.toLowerCase().equals("slowdebug")); - } - public static void main(String args[]) throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-XX:+UnlockDiagnosticVMOptions", @@ -76,11 +71,12 @@ output.shouldNotContain("NativeCallStack::NativeCallStack"); output.shouldNotContain("os::get_native_stack"); - // AllocateHeap shouldn't be in the output because it is suppose to always be inlined. - // We check for that here, but allow it for Windows and Solaris slowdebug builds because - // the compiler ends up not inlining AllocateHeap. + // AllocateHeap shouldn't be in the output because it is supposed to always be inlined. + // We check for that here, but allow it for Aix, Solaris and Windows slowdebug builds + // because the compiler ends up not inlining AllocateHeap. Boolean okToHaveAllocateHeap = - isSlowDebugBuild() && (Platform.isSolaris() || Platform.isWindows()); + Platform.isSlowDebugBuild() && + (Platform.isAix() || Platform.isSolaris() || Platform.isWindows()); if (!okToHaveAllocateHeap) { output.shouldNotContain("AllocateHeap"); } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Thread/TooSmallStackSize.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/Thread/TooSmallStackSize.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8140520 + * @summary Setting small CompilerThreadStackSize, ThreadStackSize, and + * VMThreadStackSize values should result in an error message that shows + * the minimum stack size value for each thread type. + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.management + * @run main TooSmallStackSize + */ + +/* + * The primary purpose of this test is to make sure we can run with a + * stack smaller than the minimum without crashing. Also this test will + * determine the minimum allowed stack size for the platform (as + * provided by the JVM error message when a very small stack is used), + * and then verify that the JVM can be launched with that stack size + * without a crash or any error messages. + * + * Note: The '-Xss' and '-XX:ThreadStackSize=' options + * both control Java thread stack size. This repo's version of the test + * exercises the '-XX:ThreadStackSize' VM option. The jdk repo's version + * of the test exercises the '-Xss' option. + */ + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TooSmallStackSize { + /* for debugging. Normally false. */ + static final boolean verbose = false; + static final String CompilerThreadStackSizeString = "CompilerThreadStackSize"; + static final String ThreadStackSizeString = "Java thread stack size"; + static final String VMThreadStackSizeString = "VMThreadStackSize"; + + /* + * Returns the minimum stack size this platform will allowed based on the + * contents of the error message the JVM outputs when too small of a + * stack size was used. + * + * The testOutput argument must contain the result of having already run + * the JVM with too small of a stack size. + */ + static String getMinStackAllowed(String testOutput) { + /* + * The JVM output will contain in one of the lines: + * "The CompilerThreadStackSize specified is too small. Specify at least 100k" + * "The Java thread stack size specified is too small. Specify at least 100k" + * "The VMThreadStackSize specified is too small. Specify at least 100k" + * Although the actual size will vary. We need to extract this size + * string from the output and return it. + */ + String matchStr = "Specify at least "; + int match_idx = testOutput.indexOf(matchStr); + if (match_idx >= 0) { + int size_start_idx = match_idx + matchStr.length(); + int k_start_idx = testOutput.indexOf("k", size_start_idx); + // don't include the 'k'; the caller will have to + // add it back as needed. + return testOutput.substring(size_start_idx, k_start_idx); + } + + System.out.println("Expect='" + matchStr + "'"); + System.out.println("Actual: " + testOutput); + System.out.println("FAILED: Could not get the stack size from the output"); + throw new RuntimeException("test fails"); + } + + /* + * Run the JVM with the specified stack size. + * + * Returns the minimum allowed stack size gleaned from the error message, + * if there is an error message. Otherwise returns the stack size passed in. + */ + static String checkStack(String stackOption, String optionMesg, String stackSize) throws Exception { + String min_stack_allowed; + + System.out.println("*** Testing " + stackOption + stackSize); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + stackOption + stackSize, + // Uncomment the following to get log output + // that shows actual thread creation sizes. + // "-Xlog:os+thread", + "-version"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + if (verbose) { + System.out.println("stdout: " + output.getStdout()); + } + + if (output.getExitValue() == 0) { + // checkMinStackAllowed() is called with stackSize values + // that should be the minimum that works. This method, + // checkStack(), is called with stackSize values that + // should be too small and result in error messages. + // However, some platforms fix up a stackSize value that is + // too small into something that works so we have to allow + // for checkStack() calls that work. + System.out.println("PASSED: got exit_code == 0 with " + stackOption + stackSize); + min_stack_allowed = stackSize; + } else { + String expect = "The " + optionMesg + " specified is too small"; + if (verbose) { + System.out.println("Expect='" + expect + "'"); + } + output.shouldContain(expect); + min_stack_allowed = getMinStackAllowed(output.getStdout()); + + System.out.println("PASSED: got expected error message with " + stackOption + stackSize); + } + + return min_stack_allowed; + } + + /* + * Run the JVM with the minimum allowed stack size. This should always succeed. + */ + static void checkMinStackAllowed(String stackOption, String optionMesg, String stackSize) throws Exception { + System.out.println("*** Testing " + stackOption + stackSize); + + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + stackOption + stackSize, + // Uncomment the following to get log output + // that shows actual thread creation sizes. + // "-Xlog:os+thread", + "-version"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + System.out.println("PASSED: VM launched with " + stackOption + stackSize); + } + + public static void main(String... args) throws Exception { + /* + * The result of a 16k stack size should be a quick exit with a complaint + * that the stack size is too small. However, for some win32 builds, the + * stack is always at least 64k, and this also sometimes is the minimum + * allowed size, so we won't see an error in this case. + * + * This test case will also produce a crash on some platforms if the fix + * for 6762191 is not yet in place. + */ + checkStack("-XX:ThreadStackSize=", ThreadStackSizeString, "16"); + + /* + * Try with a 32k stack size, which is the size that the launcher will + * set to if you try setting to anything smaller. This should produce the same + * result as setting to 16k if the fix for 6762191 is in place. + */ + String min_stack_allowed = checkStack("-XX:ThreadStackSize=", ThreadStackSizeString, "32"); + + /* + * Try again with a the minimum stack size that was given in the error message + */ + checkMinStackAllowed("-XX:ThreadStackSize=", ThreadStackSizeString, min_stack_allowed); + + /* + * Now redo the same tests with the compiler thread stack size: + */ + checkStack("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "16"); + min_stack_allowed = checkStack("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, "32"); + checkMinStackAllowed("-XX:CompilerThreadStackSize=", CompilerThreadStackSizeString, min_stack_allowed); + + /* + * Now redo the same tests with the VM thread stack size: + */ + checkStack("-XX:VMThreadStackSize=", VMThreadStackSizeString, "16"); + min_stack_allowed = checkStack("-XX:VMThreadStackSize=", VMThreadStackSizeString, "32"); + checkMinStackAllowed("-XX:VMThreadStackSize=", VMThreadStackSizeString, min_stack_allowed); + } +} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/AllocateInstance.java --- a/hotspot/test/runtime/Unsafe/AllocateInstance.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/AllocateInstance.java Wed Jul 05 22:16:00 2017 +0200 @@ -30,12 +30,11 @@ * @run main AllocateInstance */ -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class AllocateInstance { - static final Unsafe UNSAFE = UnsafeHelper.getUnsafe(); + static final Unsafe UNSAFE = Unsafe.getUnsafe(); class TestClass { public boolean calledConstructor = false; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/AllocateMemory.java --- a/hotspot/test/runtime/Unsafe/AllocateMemory.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/AllocateMemory.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m AllocateMemory */ -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class AllocateMemory { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); // Allocate a byte, write to the location and read back the value long address = unsafe.allocateMemory(1); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/CopyMemory.java --- a/hotspot/test/runtime/Unsafe/CopyMemory.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/CopyMemory.java Wed Jul 05 22:16:00 2017 +0200 @@ -30,14 +30,13 @@ * @run main CopyMemory */ -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class CopyMemory { final static int LENGTH = 8; public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); long src = unsafe.allocateMemory(LENGTH); long dst = unsafe.allocateMemory(LENGTH); assertNotEquals(src, 0L); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/DefineClass.java --- a/hotspot/test/runtime/Unsafe/DefineClass.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/DefineClass.java Wed Jul 05 22:16:00 2017 +0200 @@ -34,13 +34,12 @@ import java.security.ProtectionDomain; import java.io.InputStream; import jdk.test.lib.InMemoryJavaCompiler; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class DefineClass { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); TestClassLoader classloader = new TestClassLoader(); ProtectionDomain pd = new ProtectionDomain(null, null); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/FieldOffset.java --- a/hotspot/test/runtime/Unsafe/FieldOffset.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/FieldOffset.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,14 +31,13 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import java.lang.reflect.*; import static jdk.test.lib.Asserts.*; public class FieldOffset { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); Field[] fields = Test.class.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetField.java --- a/hotspot/test/runtime/Unsafe/GetField.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetField.java Wed Jul 05 22:16:00 2017 +0200 @@ -30,14 +30,13 @@ * @run main GetField */ -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import java.lang.reflect.*; import static jdk.test.lib.Asserts.*; public class GetField { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); // Unsafe.INVALID_FIELD_OFFSET is a static final int field, // make sure getField returns the correct field Field field = Unsafe.class.getField("INVALID_FIELD_OFFSET"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetPutAddress.java --- a/hotspot/test/runtime/Unsafe/GetPutAddress.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetPutAddress.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ */ import jdk.test.lib.Platform; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutAddress { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); int addressSize = unsafe.addressSize(); // Ensure the size returned from Unsafe.addressSize is correct assertEquals(unsafe.addressSize(), Platform.is32bit() ? 4 : 8); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetPutBoolean.java --- a/hotspot/test/runtime/Unsafe/GetPutBoolean.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetPutBoolean.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutBoolean { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("b1"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetPutByte.java --- a/hotspot/test/runtime/Unsafe/GetPutByte.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetPutByte.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutByte { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("b"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetPutChar.java --- a/hotspot/test/runtime/Unsafe/GetPutChar.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetPutChar.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutChar { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("c"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetPutDouble.java --- a/hotspot/test/runtime/Unsafe/GetPutDouble.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetPutDouble.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutDouble { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("d"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetPutFloat.java --- a/hotspot/test/runtime/Unsafe/GetPutFloat.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetPutFloat.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutFloat { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("f"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetPutInt.java --- a/hotspot/test/runtime/Unsafe/GetPutInt.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetPutInt.java Wed Jul 05 22:16:00 2017 +0200 @@ -30,13 +30,12 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutInt { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("i"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetPutLong.java --- a/hotspot/test/runtime/Unsafe/GetPutLong.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetPutLong.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutLong { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("l"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetPutObject.java --- a/hotspot/test/runtime/Unsafe/GetPutObject.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetPutObject.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutObject { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); Test t = new Test(); Object o = new Object(); Field field = Test.class.getField("o"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetPutShort.java --- a/hotspot/test/runtime/Unsafe/GetPutShort.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetPutShort.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class GetPutShort { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); Test t = new Test(); Field field = Test.class.getField("s"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/GetUncompressedObject.java --- a/hotspot/test/runtime/Unsafe/GetUncompressedObject.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/GetUncompressedObject.java Wed Jul 05 22:16:00 2017 +0200 @@ -30,13 +30,12 @@ import static jdk.test.lib.Asserts.*; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; public class GetUncompressedObject { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); // Allocate some memory and fill it with non-zero values. final int size = 32; diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/NestedUnsafe.java --- a/hotspot/test/runtime/Unsafe/NestedUnsafe.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/NestedUnsafe.java Wed Jul 05 22:16:00 2017 +0200 @@ -35,7 +35,6 @@ import java.io.InputStream; import java.lang.*; import jdk.test.lib.InMemoryJavaCompiler; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; @@ -50,7 +49,7 @@ " } } "); public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); Class klass = unsafe.defineAnonymousClass(NestedUnsafe.class, klassbuf, new Object[0]); unsafe.ensureClassInitialized(klass); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/PageSize.java --- a/hotspot/test/runtime/Unsafe/PageSize.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/PageSize.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ */ import java.lang.reflect.Field; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class PageSize { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); int pageSize = unsafe.pageSize(); for (int n = 1; n != 0; n <<= 1) { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/PrimitiveHostClass.java --- a/hotspot/test/runtime/Unsafe/PrimitiveHostClass.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/PrimitiveHostClass.java Wed Jul 05 22:16:00 2017 +0200 @@ -39,16 +39,7 @@ public class PrimitiveHostClass { - static final Unsafe U; - static { - try { - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - U = (Unsafe) theUnsafe.get(null); - } catch (Exception e) { - throw new AssertionError(e); - } - } + static final Unsafe U = Unsafe.getUnsafe(); public static void testVMAnonymousClass(Class hostClass) { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/RangeCheck.java --- a/hotspot/test/runtime/Unsafe/RangeCheck.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/RangeCheck.java Wed Jul 05 22:16:00 2017 +0200 @@ -33,7 +33,6 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.Platform; -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; @@ -60,7 +59,7 @@ public static class DummyClassWithMainRangeCheck { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); unsafe.getObject(new DummyClassWithMainRangeCheck(), Short.MAX_VALUE); } } diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/Reallocate.java --- a/hotspot/test/runtime/Unsafe/Reallocate.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/Reallocate.java Wed Jul 05 22:16:00 2017 +0200 @@ -31,13 +31,12 @@ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m Reallocate */ -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class Reallocate { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); long address = unsafe.allocateMemory(1); assertNotEquals(address, 0L); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/SetMemory.java --- a/hotspot/test/runtime/Unsafe/SetMemory.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/SetMemory.java Wed Jul 05 22:16:00 2017 +0200 @@ -30,13 +30,12 @@ * @run main SetMemory */ -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class SetMemory { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); long address = unsafe.allocateMemory(1); assertNotEquals(address, 0L); unsafe.setMemory(address, 1, (byte)17); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/Unsafe/ThrowException.java --- a/hotspot/test/runtime/Unsafe/ThrowException.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/Unsafe/ThrowException.java Wed Jul 05 22:16:00 2017 +0200 @@ -30,13 +30,12 @@ * @run main ThrowException */ -import jdk.test.lib.unsafe.UnsafeHelper; import jdk.internal.misc.Unsafe; import static jdk.test.lib.Asserts.*; public class ThrowException { public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); try { unsafe.throwException(new TestException()); } catch (Throwable t) { diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/contended/Basic.java --- a/hotspot/test/runtime/contended/Basic.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/contended/Basic.java Wed Jul 05 22:16:00 2017 +0200 @@ -48,20 +48,11 @@ */ public class Basic { - private static final Unsafe U; + private static final Unsafe U = Unsafe.getUnsafe(); private static int ADDRESS_SIZE; private static int HEADER_SIZE; static { - // steal Unsafe - try { - Field unsafe = Unsafe.class.getDeclaredField("theUnsafe"); - unsafe.setAccessible(true); - U = (Unsafe) unsafe.get(null); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new IllegalStateException(e); - } - // When running with CompressedOops on 64-bit platform, the address size // reported by Unsafe is still 8, while the real reference fields are 4 bytes long. // Try to guess the reference field size with this naive trick. diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/contended/DefaultValue.java --- a/hotspot/test/runtime/contended/DefaultValue.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/contended/DefaultValue.java Wed Jul 05 22:16:00 2017 +0200 @@ -49,20 +49,11 @@ */ public class DefaultValue { - private static final Unsafe U; + private static final Unsafe U = Unsafe.getUnsafe(); private static int ADDRESS_SIZE; private static int HEADER_SIZE; static { - // steal Unsafe - try { - Field unsafe = Unsafe.class.getDeclaredField("theUnsafe"); - unsafe.setAccessible(true); - U = (Unsafe) unsafe.get(null); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new IllegalStateException(e); - } - // When running with CompressedOops on 64-bit platform, the address size // reported by Unsafe is still 8, while the real reference fields are 4 bytes long. // Try to guess the reference field size with this naive trick. diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/contended/Inheritance1.java --- a/hotspot/test/runtime/contended/Inheritance1.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/contended/Inheritance1.java Wed Jul 05 22:16:00 2017 +0200 @@ -49,20 +49,11 @@ */ public class Inheritance1 { - private static final Unsafe U; + private static final Unsafe U = Unsafe.getUnsafe(); private static int ADDRESS_SIZE; private static int HEADER_SIZE; static { - // steal Unsafe - try { - Field unsafe = Unsafe.class.getDeclaredField("theUnsafe"); - unsafe.setAccessible(true); - U = (Unsafe) unsafe.get(null); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new IllegalStateException(e); - } - // When running with CompressedOops on 64-bit platform, the address size // reported by Unsafe is still 8, while the real reference fields are 4 bytes long. // Try to guess the reference field size with this naive trick. diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/defineAnonClass/NestedUnsafe.java --- a/hotspot/test/runtime/defineAnonClass/NestedUnsafe.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/defineAnonClass/NestedUnsafe.java Wed Jul 05 22:16:00 2017 +0200 @@ -39,7 +39,6 @@ import java.lang.*; import jdk.test.lib.*; import jdk.internal.misc.Unsafe; -import jdk.test.lib.unsafe.UnsafeHelper; // Test that an anonymous class in package 'p' cannot define its own anonymous class @@ -54,7 +53,7 @@ " } } "); public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); // The anonymous class calls defineAnonymousClass creating a nested anonymous class. byte klassbuf2[] = InMemoryJavaCompiler.compile("p.TestClass2", diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/defineAnonClass/NestedUnsafe2.java --- a/hotspot/test/runtime/defineAnonClass/NestedUnsafe2.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/defineAnonClass/NestedUnsafe2.java Wed Jul 05 22:16:00 2017 +0200 @@ -39,7 +39,6 @@ import java.lang.*; import jdk.test.lib.*; import jdk.internal.misc.Unsafe; -import jdk.test.lib.unsafe.UnsafeHelper; // Test that an anonymous class that gets put in its host's package cannot define @@ -54,7 +53,7 @@ " } } "); public static void main(String args[]) throws Exception { - Unsafe unsafe = UnsafeHelper.getUnsafe(); + Unsafe unsafe = Unsafe.getUnsafe(); // The anonymous class calls defineAnonymousClass creating a nested anonymous class. byte klassbuf2[] = InMemoryJavaCompiler.compile("TestClass2", diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/jni/checked/TestCheckedJniExceptionCheck.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/jni/checked/TestCheckedJniExceptionCheck.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8164086 + * @summary regression tests for 8164086, verify correct warning from checked JNI + * @library /test/lib + * @modules java.management + * @run main/native TestCheckedJniExceptionCheck launch + */ + +import java.util.List; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestCheckedJniExceptionCheck { + + static { + System.loadLibrary("TestCheckedJniExceptionCheck"); + } + + int callableMethodInvokeCount = 0; + + static final String TEST_START = "TEST STARTED"; + static final String EXPECT_WARNING_START = "EXPECT_WARNING_START"; + static final String EXPECT_WARNING_END = "EXPECT_WARNING_END"; + + static final String JNI_CHECK_EXCEPTION = "WARNING in native method: JNI call made without checking exceptions when required to from"; + + static void printExpectWarningStart(int count) { + System.out.println(EXPECT_WARNING_START + " " + count); + } + + static void printExpectWarningEnd() { + System.out.println(EXPECT_WARNING_END); + } + + public TestCheckedJniExceptionCheck() { + initMethodIds("callableMethod", "()V", + "callableNestedMethod", "(IZ)V"); + System.out.println(TEST_START); + } + + public void test() { + testSingleCallNoCheck(); + testSingleCallCheck(); + testSingleCallNoCheckMultipleTimes(); + + testMultipleCallsNoCheck(); + testMultipleCallsCheck(); + + testNestedSingleCallsNoCheck(); + testNestedSingleCallsCheck(); + testNestedMultipleCallsNoCheck(); + testNestedMultipleCallsCheck(); + } + + public void testSingleCallNoCheck() { + System.out.println("testSingleCallNoCheck start"); + callJavaFromNative(1, false); + System.out.println("testSingleCallNoCheck end"); + } + + public void testSingleCallCheck() { + System.out.println("testSingleCallCheck start"); + callJavaFromNative(1, true); + System.out.println("testSingleCallCheck end"); + } + + public void testSingleCallNoCheckMultipleTimes() { + System.out.println("testSingleCallNoCheckMultipleTimes start"); + callJavaFromNative(1, false); + callJavaFromNative(1, false); + System.out.println("testSingleCallNoCheckMultipleTimes end"); + } + + public void testMultipleCallsNoCheck() { + System.out.println("testMultipleCallsNoCheck start"); + printExpectWarningStart(1); + callJavaFromNative(2, false); + printExpectWarningEnd(); + System.out.println("testMultipleCallsNoCheck end"); + } + + public void testMultipleCallsCheck() { + System.out.println("testMultipleCallsCheck start"); + callJavaFromNative(2, true); + System.out.println("testMultipleCallsCheck end"); + } + + public void testNestedSingleCallsNoCheck() { + System.out.println("testNestedSingleCallsNoCheck start"); + callNestedJavaFromNative(1, false); + System.out.println("testNestedSingleCallsNoCheck end"); + } + + public void testNestedSingleCallsCheck() { + System.out.println("testNestedSingleCallsCheck start"); + callNestedJavaFromNative(1, true); + System.out.println("testNestedSingleCallsCheck end"); + } + + public void testNestedMultipleCallsNoCheck() { + System.out.println("testNestedMultipleCallsNoCheck start"); + printExpectWarningStart(3); + callNestedJavaFromNative(2, false); + printExpectWarningEnd(); + System.out.println("testNestedMultipleCallsNoCheck end"); + } + + public void testNestedMultipleCallsCheck() { + System.out.println("testNestedMultipleCallsCheck start"); + callNestedJavaFromNative(2, true); + System.out.println("testNestedMultipleCallsCheck end"); + } + + public void callableMethod() { + callableMethodInvokeCount++; + } + + public void callableNestedMethod(int nofCalls, boolean withExceptionChecks) { + callJavaFromNative(nofCalls, withExceptionChecks); + } + + public native void callJavaFromNative(int nofCalls, boolean withExceptionChecks); + + public native void callNestedJavaFromNative(int nofCalls, boolean withExceptionChecks); + + private native void initMethodIds(String callableMethodName, + String callableMethodSig, + String callableNestedMethodName, + String callableNestedMethodSig); + + + // Check warnings appear where they should, with start/end statements in output... + static void checkOuputForCorrectWarnings(OutputAnalyzer oa) throws RuntimeException { + List lines = oa.asLines(); + int expectedWarnings = 0; + int warningCount = 0; + int lineNo = 0; + boolean testStartLine = false; + for (String line : lines) { + lineNo++; + if (!testStartLine) { // Skip any warning before the actual test itself + testStartLine = line.startsWith(TEST_START); + continue; + } + if (line.startsWith(JNI_CHECK_EXCEPTION)) { + if (expectedWarnings == 0) { + oa.reportDiagnosticSummary(); + throw new RuntimeException("Unexpected warning at line " + lineNo); + } + warningCount++; + if (warningCount > expectedWarnings) { + oa.reportDiagnosticSummary(); + throw new RuntimeException("Unexpected warning at line " + lineNo); + } + } + else if (line.startsWith(EXPECT_WARNING_START)) { + String countStr = line.substring(EXPECT_WARNING_START.length() + 1); + expectedWarnings = Integer.parseInt(countStr); + } + else if (line.startsWith(EXPECT_WARNING_END)) { + if (warningCount != expectedWarnings) { + oa.reportDiagnosticSummary(); + throw new RuntimeException("Missing warning at line " + lineNo); + } + warningCount = 0; + expectedWarnings = 0; + } + } + /* + System.out.println("Output looks good..."); + oa.reportDiagnosticSummary(); + */ + } + + public static void main(String[] args) throws Throwable { + if (args == null || args.length == 0) { + new TestCheckedJniExceptionCheck().test(); + return; + } + + // launch and check output + checkOuputForCorrectWarnings(ProcessTools.executeTestJvm("-Xcheck:jni", + "TestCheckedJniExceptionCheck")); + } + +} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/jni/checked/libTestCheckedJniExceptionCheck.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/jni/checked/libTestCheckedJniExceptionCheck.c Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include + +static jmethodID _callable_method_id; +static jmethodID _callable_nested_method_id; + +static void check_exceptions(JNIEnv *env) { + if ((*env)->ExceptionCheck(env)) { + (*env)->ExceptionDescribe(env); + (*env)->FatalError(env, "Unexpected Exception"); + } +} + +static jmethodID get_method_id(JNIEnv *env, jclass clz, jstring jname, jstring jsig) { + jmethodID mid; + const char *name, *sig; + + name = (*env)->GetStringUTFChars(env, jname, NULL); + check_exceptions(env); + + sig = (*env)->GetStringUTFChars(env, jsig, NULL); + check_exceptions(env); + + mid = (*env)->GetMethodID(env, clz, name, sig); + check_exceptions(env); + + (*env)->ReleaseStringUTFChars(env, jname, name); + (*env)->ReleaseStringUTFChars(env, jsig, sig); + return mid; +} + +JNIEXPORT void JNICALL +Java_TestCheckedJniExceptionCheck_initMethodIds(JNIEnv *env, + jobject obj, + jstring callable_method_name, + jstring callable_method_sig, + jstring callable_nested_method_name, + jstring callable_nested_method_sig) { + jclass clz = (*env)->GetObjectClass(env, obj); + + _callable_method_id = get_method_id(env, clz, + callable_method_name, + callable_method_sig); + + _callable_nested_method_id = get_method_id(env, clz, + callable_nested_method_name, + callable_nested_method_sig); +} + +JNIEXPORT void JNICALL +Java_TestCheckedJniExceptionCheck_callJavaFromNative(JNIEnv *env, + jobject obj, + jint nofCalls, + jboolean checkExceptions) { + int i; + for (i = 0; i < nofCalls; i++) { + (*env)->CallVoidMethod(env, obj, _callable_method_id); + if (checkExceptions == JNI_TRUE) { + check_exceptions(env); + } + } +} + +JNIEXPORT void JNICALL +Java_TestCheckedJniExceptionCheck_callNestedJavaFromNative(JNIEnv *env, + jobject obj, + jint nofCalls, + jboolean checkExceptions) { + int i; + for (i = 0; i < nofCalls; i++) { + (*env)->CallVoidMethod(env, obj, _callable_nested_method_id, nofCalls, checkExceptions); + if (checkExceptions == JNI_TRUE) { + check_exceptions(env); + } + } +} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/modules/ModuleOptionsTest.java --- a/hotspot/test/runtime/modules/ModuleOptionsTest.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/runtime/modules/ModuleOptionsTest.java Wed Jul 05 22:16:00 2017 +0200 @@ -24,8 +24,8 @@ /* * @test * @bug 8136930 - * @summary Test that the VM only recognizes the last specified --add-modules - * and --list-modules options + * @summary Test that the VM only recognizes the last specified --list-modules + * options but accumulates --add-module values. * @modules java.base/jdk.internal.misc * @library /test/lib */ @@ -38,14 +38,16 @@ public static void main(String[] args) throws Exception { - // Test that last --add-modules is the only one recognized. No exception - // should be thrown. + // Test that multiple --add-modules options are cumulative, not last one wins. + // An exception should be thrown because module i_dont_exist doesn't exist. ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "--add-modules=i_dont_exist", "--add-modules=java.base", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldHaveExitValue(0); + output.shouldContain("ResolutionException"); + output.shouldContain("i_dont_exist"); + output.shouldHaveExitValue(1); - // Test that last --limit-modules is the only one recognized. No exception + // Test that the last --limit-modules is the only one recognized. No exception // should be thrown. pb = ProcessTools.createJavaProcessBuilder( "--limit-modules=i_dont_exist", "--limit-modules=java.base", "-version"); diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/verifier/popTopTests/PopDupTop.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/verifier/popTopTests/PopDupTop.java Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8149607 + * @summary Throw VerifyError when popping a stack element of TOP + * @compile popDupSwapTests.jasm + * @run main/othervm -Xverify:all PopDupTop + */ + +public class PopDupTop { + + public static void testClass(String class_name, String msg) throws Throwable { + try { + Class newClass = Class.forName(class_name); + throw new RuntimeException("Expected VerifyError exception not thrown for " + msg); + } catch (java.lang.VerifyError e) { + if (!e.getMessage().contains("Bad type on operand stack")) { + throw new RuntimeException( + "Unexpected VerifyError message for " + msg + ": " + e.getMessage()); + } + } + } + + public static void main(String args[]) throws Throwable { + System.out.println("Regression test for bug 8149607"); + + testClass("dup_x1", "dup_x1 of long,ref"); + testClass("dup2toptop", "dup2 of top,top"); + testClass("dup2longtop", "dup2 of long,top"); + testClass("dup2_x1", "dup2_x1 long,ref,ref"); + testClass("dup2_x2", "dup2_x2 top"); + testClass("dup2_x2_long_refs", "dup2_x2 long,ref,ref,ref"); + testClass("poptop", "pop of top"); + testClass("poptoptop", "pop of top,top"); + testClass("pop2toptop", "pop2 of top,top"); + testClass("pop2longtop", "pop2 of long,top"); + testClass("swaptoptop", "swap of top,top"); + testClass("swapinttop", "swap of int,top"); + testClass("swaptopint", "swap of top,int"); + } +} diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/runtime/verifier/popTopTests/popDupSwapTests.jasm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/verifier/popTopTests/popDupSwapTests.jasm Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +// Test that VerifyError is thrown if dup2_x1 tries to replace the filler slot +// of a category 2 value. +// The stack map is long,top,null,null. The verifier should reject dup2_x1's +// (form1) attempt to turn the stack map into long,top,null,null,null,null +public class dup2_x1 version 51:0 { + public static Method run:"()V" stack 6 locals 0 { + lconst_0; + aconst_null; + aconst_null; + dup2_x1; + return; + } +} + + +public class dup2_x2 version 51:0 { + public static Method run:"()V" stack 6 locals 0 { + iconst_0; + lconst_0; + aconst_null; + + stack_frame_type full; + stack_map int, bogus, bogus, null; + locals_map; + + dup2_x2; + return; + } +} + + +// Test that VerifyError is thrown if dup2_x2 tries to replace the filler slot +// of a category 2 value. +// The stack map is long,top,null,null,null. The verifier should reject dup2_x2's +// (form 1) attempt to turn the stack map into long,top,null,null,null,top,null. +public class dup2_x2_long_refs version 51:0 { + public static Method run:"()V" stack 6 locals 0 { + lconst_0; + aconst_null; + aconst_null; + aconst_null; + dup2_x2; + return; + } +} + + +// Test that VerifyError is thrown when dup2 is used to remove the upper +// half of a category 2 type. +public class dup2longtop version 51:0 { + public static Method main:"([Ljava/lang/String;)V" stack 5 locals 1 { + lconst_0; + iconst_0; + dup2; + return; + } +} + + +// Test that VerifyError is thrown when dup2 is used to remove top +// because top may be the upper half of a category 2 type. +public class dup2toptop version 51:0 { + public static Method main:"([Ljava/lang/String;)V" stack 5 locals 1 { + // here we have {long, top, null} + // EXECUTION: we have {long, null} + lconst_0; + aconst_null; + + stack_frame_type full; + stack_map bogus, bogus, null; + locals_map bogus; + + // VERIFIER: use form1 of dup2 - {top, top, null} -> {top, top, null, top, null} + // EXECUTION: have {long, null} - no applicable form of dup2 for such type state by JVMS ch. 6 + dup2; + + return; + } +} + + +// Test that VerifyError is thrown if dup_x1 tries to replace the filler slot +// of a category 2 value. +public class dup_x1 version 51:0 { + public static Method run:"()V" stack 6 locals 0 { + lconst_0; + aconst_null; + dup_x1; + return; + } +} + + +// Test that VerifyError is thrown when pop2 is used to remove top +// because top may be the upper half of a category 2 type. +public class pop2longtop version 51:0 +{ + + public Method regular:"()V" stack 6 locals 6 + { + lconst_0; + iconst_0; + stack_frame_type full; + stack_map long, bogus; + locals_map; + pop2; + return; + } +} // end Class pop2longtop + + + +// Test that VerifyError is thrown when pop2 is used to remove top, top +// because either top may be the upper half of a category 2 type. +public class pop2toptop version 51:0 +{ + + public Method regular:"()V" stack 6 locals 6 + { + iconst_0; + iconst_0; + stack_frame_type full; + stack_map bogus, bogus; + locals_map; + pop2; + return; + } +} // end Class pop2toptop + + + +// Test that VerifyError is thrown when pop is used to remove top +// because top may be the upper half of a category 2 type. +public class poptop version 51:0 +{ + + public Method regular:"()V" stack 2 locals 1 + { + iconst_0; + stack_frame_type full; + stack_map bogus; + pop; + return; + } +} // end Class poptop + + + +// Test that VerifyError is thrown when pop is used to remove top, top +// because either top may be the upper half of a category 2 type. +public class poptoptop version 51:0 +{ + + public Method regular:"()V" stack 2 locals 1 + { + iconst_0; + iconst_0; + stack_frame_type full; + stack_map bogus, bogus; + pop; + return; + } +} // end Class poptoptop + + + +// Test that VerifyError is thrown when swap is used to swap int, top +// because top may be the lower half of a category 2 type. +public class swapinttop version 51:0 +{ + + public Method regular:"()V" stack 6 locals 6 + { + iconst_0; + iconst_0; + stack_frame_type full; + stack_map int, bogus; + locals_map; + swap; + return; + } +} // end Class swapinttop + + + +// Test that VerifyError is thrown when swap is used to swap top, int +// because top may be the upper half of a category 2 type. +public class swaptopint version 51:0 +{ + + public Method regular:"()V" stack 6 locals 6 + { + iconst_0; + iconst_0; + stack_frame_type full; + stack_map bogus, int; + locals_map; + swap; + return; + } +} // end Class swaptopint + + + +// Test that VerifyError is thrown when swap is used to swap top, top +// because either top may be the upper half of a category 2 type. +public class swaptoptop version 51:0 +{ + + public Method regular:"()V" stack 6 locals 6 + { + iconst_0; + iconst_0; + stack_frame_type full; + stack_map bogus, bogus; + locals_map; + swap; + return; + } +} // end Class swaptoptop diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/testlibrary/ctw/Makefile --- a/hotspot/test/testlibrary/ctw/Makefile Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/testlibrary/ctw/Makefile Wed Jul 05 22:16:00 2017 +0200 @@ -40,7 +40,7 @@ JAVAC = $(JDK_HOME)/bin/javac JAR = $(JDK_HOME)/bin/jar -SRC_FILES = $(shell find $(SRC_DIR) $(TESTLIBRARY_DIR)/share/classes -name '*.java') +SRC_FILES = $(shell find $(SRC_DIR) $(TESTLIBRARY_DIR)/jdk/test/lib -name '*.java') WB_SRC_FILES = $(shell find $(TESTLIBRARY_DIR)/sun/hotspot -name '*.java') MAIN_CLASS = sun.hotspot.tools.ctw.CompileTheWorld diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java --- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java Wed Jul 05 22:16:00 2017 +0200 @@ -39,7 +39,7 @@ * Concrete subclasses should implement method {@link #process()}. */ public abstract class PathHandler { - private static final Unsafe UNSAFE = jdk.test.lib.unsafe.UnsafeHelper.getUnsafe(); + private static final Unsafe UNSAFE = Unsafe.getUnsafe(); private static final AtomicLong CLASS_COUNT = new AtomicLong(0L); private static volatile boolean CLASSES_LIMIT_REACHED = false; private static final Pattern JAR_IN_DIR_PATTERN diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/testlibrary/jittester/Makefile --- a/hotspot/test/testlibrary/jittester/Makefile Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/testlibrary/jittester/Makefile Wed Jul 05 22:16:00 2017 +0200 @@ -56,7 +56,6 @@ CLASSES_DIR = $(BUILD_DIR)/classes SRC_DIR = src TEST_DIR = test -DRIVER_DIR = $(TESTBASE_DIR)/jdk/test/lib/jittester/jtreg MANIFEST = manifest.mf APPLICATION_ARGS += \ --property-file $(PROPERTY_FILE) \ @@ -118,19 +117,18 @@ @rm filelist @rm -rf $(CLASSES_DIR) -copytestlibrary: $(DRIVER_DIR) - @cp -r src/jdk/test/lib/jittester/jtreg/*.java $(DRIVER_DIR) +copytestlibrary: $(TESTBASE_DIR)/jdk/test/lib/jittester/jtreg + @cp -r src/jdk/test/lib/jittester/jtreg/*.java $(TESTBASE_DIR)/jdk/test/lib/jittester/jtreg + @cp -r $(TESTLIBRARY_SRC_DIR) $(TESTBASE_DIR)/jdk/test/ testgroup: $(TESTBASE_DIR) @echo 'jittester_all = \\' > $(TESTGROUP_FILE) @echo ' /' >> $(TESTGROUP_FILE) @echo '' >> $(TESTGROUP_FILE) - @echo 'main = \\' >> $(TESTGROUP_FILE) - @echo ' Test_0.java' >> $(TESTGROUP_FILE) testroot: $(TESTBASE_DIR) @echo 'groups=TEST.groups' > $(TESTROOT_FILE) -$(TESTBASE_DIR) $(DIST_DIR) $(DRIVER_DIR): +$(TESTBASE_DIR) $(DIST_DIR) $(TESTBASE_DIR)/jdk/test/lib/jittester/jtreg: $(shell if [ ! -d $@ ]; then mkdir -p $@; fi) diff -r 8ced0dd94a6e -r 552748e3d506 hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java --- a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Thu Sep 22 16:41:14 2016 +0000 +++ b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Wed Jul 05 22:16:00 2017 +0200 @@ -50,8 +50,9 @@ OS("isAix", "isLinux", "isOSX", "isSolaris", "isWindows"), VM_TYPE("isClient", "isServer", "isGraal", "isMinimal", "isZero", "isEmbedded"), MODE("isInt", "isMixed", "isComp"), - IGNORED("isDebugBuild", "shouldSAAttach", - "canPtraceAttachLinux", "canAttachOSX", "isTieredSupported"); + IGNORED("isDebugBuild", "isFastDebugBuild", "isSlowDebugBuild", + "shouldSAAttach", "canPtraceAttachLinux", "canAttachOSX", + "isTieredSupported"); public final List methodNames; diff -r 8ced0dd94a6e -r 552748e3d506 jaxp/.hgtags --- a/jaxp/.hgtags Thu Sep 22 16:41:14 2016 +0000 +++ b/jaxp/.hgtags Wed Jul 05 22:16:00 2017 +0200 @@ -379,3 +379,4 @@ 1c6c21d87aa459d82425e1fddc9ce8647aebde34 jdk-9+134 f695240370c77a25fed88225a392e7d530cb4d78 jdk-9+135 f1eafcb0eb7182b937bc93f214d8cabd01ec4d59 jdk-9+136 +a8d5fe567ae72b4931040e59dd4478363f9004f5 jdk-9+137 diff -r 8ced0dd94a6e -r 552748e3d506 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Wed Jul 05 22:16:00 2017 +0200 @@ -1033,12 +1033,12 @@ staxInputSource = new StaxXMLInputSource(xmlInputSource, fISCreatedByResolver); } - if (staxInputSource == null) { + if (staxInputSource == null && fUseCatalog) { if (fCatalogFeatures == null) { fCatalogFeatures = JdkXmlUtils.getCatalogFeatures(fDefer, fCatalogFile, fPrefer, fResolve); } fCatalogFile = fCatalogFeatures.get(Feature.FILES); - if (fUseCatalog && fCatalogFile != null) { + if (fCatalogFile != null) { try { if (fCatalogResolver == null) { fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures); @@ -1133,12 +1133,12 @@ xmlInputSource = fEntityResolver.resolveEntity(resourceIdentifier); } - if (xmlInputSource == null) { + if (xmlInputSource == null && fUseCatalog) { if (fCatalogFeatures == null) { fCatalogFeatures = JdkXmlUtils.getCatalogFeatures(fDefer, fCatalogFile, fPrefer, fResolve); } fCatalogFile = fCatalogFeatures.get(Feature.FILES); - if (fUseCatalog && fCatalogFile != null) { + if (fCatalogFile != null) { /* since the method can be called from various processors, both EntityResolver and URIResolver are used to attempt to find diff -r 8ced0dd94a6e -r 552748e3d506 jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java Wed Jul 05 22:16:00 2017 +0200 @@ -34,6 +34,8 @@ import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; +import com.sun.org.apache.xerces.internal.parsers.XIncludeParserConfiguration; +import com.sun.org.apache.xerces.internal.parsers.XPointerParserConfiguration; import com.sun.org.apache.xerces.internal.util.AugmentationsImpl; import com.sun.org.apache.xerces.internal.util.HTTPInputSource; import com.sun.org.apache.xerces.internal.util.IntStack; @@ -129,8 +131,6 @@ public class XIncludeHandler implements XMLComponent, XMLDocumentFilter, XMLDTDFilter { - public final static String XINCLUDE_DEFAULT_CONFIGURATION = - "com.sun.org.apache.xerces.internal.parsers.XIncludeParserConfiguration"; public final static String HTTP_ACCEPT = "Accept"; public final static String HTTP_ACCEPT_LANGUAGE = "Accept-Language"; public final static String XPOINTER = "xpointer"; @@ -1624,12 +1624,12 @@ includedSource = fEntityResolver.resolveEntity(resourceIdentifier); - if (includedSource == null) { + if (includedSource == null && fUseCatalog) { if (fCatalogFeatures == null) { fCatalogFeatures = JdkXmlUtils.getCatalogFeatures(fDefer, fCatalogFile, fPrefer, fResolve); } fCatalogFile = fCatalogFeatures.get(CatalogFeatures.Feature.FILES); - if (fUseCatalog && fCatalogFile != null) { + if (fCatalogFile != null) { /* Although URI entry is preferred for resolving XInclude, system entry is allowed as well. @@ -1690,14 +1690,11 @@ if ((xpointer != null && fXPointerChildConfig == null) || (xpointer == null && fXIncludeChildConfig == null) ) { - String parserName = XINCLUDE_DEFAULT_CONFIGURATION; - if (xpointer != null) - parserName = "com.sun.org.apache.xerces.internal.parsers.XPointerParserConfiguration"; - - fChildConfig = - (XMLParserConfiguration)ObjectFactory.newInstance( - parserName, - true); + if (xpointer == null) { + fChildConfig = new XIncludeParserConfiguration(); + } else { + fChildConfig = new XPointerParserConfiguration(); + } // use the same symbol table, error reporter, entity resolver, security manager and buffer size. if (fSymbolTable != null) fChildConfig.setProperty(SYMBOL_TABLE, fSymbolTable); diff -r 8ced0dd94a6e -r 552748e3d506 jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.java --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.java Wed Jul 05 22:16:00 2017 +0200 @@ -32,7 +32,6 @@ import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stax.StAXSource; import javax.xml.transform.stream.StreamSource; - import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Listeners; @@ -42,7 +41,7 @@ /** * @test - * @bug 8158084 8162438 8162442 8166220 + * @bug 8158084 8162438 8162442 8166220 8166398 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport * @run testng/othervm catalog.CatalogSupport @@ -51,7 +50,7 @@ * A custom resolver is used whether or not there's a Catalog; * A Catalog is used when there's no custom resolver, and the USE_CATALOG * is true (which is the case by default). - */ +*/ /** * Support Catalog: @@ -177,13 +176,13 @@ */ @DataProvider(name = "data_SAXA") public Object[][] getDataSAX() { - String[] systemIds = {"system.xsd"}; - InputSource[] returnValues = {new InputSource(new StringReader(dtd_systemResolved))}; - MyEntityHandler entityHandler = new MyEntityHandler(systemIds, returnValues, elementInSystem); + String[] systemIds = {"system.dtd"}; return new Object[][]{ {false, true, xml_catalog, xml_system, new MyHandler(elementInSystem), expectedWCatalog}, - {false, true, xml_catalog, xml_system, entityHandler, expectedWResolver}, - {true, true, xml_catalog, xml_system, entityHandler, expectedWResolver} + {false, true, xml_catalog, xml_system, getMyEntityHandler(elementInSystem, systemIds, + new InputSource(new StringReader(dtd_systemResolved))), expectedWResolver}, + {true, true, xml_catalog, xml_system, getMyEntityHandler(elementInSystem, systemIds, + new InputSource(new StringReader(dtd_systemResolved))), expectedWResolver} }; } @@ -209,7 +208,7 @@ */ @DataProvider(name = "data_DOMA") public Object[][] getDataDOM() { - String[] systemIds = {"system.xsd"}; + String[] systemIds = {"system.dtd"}; InputSource[] returnValues = {new InputSource(new StringReader(dtd_systemResolved))}; MyEntityHandler entityHandler = new MyEntityHandler(systemIds, returnValues, elementInSystem); return new Object[][]{ @@ -230,8 +229,8 @@ return new Object[][]{ {false, true, xml_catalog, xml_system, null, expectedWCatalog}, - {false, true, xml_catalog, xml_system, null, expectedWResolver}, - {true, true, xml_catalog, xml_system, null, expectedWResolver} + {false, true, xml_catalog, xml_system, new MyStaxEntityResolver(), expectedWResolver}, + {true, true, xml_catalog, xml_system, new MyStaxEntityResolver(), expectedWResolver} }; } diff -r 8ced0dd94a6e -r 552748e3d506 jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.xml --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.xml Thu Sep 22 16:41:14 2016 +0000 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupport.xml Wed Jul 05 22:16:00 2017 +0200 @@ -15,6 +15,7 @@ + diff -r 8ced0dd94a6e -r 552748e3d506 jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/CatalogSupportBase.java Wed Jul 05 22:16:00 2017 +0200 @@ -276,7 +276,7 @@ SAXParser parser = getSAXParser(setUseCatalog, useCatalog, catalog); parser.parse(xml, handler); - assertEquals(expected, handler.getResult().trim(), ""); + Assert.assertEquals(handler.getResult().trim(), expected); } /* @@ -287,8 +287,9 @@ XMLReader reader = getXMLReader(setUseCatalog, useCatalog, catalog); reader.setContentHandler(handler); + reader.setEntityResolver(handler); reader.parse(xml); - assertEquals(expected, handler.getResult().trim(), ""); + Assert.assertEquals(handler.getResult().trim(), expected); } /* @@ -300,7 +301,7 @@ parser.parse(new InputSource(new StringReader(xml)), handler); debugPrint("handler.result:" + handler.getResult()); - assertEquals(expected, handler.getResult(), "Catalog support for XInclude"); + Assert.assertEquals(handler.getResult().trim(), expected); } /* @@ -314,8 +315,7 @@ Node node = doc.getElementsByTagName(elementInSystem).item(0); String result = node.getFirstChild().getTextContent(); - - assertEquals(expected, result.trim(), "Catalog support for DOM"); + Assert.assertEquals(result.trim(), expected); } /* @@ -327,7 +327,7 @@ XMLStreamReader streamReader = getStreamReader( setUseCatalog, useCatalog, catalog, xml, resolver); String text = getText(streamReader, XMLStreamConstants.CHARACTERS); - assertEquals(expected, text.trim(), "Catalog support for StAX"); + Assert.assertEquals(text.trim(), expected); } /* @@ -340,7 +340,7 @@ XMLStreamReader streamReader = getStreamReader( setUseCatalog, useCatalog, catalog, xml, resolver); String text = getText(streamReader, XMLStreamConstants.ENTITY_REFERENCE); - assertEquals(expected, text.trim(), "Catalog support for StAX"); + Assert.assertEquals(text.trim(), expected); } /* @@ -601,9 +601,11 @@ } /** - * Returns the text of the first element found by the reader. + * Returns the accumulated text of an event type. + * * @param streamReader the XMLStreamReader - * @return the text of the first element + * @param type the type of event requested + * @return the text of the accumulated text for the request type * @throws XMLStreamException */ String getText(XMLStreamReader streamReader, int type) throws XMLStreamException { @@ -662,24 +664,6 @@ return factory; } - void assertNotNull(Object obj, String msg) { - if (obj == null) { - debugPrint("Test failed: " + msg); - } else { - debugPrint("Test passed: " + obj + " is not null"); - } - } - - void assertEquals(String expected, String actual, String msg) { - if (!expected.equals(actual)) { - debugPrint("Test failed: " + msg); - } else { - debugPrint("Test passed: "); - } - debugPrint("Expected: " + expected); - debugPrint("Actual: " + actual); - } - void fail(String msg) { System.out.println("Test failed:"); System.out.println(msg); diff -r 8ced0dd94a6e -r 552748e3d506 jaxp/test/javax/xml/jaxp/unittest/catalog/XI_simple4Catalog.xml --- a/jaxp/test/javax/xml/jaxp/unittest/catalog/XI_simple4Catalog.xml Thu Sep 22 16:41:14 2016 +0000 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/XI_simple4Catalog.xml Wed Jul 05 22:16:00 2017 +0200 @@ -9,7 +9,7 @@ - + diff -r 8ced0dd94a6e -r 552748e3d506 jaxp/test/javax/xml/jaxp/unittest/catalog/XI_test2Catalog.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/javax/xml/jaxp/unittest/catalog/XI_test2Catalog.xml Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,10 @@ + + + + + + + + + + diff -r 8ced0dd94a6e -r 552748e3d506 jdk/.hgtags --- a/jdk/.hgtags Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/.hgtags Wed Jul 05 22:16:00 2017 +0200 @@ -379,3 +379,4 @@ 803adcd526d74ae0b64948d1f8260c2dbe514779 jdk-9+134 021369229cfd0b5feb76834b2ea498f47f43c0f3 jdk-9+135 54c5931849a33a363e03fdffa141503f5cc4779d jdk-9+136 +e72df94364e3686e7d62059ce0d6b187b82da713 jdk-9+137 diff -r 8ced0dd94a6e -r 552748e3d506 jdk/make/launcher/Launcher-java.desktop.gmk --- a/jdk/make/launcher/Launcher-java.desktop.gmk Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/make/launcher/Launcher-java.desktop.gmk Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ # Hook to include the corresponding custom file, if present. $(eval $(call IncludeCustomExtension, jdk, launcher/Launcher-java.desktop.gmk)) -ifndef BUILD_HEADLESS_ONLY +ifeq ($(ENABLE_HEADLESS_ONLY), false) $(eval $(call SetupBuildLauncher, appletviewer, \ MAIN_CLASS := sun.applet.Main, \ JAVA_ARGS := --add-modules ALL-DEFAULT, \ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/make/launcher/Launcher-jdk.policytool.gmk --- a/jdk/make/launcher/Launcher-jdk.policytool.gmk Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/make/launcher/Launcher-jdk.policytool.gmk Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ include LauncherCommon.gmk -ifndef BUILD_HEADLESS_ONLY +ifeq ($(ENABLE_HEADLESS_ONLY), false) $(eval $(call SetupBuildLauncher, policytool, \ MAIN_CLASS := sun.security.tools.policytool.PolicyTool, \ LIBS_unix := $(X_LIBS), \ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/make/lib/Awt2dLibraries.gmk --- a/jdk/make/lib/Awt2dLibraries.gmk Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/make/lib/Awt2dLibraries.gmk Wed Jul 05 22:16:00 2017 +0200 @@ -280,7 +280,7 @@ ################################################################################ ifeq ($(findstring $(OPENJDK_TARGET_OS),windows macosx),) - ifndef BUILD_HEADLESS_ONLY + ifeq ($(ENABLE_HEADLESS_ONLY), false) LIBAWT_XAWT_DIRS := \ $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libawt_xawt \ @@ -511,77 +511,75 @@ ################################################################################ -ifeq ($(BUILD_HEADLESS), true) - # Mac and Windows only use the native AWT lib, do not build libawt_headless - ifeq ($(findstring $(OPENJDK_TARGET_OS), windows macosx),) +# Mac and Windows only use the native AWT lib, do not build libawt_headless +ifeq ($(findstring $(OPENJDK_TARGET_OS), windows macosx),) - LIBAWT_HEADLESS_DIRS := $(JDK_TOPDIR)/src/java.desktop/unix/native/libawt_headless/awt \ - $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/awt \ - $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/java2d/opengl \ - $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/java2d/x11 \ - $(JDK_TOPDIR)/src/java.desktop/share/native/common/java2d/opengl \ - $(JDK_TOPDIR)/src/java.desktop/share/native/common/font \ - # + LIBAWT_HEADLESS_DIRS := $(JDK_TOPDIR)/src/java.desktop/unix/native/libawt_headless/awt \ + $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/awt \ + $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/java2d/opengl \ + $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/java2d/x11 \ + $(JDK_TOPDIR)/src/java.desktop/share/native/common/java2d/opengl \ + $(JDK_TOPDIR)/src/java.desktop/share/native/common/font \ + # - LIBAWT_HEADLESS_EXCLUDES := medialib - LIBAWT_HEADLESS_CFLAGS := -I$(SUPPORT_OUTPUTDIR)/headers/java.desktop \ - $(addprefix -I, $(LIBAWT_HEADLESS_DIRS)) \ - -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d \ - -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d/loops \ - -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/awt/image/cvutils \ - -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d/pipe \ - -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/awt/image \ - -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libawt/java2d \ - -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/font \ - -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/awt/debug \ - -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/font \ - -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libsunwjdga/ \ - $(LIBJAVA_HEADER_FLAGS) \ - # + LIBAWT_HEADLESS_EXCLUDES := medialib + LIBAWT_HEADLESS_CFLAGS := -I$(SUPPORT_OUTPUTDIR)/headers/java.desktop \ + $(addprefix -I, $(LIBAWT_HEADLESS_DIRS)) \ + -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d \ + -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d/loops \ + -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/awt/image/cvutils \ + -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d/pipe \ + -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/awt/image \ + -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libawt/java2d \ + -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/font \ + -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/awt/debug \ + -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/font \ + -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libsunwjdga/ \ + $(LIBJAVA_HEADER_FLAGS) \ + # - LIBAWT_HEADLESS_REORDER := - ifeq ($(OPENJDK_TARGET_OS), solaris) - ifneq ($(OPENJDK_TARGET_CPU), x86_64) - LIBAWT_HEADLESS_REORDER := $(JDK_TOPDIR)/make/mapfiles/libawt_headless/reorder-$(OPENJDK_TARGET_CPU) - endif + LIBAWT_HEADLESS_REORDER := + ifeq ($(OPENJDK_TARGET_OS), solaris) + ifneq ($(OPENJDK_TARGET_CPU), x86_64) + LIBAWT_HEADLESS_REORDER := $(JDK_TOPDIR)/make/mapfiles/libawt_headless/reorder-$(OPENJDK_TARGET_CPU) endif + endif - $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_HEADLESS, \ - LIBRARY := awt_headless, \ - OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(LIBAWT_HEADLESS_DIRS), \ - EXCLUDES := $(LIBAWT_HEADLESS_EXCLUDES), \ - OPTIMIZATION := LOW, \ - CFLAGS := $(CFLAGS_JDKLIB) \ - -DHEADLESS=true \ - -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \ - $(CUPS_CFLAGS) \ - $(X_CFLAGS) \ - $(LIBAWT_HEADLESS_CFLAGS), \ - DISABLED_WARNINGS_xlc := 1506-356, \ - DISABLED_WARNINGS_solstudio := E_EMPTY_TRANSLATION_UNIT, \ - MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libawt_headless/mapfile-vers, \ - LDFLAGS := $(LDFLAGS_JDKLIB) \ - $(call SET_SHARED_LIBRARY_ORIGIN), \ - LDFLAGS_unix := -L$(INSTALL_LIBRARIES_HERE), \ - LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ - LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ - REORDER := $(LIBAWT_HEADLESS_REORDER), \ - LIBS_unix := -lawt -ljvm -ljava, \ - LIBS_linux := $(LIBM) $(LIBDL), \ - LIBS_solaris := $(LIBM) $(LIBDL) $(LIBCXX) -lc, \ - OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libawt_headless, \ - )) + $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_HEADLESS, \ + LIBRARY := awt_headless, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBAWT_HEADLESS_DIRS), \ + EXCLUDES := $(LIBAWT_HEADLESS_EXCLUDES), \ + OPTIMIZATION := LOW, \ + CFLAGS := $(CFLAGS_JDKLIB) \ + -DHEADLESS=true \ + -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \ + $(CUPS_CFLAGS) \ + $(X_CFLAGS) \ + $(LIBAWT_HEADLESS_CFLAGS), \ + DISABLED_WARNINGS_xlc := 1506-356, \ + DISABLED_WARNINGS_solstudio := E_EMPTY_TRANSLATION_UNIT, \ + MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libawt_headless/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_unix := -L$(INSTALL_LIBRARIES_HERE), \ + LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ + LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \ + REORDER := $(LIBAWT_HEADLESS_REORDER), \ + LIBS_unix := -lawt -ljvm -ljava, \ + LIBS_linux := $(LIBM) $(LIBDL), \ + LIBS_solaris := $(LIBM) $(LIBDL) $(LIBCXX) -lc, \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libawt_headless, \ + )) - # AIX warning explanation: - # 1506-356 : (W) Compilation unit is empty. - # This happens during the headless build + # AIX warning explanation: + # 1506-356 : (W) Compilation unit is empty. + # This happens during the headless build - $(BUILD_LIBAWT_HEADLESS): $(BUILD_LIBAWT) + $(BUILD_LIBAWT_HEADLESS): $(BUILD_LIBAWT) - TARGETS += $(BUILD_LIBAWT_HEADLESS) + TARGETS += $(BUILD_LIBAWT_HEADLESS) - endif endif ################################################################################ @@ -780,7 +778,7 @@ ifneq ($(OPENJDK_TARGET_OS), solaris) JAWT_LIBS += -lawt endif - ifndef BUILD_HEADLESS_ONLY + ifeq ($(ENABLE_HEADLESS_ONLY), false) JAWT_LIBS += -lawt_xawt else JAWT_LIBS += -lawt_headless @@ -809,7 +807,7 @@ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjawt, \ )) - ifndef BUILD_HEADLESS_ONLY + ifeq ($(ENABLE_HEADLESS_ONLY), false) $(BUILD_LIBJAWT): $(BUILD_LIBAWT_XAWT) else $(BUILD_LIBJAWT): $(INSTALL_LIBRARIES_HERE)/$(LIBRARY_PREFIX)awt_headless$(SHARED_LIBRARY_SUFFIX) @@ -825,7 +823,7 @@ ################################################################################ -ifndef BUILD_HEADLESS_ONLY +ifeq ($(ENABLE_HEADLESS_ONLY), false) LIBSPLASHSCREEN_DIRS := \ $(JDK_TOPDIR)/src/java.desktop/share/native/libjavajpeg \ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/aix/native/libjli/java_md_aix.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/aix/native/libjli/java_md_aix.c Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016 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. + */ +#include +#include + +#include "java_md_aix.h" + +static unsigned char dladdr_buffer[0x4000]; + +static int fill_dll_info(void) { + return loadquery(L_GETINFO, dladdr_buffer, sizeof(dladdr_buffer)); +} + +static int dladdr_dont_reload(void *addr, Dl_info *info) { + const struct ld_info *p = (struct ld_info *)dladdr_buffer; + memset((void *)info, 0, sizeof(Dl_info)); + for (;;) { + if (addr >= p->ldinfo_textorg && + addr < (((char*)p->ldinfo_textorg) + p->ldinfo_textsize)) + { + info->dli_fname = p->ldinfo_filename; + return 1; + } + if (!p->ldinfo_next) { + break; + } + p = (struct ld_info *)(((char *)p) + p->ldinfo_next); + } + return 0; +} + +int dladdr(void *addr, Dl_info *info) { + static int loaded = 0; + int rc = 0; + void *addr0; + if (!addr) { + return rc; + } + if (!loaded) { + if (fill_dll_info() == -1) + return rc; + loaded = 1; + } + + // first try with addr on cached data + rc = dladdr_dont_reload(addr, info); + + // addr could be an AIX function descriptor, so try dereferenced version + if (rc == 0) { + addr0 = *((void **)addr); + rc = dladdr_dont_reload(addr0, info); + } + + // if we had no success until now, maybe loadquery info is outdated. + // refresh and retry + if (rc == 0) { + if (fill_dll_info() == -1) + return rc; + rc = dladdr_dont_reload(addr, info); + if (rc == 0) { + rc = dladdr_dont_reload(addr0, info); + } + } + return rc; +} diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/aix/native/libjli/java_md_aix.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/aix/native/libjli/java_md_aix.h Wed Jul 05 22:16:00 2017 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 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. + */ + +#ifndef JAVA_MD_AIX_H +#define JAVA_MD_AIX_H + +/* + * Very limited AIX port of dladdr() for libjli.so. + * + * We try to mimick dladdr(3) on Linux (see http://linux.die.net/man/3/dladdr) + * dladdr(3) is not POSIX but a GNU extension, and is not available on AIX. + * + * We only support Dl_info.dli_fname here as this is the only thing that is + * used of it by libjli.so. A more comprehensive port of dladdr can be found + * in the hotspot implementation which is not available at this place, though. + */ + +typedef struct { + const char *dli_fname; /* file path of loaded library */ + void *dli_fbase; /* unsupported */ + const char *dli_sname; /* unsupported */ + void *dli_saddr; /* unsupported */ +} Dl_info; + +int dladdr(void *addr, Dl_info *info); + +#endif /* JAVA_MD_AIX_H */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java --- a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java Wed Jul 05 22:16:00 2017 +0200 @@ -71,6 +71,7 @@ // These flags must match the values maintained in the VM @Native private static final int DEFAULT_MODE = 0x0; @Native private static final int FILL_CLASS_REFS_ONLY = 0x2; + @Native private static final int GET_CALLER_CLASS = 0x4; @Native private static final int SHOW_HIDDEN_FRAMES = 0x20; // LambdaForms are hidden by the VM @Native private static final int FILL_LIVE_STACK_FRAMES = 0x100; /* @@ -614,9 +615,7 @@ private Class caller; CallerClassFinder(StackWalker walker) { - super(walker, FILL_CLASS_REFS_ONLY); - assert (mode & FILL_CLASS_REFS_ONLY) == FILL_CLASS_REFS_ONLY - : "mode should contain FILL_CLASS_REFS_ONLY"; + super(walker, FILL_CLASS_REFS_ONLY|GET_CALLER_CLASS); } final class ClassBuffer extends FrameBuffer> { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Jul 05 22:16:00 2017 +0200 @@ -869,5 +869,4 @@ static SpeciesData speciesData_LLL() { return checkCache(3, "LLL"); } static SpeciesData speciesData_LLLL() { return checkCache(4, "LLLL"); } static SpeciesData speciesData_LLLLL() { return checkCache(5, "LLLLL"); } - static SpeciesData speciesData_LLLLLL() { return checkCache(6, "LLLLLL"); } } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Wed Jul 05 22:16:00 2017 +0200 @@ -39,14 +39,14 @@ import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.Arrays; -import java.util.ArrayList; import java.util.HashMap; import java.util.stream.Stream; -import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.BasicType; import static java.lang.invoke.LambdaForm.BasicType.*; -import static java.lang.invoke.LambdaForm.Kind.*; +import static java.lang.invoke.LambdaForm.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.*; @@ -65,6 +65,9 @@ private static final String OBJ = "java/lang/Object"; private static final String OBJARY = "[Ljava/lang/Object;"; + private static final String LOOP_CLAUSES = MHI + "$LoopClauses"; + private static final String MHARY2 = "[[L" + MH + ";"; + private static final String LF_SIG = "L" + LF + ";"; private static final String LFN_SIG = "L" + LFN + ";"; private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";"; @@ -1319,38 +1322,43 @@ * The pattern looks like (Cf. MethodHandleImpl.loop): *
    {@code
          * // a0: BMH
    -     * // a1: inits, a2: steps, a3: preds, a4: finis
    -     * // a5: box, a6: unbox
    -     * // a7 (and following): arguments
    -     * loop=Lambda(a0:L,a1:L,a2:L,a3:L,a4:L,a5:L,a6:L,a7:L)=>{
    -     *   t8:L=MethodHandle.invokeBasic(a5:L,a7:L);                  // box the arguments into an Object[]
    -     *   t9:L=MethodHandleImpl.loop(bt:L,a1:L,a2:L,a3:L,a4:L,t8:L); // call the loop executor (with supplied types in bt)
    -     *   t10:L=MethodHandle.invokeBasic(a6:L,t9:L);t10:L}           // unbox the result; return the result
    +     * // a1: LoopClauses (containing an array of arrays: inits, steps, preds, finis)
    +     * // a2: box, a3: unbox
    +     * // a4 (and following): arguments
    +     * loop=Lambda(a0:L,a1:L,a2:L,a3:L,a4:L)=>{
    +     *   t5:L=MethodHandle.invokeBasic(a2:L,a4:L);          // box the arguments into an Object[]
    +     *   t6:L=MethodHandleImpl.loop(bt:L,a1:L,t5:L);        // call the loop executor (with supplied types in bt)
    +     *   t7:L=MethodHandle.invokeBasic(a3:L,t6:L);t7:L}     // unbox the result; return the result
          * }
    *

    * It is compiled into bytecode equivalent to the code seen in {@link MethodHandleImpl#loop(BasicType[], - * MethodHandle[], MethodHandle[], MethodHandle[], MethodHandle[], Object...)}, with the difference that no arrays + * MethodHandleImpl.LoopClauses, Object...)}, with the difference that no arrays * will be used for local state storage. Instead, the local state will be mapped to actual stack slots. *

    * Bytecode generation applies an unrolling scheme to enable better bytecode generation regarding local state type * handling. The generated bytecode will have the following form ({@code void} types are ignored for convenience). * Assume there are {@code C} clauses in the loop. *

    {@code
    -     * INIT: (INIT_SEQ for clause 1)
    -     *       ...
    -     *       (INIT_SEQ for clause C)
    -     * LOOP: (LOOP_SEQ for clause 1)
    -     *       ...
    -     *       (LOOP_SEQ for clause C)
    -     *       GOTO LOOP
    -     * DONE: ...
    +     * PREINIT: ALOAD_1
    +     *          CHECKCAST LoopClauses
    +     *          GETFIELD LoopClauses.clauses
    +     *          ASTORE clauseDataIndex          // place the clauses 2-dimensional array on the stack
    +     * INIT:    (INIT_SEQ for clause 1)
    +     *          ...
    +     *          (INIT_SEQ for clause C)
    +     * LOOP:    (LOOP_SEQ for clause 1)
    +     *          ...
    +     *          (LOOP_SEQ for clause C)
    +     *          GOTO LOOP
    +     * DONE:    ...
          * }
    *

    * The {@code INIT_SEQ_x} sequence for clause {@code x} (with {@code x} ranging from {@code 0} to {@code C-1}) has * the following shape. Assume slot {@code vx} is used to hold the state for clause {@code x}. *

    {@code
    -     * INIT_SEQ_x:  ALOAD inits
    -     *              CHECKCAST MethodHandle[]
    +     * INIT_SEQ_x:  ALOAD clauseDataIndex
    +     *              ICONST_0
    +     *              AALOAD      // load the inits array
          *              ICONST x
          *              AALOAD      // load the init handle for clause x
          *              load args
    @@ -1361,24 +1369,27 @@
          * The {@code LOOP_SEQ_x} sequence for clause {@code x} (with {@code x} ranging from {@code 0} to {@code C-1}) has
          * the following shape. Again, assume slot {@code vx} is used to hold the state for clause {@code x}.
          * 
    {@code
    -     * LOOP_SEQ_x:  ALOAD steps
    -     *              CHECKCAST MethodHandle[]
    +     * LOOP_SEQ_x:  ALOAD clauseDataIndex
    +     *              ICONST_1
    +     *              AALOAD              // load the steps array
          *              ICONST x
          *              AALOAD              // load the step handle for clause x
          *              load locals
          *              load args
          *              INVOKEVIRTUAL MethodHandle.invokeBasic
          *              store vx
    -     *              ALOAD preds
    -     *              CHECKCAST MethodHandle[]
    +     *              ALOAD clauseDataIndex
    +     *              ICONST_2
    +     *              AALOAD              // load the preds array
          *              ICONST x
          *              AALOAD              // load the pred handle for clause x
          *              load locals
          *              load args
          *              INVOKEVIRTUAL MethodHandle.invokeBasic
          *              IFNE LOOP_SEQ_x+1   // predicate returned false -> jump to next clause
    -     *              ALOAD finis
    -     *              CHECKCAST MethodHandle[]
    +     *              ALOAD clauseDataIndex
    +     *              ICONST_3
    +     *              AALOAD              // load the finis array
          *              ICONST x
          *              AALOAD              // load the fini handle for clause x
          *              load locals
    @@ -1397,8 +1408,12 @@
             BasicType[] loopClauseTypes = (BasicType[]) invoker.arguments[0];
             Class[] loopLocalStateTypes = Stream.of(loopClauseTypes).
                     filter(bt -> bt != BasicType.V_TYPE).map(BasicType::basicTypeClass).toArray(Class[]::new);
    +        Class[] localTypes = new Class[loopLocalStateTypes.length + 1];
    +        localTypes[0] = MethodHandleImpl.LoopClauses.class;
    +        System.arraycopy(loopLocalStateTypes, 0, localTypes, 1, loopLocalStateTypes.length);
     
    -        final int firstLoopStateIndex = extendLocalsMap(loopLocalStateTypes);
    +        final int clauseDataIndex = extendLocalsMap(localTypes);
    +        final int firstLoopStateIndex = clauseDataIndex + 1;
     
             Class returnType = result.function.resolvedHandle().type().returnType();
             MethodType loopType = args.function.resolvedHandle().type()
    @@ -1420,10 +1435,16 @@
             Label lDone = new Label();
             Label lNext;
     
    +        // PREINIT:
    +        emitPushArgument(MethodHandleImpl.LoopClauses.class, invoker.arguments[1]);
    +        mv.visitFieldInsn(Opcodes.GETFIELD, LOOP_CLAUSES, "clauses", MHARY2);
    +        emitAstoreInsn(clauseDataIndex);
    +
             // INIT:
             for (int c = 0, state = 0; c < nClauses; ++c) {
                 MethodType cInitType = loopType.changeReturnType(loopClauseTypes[c].basicTypeClass());
    -            emitLoopHandleInvoke(invoker, inits, c, args, false, cInitType, loopLocalStateTypes, firstLoopStateIndex);
    +            emitLoopHandleInvoke(invoker, inits, c, args, false, cInitType, loopLocalStateTypes, clauseDataIndex,
    +                    firstLoopStateIndex);
                 if (cInitType.returnType() != void.class) {
                     emitStoreInsn(BasicType.basicType(cInitType.returnType()), firstLoopStateIndex + state);
                     ++state;
    @@ -1440,18 +1461,21 @@
                 boolean isVoid = stepType.returnType() == void.class;
     
                 // invoke loop step
    -            emitLoopHandleInvoke(invoker, steps, c, args, true, stepType, loopLocalStateTypes, firstLoopStateIndex);
    +            emitLoopHandleInvoke(invoker, steps, c, args, true, stepType, loopLocalStateTypes, clauseDataIndex,
    +                    firstLoopStateIndex);
                 if (!isVoid) {
                     emitStoreInsn(BasicType.basicType(stepType.returnType()), firstLoopStateIndex + state);
                     ++state;
                 }
     
                 // invoke loop predicate
    -            emitLoopHandleInvoke(invoker, preds, c, args, true, predType, loopLocalStateTypes, firstLoopStateIndex);
    +            emitLoopHandleInvoke(invoker, preds, c, args, true, predType, loopLocalStateTypes, clauseDataIndex,
    +                    firstLoopStateIndex);
                 mv.visitJumpInsn(Opcodes.IFNE, lNext);
     
                 // invoke fini
    -            emitLoopHandleInvoke(invoker, finis, c, args, true, finiType, loopLocalStateTypes, firstLoopStateIndex);
    +            emitLoopHandleInvoke(invoker, finis, c, args, true, finiType, loopLocalStateTypes, clauseDataIndex,
    +                    firstLoopStateIndex);
                 mv.visitJumpInsn(Opcodes.GOTO, lDone);
     
                 // this is the beginning of the next loop clause
    @@ -1483,9 +1507,10 @@
         }
     
         private void emitLoopHandleInvoke(Name holder, int handles, int clause, Name args, boolean pushLocalState,
    -                                      MethodType type, Class[] loopLocalStateTypes, int firstLoopStateSlot) {
    +                                      MethodType type, Class[] loopLocalStateTypes, int clauseDataSlot,
    +                                      int firstLoopStateSlot) {
             // load handle for clause
    -        emitPushArgument(holder, handles);
    +        emitPushClauseArray(clauseDataSlot, handles);
             emitIconstInsn(clause);
             mv.visitInsn(Opcodes.AALOAD);
             // load loop state (preceding the other arguments)
    @@ -1499,6 +1524,12 @@
             mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.toMethodDescriptorString(), false);
         }
     
    +    private void emitPushClauseArray(int clauseDataSlot, int which) {
    +        emitAloadInsn(clauseDataSlot);
    +        emitIconstInsn(which - 1);
    +        mv.visitInsn(Opcodes.AALOAD);
    +    }
    +
         private void emitZero(BasicType type) {
             switch (type) {
                 case I_TYPE: mv.visitInsn(Opcodes.ICONST_0); break;
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java
    --- a/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/src/java.base/share/classes/java/lang/invoke/LambdaForm.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -41,7 +41,6 @@
     import static java.lang.invoke.LambdaForm.BasicType.*;
     import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
     import static java.lang.invoke.MethodHandleStatics.*;
    -import java.util.Objects;
     
     /**
      * The symbolic, non-executable form of a method handle's invocation semantics.
    @@ -732,9 +731,9 @@
         boolean isLoop(int pos) {
             // loop idiom:
             //   t_{n}:L=MethodHandle.invokeBasic(...)
    -        //   t_{n+1}:L=MethodHandleImpl.loop(types, *, *, *, *, t_{n})
    +        //   t_{n+1}:L=MethodHandleImpl.loop(types, *, t_{n})
             //   t_{n+2}:?=MethodHandle.invokeBasic(*, t_{n+1})
    -        return isMatchingIdiom(pos, "loop", 5);
    +        return isMatchingIdiom(pos, "loop", 2);
         }
     
         /*
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
    --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1689,8 +1689,7 @@
                 NF_tryFinally = new NamedFunction(MethodHandleImpl.class
                         .getDeclaredMethod("tryFinally", MethodHandle.class, MethodHandle.class, Object[].class));
                 NF_loop = new NamedFunction(MethodHandleImpl.class
    -                    .getDeclaredMethod("loop", BasicType[].class, MethodHandle[].class, MethodHandle[].class,
    -                            MethodHandle[].class, MethodHandle[].class, Object[].class));
    +                    .getDeclaredMethod("loop", BasicType[].class, LoopClauses.class, Object[].class));
                 NF_throwException = new NamedFunction(MethodHandleImpl.class
                         .getDeclaredMethod("throwException", Throwable.class));
                 NF_profileBoolean = new NamedFunction(MethodHandleImpl.class
    @@ -1794,12 +1793,13 @@
             MethodHandle collectArgs = varargsArray(type.parameterCount()).asType(varargsType);
             MethodHandle unboxResult = unboxResultHandle(tloop);
     
    -        BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLLL();
    +        LoopClauses clauseData =
    +                new LoopClauses(new MethodHandle[][]{toArray(init), toArray(step), toArray(pred), toArray(fini)});
    +        BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL();
             BoundMethodHandle mh;
             try {
    -            mh = (BoundMethodHandle) data.constructor().invokeBasic(type, form, (Object) toArray(init),
    -                    (Object) toArray(step), (Object) toArray(pred), (Object) toArray(fini), (Object) collectArgs,
    -                    (Object) unboxResult);
    +            mh = (BoundMethodHandle) data.constructor().invokeBasic(type, form, (Object) clauseData,
    +                    (Object) collectArgs, (Object) unboxResult);
             } catch (Throwable ex) {
                 throw uncaughtException(ex);
             }
    @@ -1818,23 +1818,20 @@
          * {@code t12}):
          * 
    {@code
          *  loop=Lambda(a0:L,a1:L)=>{
    -     *    t2:L=BoundMethodHandle$Species_L6.argL0(a0:L);             // array of init method handles
    -     *    t3:L=BoundMethodHandle$Species_L6.argL1(a0:L);             // array of step method handles
    -     *    t4:L=BoundMethodHandle$Species_L6.argL2(a0:L);             // array of pred method handles
    -     *    t5:L=BoundMethodHandle$Species_L6.argL3(a0:L);             // array of fini method handles
    -     *    t6:L=BoundMethodHandle$Species_L6.argL4(a0:L);             // helper handle to box the arguments into an Object[]
    -     *    t7:L=BoundMethodHandle$Species_L6.argL5(a0:L);             // helper handle to unbox the result
    -     *    t8:L=MethodHandle.invokeBasic(t6:L,a1:L);                  // box the arguments into an Object[]
    -     *    t9:L=MethodHandleImpl.loop(null,t2:L,t3:L,t4:L,t5:L,t6:L); // call the loop executor
    -     *    t10:L=MethodHandle.invokeBasic(t7:L,t9:L);t10:L}           // unbox the result; return the result
    +     *    t2:L=BoundMethodHandle$Species_L3.argL0(a0:L);    // LoopClauses holding init, step, pred, fini handles
    +     *    t3:L=BoundMethodHandle$Species_L3.argL1(a0:L);    // helper handle to box the arguments into an Object[]
    +     *    t4:L=BoundMethodHandle$Species_L3.argL2(a0:L);    // helper handle to unbox the result
    +     *    t5:L=MethodHandle.invokeBasic(t3:L,a1:L);         // box the arguments into an Object[]
    +     *    t6:L=MethodHandleImpl.loop(null,t2:L,t3:L);       // call the loop executor
    +     *    t7:L=MethodHandle.invokeBasic(t4:L,t6:L);t7:L}    // unbox the result; return the result
          * }
    *

    - * {@code argL0} through {@code argL3} are the arrays of init, step, pred, and fini method handles. - * {@code argL4} and {@code argL5} are auxiliary method handles: {@code argL2} boxes arguments and wraps them into - * {@code Object[]} ({@code ValueConversions.array()}), and {@code argL3} unboxes the result if necessary + * {@code argL0} is a LoopClauses instance holding, in a 2-dimensional array, the init, step, pred, and fini method + * handles. {@code argL1} and {@code argL2} are auxiliary method handles: {@code argL1} boxes arguments and wraps + * them into {@code Object[]} ({@code ValueConversions.array()}), and {@code argL2} unboxes the result if necessary * ({@code ValueConversions.unbox()}). *

    - * Having {@code t6} and {@code t7} passed in via a BMH and not hardcoded in the lambda form allows to share lambda + * Having {@code t3} and {@code t4} passed in via a BMH and not hardcoded in the lambda form allows to share lambda * forms among loop combinators with the same basic type. *

    * The above template is instantiated by using the {@link LambdaFormEditor} to replace the {@code null} argument to @@ -1845,15 +1842,12 @@ private static LambdaForm makeLoopForm(MethodType basicType, BasicType[] localVarTypes) { MethodType lambdaType = basicType.invokerType(); - final int THIS_MH = 0; // the BMH_LLLLLL + final int THIS_MH = 0; // the BMH_LLL final int ARG_BASE = 1; // start of incoming arguments final int ARG_LIMIT = ARG_BASE + basicType.parameterCount(); int nameCursor = ARG_LIMIT; - final int GET_INITS = nameCursor++; - final int GET_STEPS = nameCursor++; - final int GET_PREDS = nameCursor++; - final int GET_FINIS = nameCursor++; + final int GET_CLAUSE_DATA = nameCursor++; final int GET_COLLECT_ARGS = nameCursor++; final int GET_UNBOX_RESULT = nameCursor++; final int BOXED_ARGS = nameCursor++; @@ -1864,14 +1858,11 @@ if (lform == null) { Name[] names = arguments(nameCursor - ARG_LIMIT, lambdaType); - BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLLL(); + BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLL(); names[THIS_MH] = names[THIS_MH].withConstraint(data); - names[GET_INITS] = new Name(data.getterFunction(0), names[THIS_MH]); - names[GET_STEPS] = new Name(data.getterFunction(1), names[THIS_MH]); - names[GET_PREDS] = new Name(data.getterFunction(2), names[THIS_MH]); - names[GET_FINIS] = new Name(data.getterFunction(3), names[THIS_MH]); - names[GET_COLLECT_ARGS] = new Name(data.getterFunction(4), names[THIS_MH]); - names[GET_UNBOX_RESULT] = new Name(data.getterFunction(5), names[THIS_MH]); + names[GET_CLAUSE_DATA] = new Name(data.getterFunction(0), names[THIS_MH]); + names[GET_COLLECT_ARGS] = new Name(data.getterFunction(1), names[THIS_MH]); + names[GET_UNBOX_RESULT] = new Name(data.getterFunction(2), names[THIS_MH]); // t_{i}:L=MethodHandle.invokeBasic(collectArgs:L,a1:L,...); MethodType collectArgsType = basicType.changeReturnType(Object.class); @@ -1881,10 +1872,10 @@ System.arraycopy(names, ARG_BASE, args, 1, ARG_LIMIT - ARG_BASE); names[BOXED_ARGS] = new Name(makeIntrinsic(invokeBasic, Intrinsic.LOOP), args); - // t_{i+1}:L=MethodHandleImpl.loop(localTypes:L,inits:L,steps:L,preds:L,finis:L,t_{i}:L); + // t_{i+1}:L=MethodHandleImpl.loop(localTypes:L,clauses:L,t_{i}:L); Object[] lArgs = new Object[]{null, // placeholder for BasicType[] localTypes - will be added by LambdaFormEditor - names[GET_INITS], names[GET_STEPS], names[GET_PREDS], names[GET_FINIS], names[BOXED_ARGS]}; + names[GET_CLAUSE_DATA], names[BOXED_ARGS]}; names[LOOP] = new Name(NF_loop, lArgs); // t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L); @@ -1900,22 +1891,52 @@ return lform.editor().noteLoopLocalTypesForm(BOXED_ARGS, localVarTypes); } + static class LoopClauses { + @Stable final MethodHandle[][] clauses; + LoopClauses(MethodHandle[][] clauses) { + assert clauses.length == 4; + this.clauses = clauses; + } + @Override + public String toString() { + StringBuffer sb = new StringBuffer("LoopClauses -- "); + for (int i = 0; i < 4; ++i) { + if (i > 0) { + sb.append(" "); + } + sb.append('<').append(i).append(">: "); + MethodHandle[] hs = clauses[i]; + for (int j = 0; j < hs.length; ++j) { + if (j > 0) { + sb.append(" "); + } + sb.append('*').append(j).append(": ").append(hs[j]).append('\n'); + } + } + sb.append(" --\n"); + return sb.toString(); + } + } /** * Intrinsified during LambdaForm compilation * (see {@link InvokerBytecodeGenerator#emitLoop(int)}). */ @LambdaForm.Hidden - static Object loop(BasicType[] localTypes, MethodHandle[] init, MethodHandle[] step, MethodHandle[] pred, - MethodHandle[] fini, Object... av) throws Throwable { + static Object loop(BasicType[] localTypes, LoopClauses clauseData, Object... av) throws Throwable { + final MethodHandle[] init = clauseData.clauses[0]; + final MethodHandle[] step = clauseData.clauses[1]; + final MethodHandle[] pred = clauseData.clauses[2]; + final MethodHandle[] fini = clauseData.clauses[3]; int varSize = (int) Stream.of(init).filter(h -> h.type().returnType() != void.class).count(); int nArgs = init[0].type().parameterCount(); Object[] varsAndArgs = new Object[varSize + nArgs]; for (int i = 0, v = 0; i < init.length; ++i) { - if (init[i].type().returnType() == void.class) { - init[i].asFixedArity().invokeWithArguments(av); + MethodHandle ih = init[i]; + if (ih.type().returnType() == void.class) { + ih.invokeWithArguments(av); } else { - varsAndArgs[v++] = init[i].asFixedArity().invokeWithArguments(av); + varsAndArgs[v++] = ih.invokeWithArguments(av); } } System.arraycopy(av, 0, varsAndArgs, varSize, nArgs); @@ -1926,12 +1947,12 @@ MethodHandle s = step[i]; MethodHandle f = fini[i]; if (s.type().returnType() == void.class) { - s.asFixedArity().invokeWithArguments(varsAndArgs); + s.invokeWithArguments(varsAndArgs); } else { - varsAndArgs[v++] = s.asFixedArity().invokeWithArguments(varsAndArgs); + varsAndArgs[v++] = s.invokeWithArguments(varsAndArgs); } - if (!(boolean) p.asFixedArity().invokeWithArguments(varsAndArgs)) { - return f.asFixedArity().invokeWithArguments(varsAndArgs); + if (!(boolean) p.invokeWithArguments(varsAndArgs)) { + return f.invokeWithArguments(varsAndArgs); } } } @@ -2122,14 +2143,13 @@ Throwable t = null; Object r = null; try { - // Use asFixedArity() to avoid unnecessary boxing of last argument for VarargsCollector case. - r = target.asFixedArity().invokeWithArguments(av); + r = target.invokeWithArguments(av); } catch (Throwable thrown) { t = thrown; throw t; } finally { Object[] args = target.type().returnType() == void.class ? prepend(av, t) : prepend(av, t, r); - r = cleanup.asFixedArity().invokeWithArguments(args); + r = cleanup.invokeWithArguments(args); } return r; } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Wed Jul 05 22:16:00 2017 +0200 @@ -4368,10 +4368,11 @@ } // Step 4: fill in missing parameter types. - List finit = fillParameterTypes(init, commonSuffix); - List fstep = fillParameterTypes(step, commonParameterSequence); - List fpred = fillParameterTypes(pred, commonParameterSequence); - List ffini = fillParameterTypes(fini, commonParameterSequence); + // Also convert all handles to fixed-arity handles. + List finit = fixArities(fillParameterTypes(init, commonSuffix)); + List fstep = fixArities(fillParameterTypes(step, commonParameterSequence)); + List fpred = fixArities(fillParameterTypes(pred, commonParameterSequence)); + List ffini = fixArities(fillParameterTypes(fini, commonParameterSequence)); assert finit.stream().map(MethodHandle::type).map(MethodType::parameterList). allMatch(pl -> pl.equals(commonSuffix)); @@ -4389,6 +4390,10 @@ }).collect(Collectors.toList()); } + private static List fixArities(List hs) { + return hs.stream().map(MethodHandle::asFixedArity).collect(Collectors.toList()); + } + /** * Constructs a {@code while} loop from an initializer, a body, and a predicate. This is a convenience wrapper for * the {@linkplain #loop(MethodHandle[][]) generic loop combinator}. @@ -4887,7 +4892,8 @@ // target parameter list. cleanup = dropArgumentsToMatch(cleanup, (rtype == void.class ? 1 : 2), targetParamTypes, 0); - return MethodHandleImpl.makeTryFinally(target, cleanup, rtype, targetParamTypes); + // Use asFixedArity() to avoid unnecessary boxing of last argument for VarargsCollector case. + return MethodHandleImpl.makeTryFinally(target.asFixedArity(), cleanup.asFixedArity(), rtype, targetParamTypes); } /** diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/module/ModuleInfo.java --- a/jdk/src/java.base/share/classes/java/lang/module/ModuleInfo.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleInfo.java Wed Jul 05 22:16:00 2017 +0200 @@ -664,7 +664,7 @@ try { bb.get(b, off, len); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -681,7 +681,7 @@ int ch = bb.get(); return (ch != 0); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -690,7 +690,7 @@ try { return bb.get(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -699,7 +699,7 @@ try { return ((int) bb.get()) & 0xff; } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -708,7 +708,7 @@ try { return bb.getShort(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -717,7 +717,7 @@ try { return ((int) bb.getShort()) & 0xffff; } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -726,7 +726,7 @@ try { return bb.getChar(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -735,7 +735,7 @@ try { return bb.getInt(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -744,7 +744,7 @@ try { return bb.getLong(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -753,7 +753,7 @@ try { return bb.getFloat(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } @@ -762,7 +762,7 @@ try { return bb.getDouble(); } catch (BufferUnderflowException e) { - throw new EOFException(); + throw new EOFException(e.getMessage()); } } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java --- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Wed Jul 05 22:16:00 2017 +0200 @@ -597,10 +597,10 @@ private final Module module; ProxyBuilder(ClassLoader loader, List> interfaces) { if (!VM.isModuleSystemInited()) { - throw new InternalError("Proxy is not supported until module system is fully initialzed"); + throw new InternalError("Proxy is not supported until module system is fully initialized"); } if (interfaces.size() > 65535) { - throw new IllegalArgumentException("interface limit exceeded"); + throw new IllegalArgumentException("interface limit exceeded: " + interfaces.size()); } Set> refTypes = referencedTypes(loader, interfaces); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Wed Jul 05 22:16:00 2017 +0200 @@ -2559,6 +2559,13 @@ * exceptionally with a CompletionException with this exception as * cause. * + *

    Unless overridden by a subclass, a new non-minimal + * CompletableFuture with all methods available can be obtained from + * a minimal CompletionStage via {@link #toCompletableFuture()}. + * For example, completion of a minimal stage can be awaited by + * + *

     {@code minimalStage.toCompletableFuture().join(); }
    + * * @return the new CompletionStage * @since 9 */ @@ -2853,6 +2860,16 @@ @Override public CompletableFuture completeOnTimeout (T value, long timeout, TimeUnit unit) { throw new UnsupportedOperationException(); } + @Override public CompletableFuture toCompletableFuture() { + Object r; + if ((r = result) != null) + return new CompletableFuture(encodeRelay(r)); + else { + CompletableFuture d = new CompletableFuture<>(); + unipush(new UniRelay(d, this)); + return d; + } + } } // VarHandle mechanics diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Wed Jul 05 22:16:00 2017 +0200 @@ -1191,7 +1191,7 @@ * Default idle timeout value (in milliseconds) for the thread * triggering quiescence to park waiting for new work */ - private static final long DEFAULT_KEEPALIVE = 60000L; + private static final long DEFAULT_KEEPALIVE = 60_000L; /** * Undershoot tolerance for idle timeouts @@ -2303,7 +2303,6 @@ throw new NullPointerException(); long ms = Math.max(unit.toMillis(keepAliveTime), TIMEOUT_SLOP); - String prefix = "ForkJoinPool-" + nextPoolId() + "-worker-"; int corep = Math.min(Math.max(corePoolSize, parallelism), MAX_CAP); long c = ((((long)(-corep) << TC_SHIFT) & TC_MASK) | (((long)(-parallelism) << RC_SHIFT) & RC_MASK)); @@ -2315,8 +2314,8 @@ n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1; // power of two, including space for submission queues + this.workerNamePrefix = "ForkJoinPool-" + nextPoolId() + "-worker-"; this.workQueues = new WorkQueue[n]; - this.workerNamePrefix = prefix; this.factory = factory; this.ueh = handler; this.saturate = saturate; @@ -2327,11 +2326,19 @@ checkPermission(); } + private Object newInstanceFromSystemProperty(String property) + throws ReflectiveOperationException { + String className = System.getProperty(property); + return (className == null) + ? null + : ClassLoader.getSystemClassLoader().loadClass(className) + .getConstructor().newInstance(); + } + /** * Constructor for common pool using parameters possibly * overridden by system properties */ - @SuppressWarnings("deprecation") // Class.newInstance private ForkJoinPool(byte forCommonPoolOnly) { int parallelism = -1; ForkJoinWorkerThreadFactory fac = null; @@ -2339,18 +2346,12 @@ try { // ignore exceptions in accessing/parsing properties String pp = System.getProperty ("java.util.concurrent.ForkJoinPool.common.parallelism"); - String fp = System.getProperty - ("java.util.concurrent.ForkJoinPool.common.threadFactory"); - String hp = System.getProperty - ("java.util.concurrent.ForkJoinPool.common.exceptionHandler"); if (pp != null) parallelism = Integer.parseInt(pp); - if (fp != null) - fac = ((ForkJoinWorkerThreadFactory)ClassLoader. - getSystemClassLoader().loadClass(fp).newInstance()); - if (hp != null) - handler = ((UncaughtExceptionHandler)ClassLoader. - getSystemClassLoader().loadClass(hp).newInstance()); + fac = (ForkJoinWorkerThreadFactory) newInstanceFromSystemProperty( + "java.util.concurrent.ForkJoinPool.common.threadFactory"); + handler = (UncaughtExceptionHandler) newInstanceFromSystemProperty( + "java.util.concurrent.ForkJoinPool.common.exceptionHandler"); } catch (Exception ignore) { } @@ -2373,8 +2374,8 @@ n |= n >>> 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1; + this.workerNamePrefix = "ForkJoinPool.commonPool-worker-"; this.workQueues = new WorkQueue[n]; - this.workerNamePrefix = "ForkJoinPool.commonPool-worker-"; this.factory = fac; this.ueh = handler; this.saturate = null; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java Wed Jul 05 22:16:00 2017 +0200 @@ -35,6 +35,9 @@ package java.util.concurrent.atomic; +import static java.lang.Double.doubleToRawLongBits; +import static java.lang.Double.longBitsToDouble; + import java.io.Serializable; import java.util.function.DoubleBinaryOperator; @@ -91,7 +94,7 @@ public DoubleAccumulator(DoubleBinaryOperator accumulatorFunction, double identity) { this.function = accumulatorFunction; - base = this.identity = Double.doubleToRawLongBits(identity); + base = this.identity = doubleToRawLongBits(identity); } /** @@ -101,18 +104,19 @@ */ public void accumulate(double x) { Cell[] as; long b, v, r; int m; Cell a; - if ((as = cells) != null || - (r = Double.doubleToRawLongBits - (function.applyAsDouble - (Double.longBitsToDouble(b = base), x))) != b && !casBase(b, r)) { + if ((as = cells) != null + || ((r = doubleToRawLongBits + (function.applyAsDouble(longBitsToDouble(b = base), x))) != b + && !casBase(b, r))) { boolean uncontended = true; - if (as == null || (m = as.length - 1) < 0 || - (a = as[getProbe() & m]) == null || - !(uncontended = - (r = Double.doubleToRawLongBits - (function.applyAsDouble - (Double.longBitsToDouble(v = a.value), x))) == v || - a.cas(v, r))) + if (as == null + || (m = as.length - 1) < 0 + || (a = as[getProbe() & m]) == null + || !(uncontended = + ((r = doubleToRawLongBits + (function.applyAsDouble + (longBitsToDouble(v = a.value), x))) == v) + || a.cas(v, r))) doubleAccumulate(x, function, uncontended); } } @@ -128,12 +132,12 @@ */ public double get() { Cell[] as = cells; - double result = Double.longBitsToDouble(base); + double result = longBitsToDouble(base); if (as != null) { for (Cell a : as) if (a != null) result = function.applyAsDouble - (result, Double.longBitsToDouble(a.value)); + (result, longBitsToDouble(a.value)); } return result; } @@ -168,12 +172,12 @@ */ public double getThenReset() { Cell[] as = cells; - double result = Double.longBitsToDouble(base); + double result = longBitsToDouble(base); base = identity; if (as != null) { for (Cell a : as) { if (a != null) { - double v = Double.longBitsToDouble(a.value); + double v = longBitsToDouble(a.value); a.reset(identity); result = function.applyAsDouble(result, v); } @@ -267,9 +271,9 @@ * held by this proxy */ private Object readResolve() { - double d = Double.longBitsToDouble(identity); + double d = longBitsToDouble(identity); DoubleAccumulator a = new DoubleAccumulator(function, d); - a.base = Double.doubleToRawLongBits(value); + a.base = doubleToRawLongBits(value); return a; } } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java --- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java Wed Jul 05 22:16:00 2017 +0200 @@ -103,14 +103,16 @@ */ public void accumulate(long x) { Cell[] as; long b, v, r; int m; Cell a; - if ((as = cells) != null || - (r = function.applyAsLong(b = base, x)) != b && !casBase(b, r)) { + if ((as = cells) != null + || ((r = function.applyAsLong(b = base, x)) != b + && !casBase(b, r))) { boolean uncontended = true; - if (as == null || (m = as.length - 1) < 0 || - (a = as[getProbe() & m]) == null || - !(uncontended = - (r = function.applyAsLong(v = a.value, x)) == v || - a.cas(v, r))) + if (as == null + || (m = as.length - 1) < 0 + || (a = as[getProbe() & m]) == null + || !(uncontended = + (r = function.applyAsLong(v = a.value, x)) == v + || a.cas(v, r))) longAccumulate(x, function, uncontended); } } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java Wed Jul 05 22:16:00 2017 +0200 @@ -186,7 +186,9 @@ if (result.getMajorVersion() != ImageHeader.MAJOR_VERSION || result.getMinorVersion() != ImageHeader.MINOR_VERSION) { - throw new IOException("The image file \"" + name + "\" is not the correct version"); + throw new IOException("The image file \"" + name + "\" is not " + + "the correct version. Major: " + result.getMajorVersion() + + ". Minor: " + result.getMinorVersion()); } return result; @@ -318,11 +320,11 @@ private ByteBuffer readBuffer(long offset, long size) { if (offset < 0 || Integer.MAX_VALUE <= offset) { - throw new IndexOutOfBoundsException("offset"); + throw new IndexOutOfBoundsException("Bad offset: " + offset); } if (size < 0 || Integer.MAX_VALUE <= size) { - throw new IndexOutOfBoundsException("size"); + throw new IndexOutOfBoundsException("Bad size: " + size); } if (MAP_ALL) { @@ -382,11 +384,13 @@ long uncompressedSize = loc.getUncompressedSize(); if (compressedSize < 0 || Integer.MAX_VALUE < compressedSize) { - throw new IndexOutOfBoundsException("Compressed size"); + throw new IndexOutOfBoundsException( + "Bad compressed size: " + compressedSize); } if (uncompressedSize < 0 || Integer.MAX_VALUE < uncompressedSize) { - throw new IndexOutOfBoundsException("Uncompressed size"); + throw new IndexOutOfBoundsException( + "Bad uncompressed size: " + uncompressedSize); } if (compressedSize == 0) { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jimage/ImageHeader.java --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageHeader.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageHeader.java Wed Jul 05 22:16:00 2017 +0200 @@ -79,7 +79,8 @@ Objects.requireNonNull(buffer); if (buffer.capacity() != HEADER_SLOTS) { - throw new InternalError("jimage header not the correct size"); + throw new InternalError( + "jimage header not the correct size: " + buffer.capacity()); } int magic = buffer.get(0); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageLocation.java Wed Jul 05 22:16:00 2017 +0200 @@ -81,7 +81,8 @@ } if (kind < ATTRIBUTE_END || ATTRIBUTE_COUNT <= kind) { - throw new InternalError("Invalid jimage attribute kind"); + throw new InternalError( + "Invalid jimage attribute kind: " + kind); } int length = attributeLength(data); @@ -91,7 +92,7 @@ value <<= 8; if (!bytes.hasRemaining()) { - throw new InternalError("\"Missing jimage attribute datad"); + throw new InternalError("Missing jimage attribute data"); } value |= bytes.get() & 0xFF; @@ -134,7 +135,8 @@ long getAttribute(int kind) { if (kind < ATTRIBUTE_END || ATTRIBUTE_COUNT <= kind) { - throw new InternalError("Invalid jimage attribute kind"); + throw new InternalError( + "Invalid jimage attribute kind: " + kind); } return attributes[kind]; @@ -142,7 +144,8 @@ String getAttributeString(int kind) { if (kind < ATTRIBUTE_END || ATTRIBUTE_COUNT <= kind) { - throw new InternalError("Invalid jimage attribute kind"); + throw new InternalError( + "Invalid jimage attribute kind: " + kind); } return getStrings().get((int)attributes[kind]); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStream.java --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStream.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStream.java Wed Jul 05 22:16:00 2017 +0200 @@ -82,7 +82,7 @@ public void ensure(int needs) { if (needs < 0) { - throw new IndexOutOfBoundsException("needs"); + throw new IndexOutOfBoundsException("Bad value: " + needs); } if (needs > buffer.remaining()) { @@ -106,7 +106,7 @@ public void skip(int n) { if (n < 0) { - throw new IndexOutOfBoundsException("n"); + throw new IndexOutOfBoundsException("skip value = " + n); } buffer.position(buffer.position() + n); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java --- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageStringsReader.java Wed Jul 05 22:16:00 2017 +0200 @@ -151,7 +151,7 @@ try { charsFromMUTF8(chars, bytes, offset, count); } catch (UTFDataFormatException ex) { - throw new InternalError("Attempt to convert non modified UTF-8 byte sequence"); + throw new InternalError("Attempt to convert non modified UTF-8 byte sequence", ex); } return new String(chars); @@ -199,7 +199,8 @@ ch = buffer.get(); if ((ch & 0xC0) != 0x80) { - throw new InternalError("Bad continuation in modified UTF-8 byte sequence"); + throw new InternalError("Bad continuation in " + + "modified UTF-8 byte sequence: " + ch); } uch = ((uch & ~mask) << 6) | (ch & 0x3F); @@ -208,7 +209,8 @@ } if ((uch & 0xFFFF) != uch) { - throw new InternalError("UTF-32 char in modified UTF-8 byte sequence"); + throw new InternalError("UTF-32 char in modified UTF-8 " + + "byte sequence: " + uch); } chars[j++] = (char)uch; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java --- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtFileSystem.java Wed Jul 05 22:16:00 2017 +0200 @@ -183,7 +183,7 @@ public PathMatcher getPathMatcher(String syntaxAndInput) { int pos = syntaxAndInput.indexOf(':'); if (pos <= 0 || pos == syntaxAndInput.length()) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException("pos is " + pos); } String syntax = syntaxAndInput.substring(0, pos); String input = syntaxAndInput.substring(pos + 1); @@ -285,7 +285,8 @@ for (OpenOption option : options) { Objects.requireNonNull(option); if (!(option instanceof StandardOpenOption)) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException( + "option class: " + option.getClass()); } } if (options.contains(StandardOpenOption.WRITE) || diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java --- a/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/jrtfs/JrtPath.java Wed Jul 05 22:16:00 2017 +0200 @@ -122,7 +122,8 @@ public final JrtPath getName(int index) { initOffsets(); if (index < 0 || index >= offsets.length) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException("index: " + + index + ", offsets length: " + offsets.length); } int begin = offsets[index]; int end; @@ -139,7 +140,9 @@ initOffsets(); if (beginIndex < 0 || endIndex > offsets.length || beginIndex >= endIndex) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException( + "beginIndex: " + beginIndex + ", endIndex: " + endIndex + + ", offsets length: " + offsets.length); } // starting/ending offsets int begin = offsets[beginIndex]; @@ -211,7 +214,8 @@ return o; } if (jrtfs != o.jrtfs || isAbsolute() != o.isAbsolute()) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException( + "Incorrect filesystem or path: " + other); } final String tp = this.path; final String op = o.path; @@ -366,7 +370,8 @@ private JrtPath checkPath(Path path) { Objects.requireNonNull(path); if (!(path instanceof JrtPath)) - throw new ProviderMismatchException(); + throw new ProviderMismatchException("path class: " + + path.getClass()); return (JrtPath) path; } @@ -459,7 +464,7 @@ } if (c == '\u0000') { throw new InvalidPathException(path, - "Path: nul character not allowed"); + "Path: NUL character not allowed"); } to.append(c); prevC = c; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java --- a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Wed Jul 05 22:16:00 2017 +0200 @@ -1603,11 +1603,50 @@ return weakCompareAndSwapShort(o, offset, c2s(expected), c2s(x)); } + /** + * The JVM converts integral values to boolean values using two + * different conventions, byte testing against zero and truncation + * to least-significant bit. + * + *

    The JNI documents specify that, at least for returning + * values from native methods, a Java boolean value is converted + * to the value-set 0..1 by first truncating to a byte (0..255 or + * maybe -128..127) and then testing against zero. Thus, Java + * booleans in non-Java data structures are by convention + * represented as 8-bit containers containing either zero (for + * false) or any non-zero value (for true). + * + *

    Java booleans in the heap are also stored in bytes, but are + * strongly normalized to the value-set 0..1 (i.e., they are + * truncated to the least-significant bit). + * + *

    The main reason for having different conventions for + * conversion is performance: Truncation to the least-significant + * bit can be usually implemented with fewer (machine) + * instructions than byte testing against zero. + * + *

    A number of Unsafe methods load boolean values from the heap + * as bytes. Unsafe converts those values according to the JNI + * rules (i.e, using the "testing against zero" convention). The + * method {@code byte2bool} implements that conversion. + * + * @param b the byte to be converted to boolean + * @return the result of the conversion + */ @ForceInline private boolean byte2bool(byte b) { - return b > 0; - } - + return b != 0; + } + + /** + * Convert a boolean value to a byte. The return value is strongly + * normalized to the value-set 0..1 (i.e., the value is truncated + * to the least-significant bit). See {@link #byte2bool(byte)} for + * more details on conversion conventions. + * + * @param b the boolean to be converted to byte (and then normalized) + * @return the result of the conversion + */ @ForceInline private byte bool2byte(boolean b) { return b ? (byte)1 : (byte)0; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/misc/VM.java --- a/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java Wed Jul 05 22:16:00 2017 +0200 @@ -50,7 +50,7 @@ public static void initLevel(int value) { synchronized (lock) { if (value <= initLevel || value > SYSTEM_BOOTED) - throw new InternalError(); + throw new InternalError("Bad level: " + value); initLevel = value; lock.notifyAll(); } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java --- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Wed Jul 05 22:16:00 2017 +0200 @@ -153,27 +153,24 @@ boolean addAllDefaultModules = false; boolean addAllSystemModules = false; boolean addAllApplicationModules = false; - String propValue = getAndRemoveProperty("jdk.module.addmods"); - if (propValue != null) { - for (String mod: propValue.split(",")) { - switch (mod) { - case ALL_DEFAULT: - addAllDefaultModules = true; - break; - case ALL_SYSTEM: - addAllSystemModules = true; - break; - case ALL_MODULE_PATH: - addAllApplicationModules = true; - break; - default : - roots.add(mod); - } + for (String mod: getExtraAddModules()) { + switch (mod) { + case ALL_DEFAULT: + addAllDefaultModules = true; + break; + case ALL_SYSTEM: + addAllSystemModules = true; + break; + case ALL_MODULE_PATH: + addAllApplicationModules = true; + break; + default : + roots.add(mod); } } // --limit-modules - propValue = getAndRemoveProperty("jdk.module.limitmods"); + String propValue = getAndRemoveProperty("jdk.module.limitmods"); if (propValue != null) { Set mods = new HashSet<>(); for (String mod: propValue.split(",")) { @@ -392,6 +389,32 @@ } } + /** + * Returns the set of module names specified via --add-modules options + * on the command line + */ + private static Set getExtraAddModules() { + String prefix = "jdk.module.addmods."; + int index = 0; + + // the system property is removed after decoding + String value = getAndRemoveProperty(prefix + index); + if (value == null) { + return Collections.emptySet(); + } + + Set modules = new HashSet<>(); + while (value != null) { + for (String s : value.split(",")) { + if (s.length() > 0) modules.add(s); + } + + index++; + value = getAndRemoveProperty(prefix + index); + } + + return modules; + } /** * Process the --add-reads options to add any additional read edges that @@ -514,7 +537,7 @@ // value is (,)* if (map.containsKey(key)) - fail(key + " specified more than once"); + fail(key + " specified more than once"); Set values = new HashSet<>(); map.put(key, values); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/module-info.java --- a/jdk/src/java.base/share/classes/module-info.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/module-info.java Wed Jul 05 22:16:00 2017 +0200 @@ -166,6 +166,7 @@ jdk.charsets, jdk.compiler, jdk.jartool, + jdk.jdeps, jdk.jlink, jdk.net, jdk.scripting.nashorn, @@ -189,7 +190,8 @@ jdk.unsupported, jdk.vm.ci; exports jdk.internal.util.jar to - jdk.jartool; + jdk.jartool, + jdk.jdeps; exports jdk.internal.vm to java.management, jdk.jvmstat; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java --- a/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Wed Jul 05 22:16:00 2017 +0200 @@ -328,8 +328,6 @@ public SocketAddress receive(ByteBuffer dst) throws IOException { if (dst.isReadOnly()) throw new IllegalArgumentException("Read-only buffer"); - if (dst == null) - throw new NullPointerException(); synchronized (readLock) { ensureOpen(); // Socket was not bound before attempting receive @@ -716,8 +714,6 @@ @Override public DatagramChannel connect(SocketAddress sa) throws IOException { - int localPort = 0; - synchronized(readLock) { synchronized(writeLock) { synchronized (stateLock) { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java --- a/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java Wed Jul 05 22:16:00 2017 +0200 @@ -616,8 +616,6 @@ } public boolean connect(SocketAddress sa) throws IOException { - int localPort = 0; - synchronized (readLock) { synchronized (writeLock) { ensureOpenAndUnconnected(); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java --- a/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/provider/SeedGenerator.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -344,7 +344,8 @@ try { BogusThread bt = new BogusThread(); Thread t = new Thread - (seedGroup, bt, "SeedGenerator Thread", 0, false); + (seedGroup, bt, "SeedGenerator Thread", 0, + false); t.start(); } catch (Exception e) { throw new InternalError("internal error: " + @@ -357,7 +358,8 @@ long startTime = System.nanoTime(); while (System.nanoTime() - startTime < 250000000) { synchronized(this){}; - latch++; + // Mask the sign bit and keep latch non-negative + latch = (latch + 1) & 0x1FFFFFFF; } // Translate the value using the permutation, and xor @@ -431,7 +433,7 @@ // data and using it to mix the trivial permutation. // It should be evenly distributed. The specific values // are not crucial to the security of this class. - private static byte[] rndTab = { + private static final byte[] rndTab = { 56, 30, -107, -6, -86, 25, -83, 75, -12, -64, 5, -128, 78, 21, 16, 32, 70, -81, 37, -51, -43, -46, -108, 87, 29, 17, -55, 22, -11, -111, diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/share/native/include/jvm.h --- a/jdk/src/java.base/share/native/include/jvm.h Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/share/native/include/jvm.h Wed Jul 05 22:16:00 2017 +0200 @@ -179,6 +179,7 @@ */ enum { JVM_STACKWALK_FILL_CLASS_REFS_ONLY = 0x2, + JVM_STACKWALK_GET_CALLER_CLASS = 0x04, JVM_STACKWALK_SHOW_HIDDEN_FRAMES = 0x20, JVM_STACKWALK_FILL_LIVE_STACK_FRAMES = 0x100 }; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c --- a/jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/unix/native/libjava/ProcessImpl_md.c Wed Jul 05 22:16:00 2017 +0200 @@ -152,8 +152,8 @@ #ifdef __solaris__ /* These really are the Solaris defaults! */ return (geteuid() == 0 || getuid() == 0) ? - "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" : - "/usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin:"; + "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" : + "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:"; #else return ":/bin:/usr/bin"; /* glibc */ #endif diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/unix/native/libjli/java_md.h --- a/jdk/src/java.base/unix/native/libjli/java_md.h Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/unix/native/libjli/java_md.h Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,12 +35,12 @@ #include "manifest_info.h" #include "jli_util.h" -#define PATH_SEPARATOR ':' -#define FILESEP "/" -#define FILE_SEPARATOR '/' +#define PATH_SEPARATOR ':' +#define FILESEP "/" +#define FILE_SEPARATOR '/' #define IS_FILE_SEPARATOR(c) ((c) == '/') #ifndef MAXNAMELEN -#define MAXNAMELEN PATH_MAX +#define MAXNAMELEN PATH_MAX #endif #ifdef _LP64 @@ -59,10 +59,13 @@ static jboolean GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative); +#if defined(_AIX) +#include "java_md_aix.h" +#endif + #ifdef MACOSX #include "java_md_macosx.h" #else /* !MACOSX */ #include "java_md_solinux.h" #endif /* MACOSX */ - #endif /* JAVA_MD_H */ diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c --- a/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.base/windows/native/libnet/Inet4AddressImpl.c Wed Jul 05 22:16:00 2017 +0200 @@ -33,6 +33,7 @@ #include #include #include +#include #include "java_net_InetAddress.h" #include "java_net_Inet4AddressImpl.h" @@ -442,7 +443,15 @@ DWORD ReplySize = 0; jboolean ret = JNI_FALSE; - ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData); + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366051%28v=vs.85%29.aspx + ReplySize = sizeof(ICMP_ECHO_REPLY) // The buffer should be large enough + // to hold at least one ICMP_ECHO_REPLY + // structure + + sizeof(SendData) // plus RequestSize bytes of data. + + 8; // This buffer should also be large enough + // to also hold 8 more bytes of data + // (the size of an ICMP error message) + ReplyBuffer = (VOID*) malloc(ReplySize); if (ReplyBuffer == NULL) { IcmpCloseHandle(hIcmpFile); @@ -478,10 +487,47 @@ (timeout < 1000) ? 1000 : timeout); // DWORD Timeout } - if (dwRetVal != 0) { + if (dwRetVal == 0) { // if the call failed + TCHAR *buf; + DWORD err = WSAGetLastError(); + switch (err) { + case ERROR_NO_NETWORK: + case ERROR_NETWORK_UNREACHABLE: + case ERROR_HOST_UNREACHABLE: + case ERROR_PROTOCOL_UNREACHABLE: + case ERROR_PORT_UNREACHABLE: + case ERROR_REQUEST_ABORTED: + case ERROR_INCORRECT_ADDRESS: + case ERROR_HOST_DOWN: + case ERROR_INVALID_COMPUTERNAME: + case ERROR_INVALID_NETNAME: + case WSAEHOSTUNREACH: /* Host Unreachable */ + case WSAENETUNREACH: /* Network Unreachable */ + case WSAENETDOWN: /* Network is down */ + case WSAEPFNOSUPPORT: /* Protocol Family unsupported */ + case IP_REQ_TIMED_OUT: + break; + default: + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&buf, 0, NULL); + NET_ThrowNew(env, err, buf); + LocalFree(buf); + break; + } + } else { PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer; - if ((int)pEchoReply->RoundTripTime <= timeout) + + // This is to take into account the undocumented minimum + // timeout mentioned in the IcmpSendEcho call above. + // We perform an extra check to make sure that our + // roundtrip time was less than our desired timeout + // for cases where that timeout is < 1000ms. + if (pEchoReply->Status == IP_SUCCESS + && (int)pEchoReply->RoundTripTime <= timeout) + { ret = JNI_TRUE; + } } free(ReplyBuffer); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.desktop/share/classes/com/sun/beans/finder/ConstructorFinder.java --- a/jdk/src/java.desktop/share/classes/com/sun/beans/finder/ConstructorFinder.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/com/sun/beans/finder/ConstructorFinder.java Wed Jul 05 22:16:00 2017 +0200 @@ -67,19 +67,22 @@ */ public static Constructor findConstructor(Class type, Class...args) throws NoSuchMethodException { if (type.isPrimitive()) { - throw new NoSuchMethodException("Primitive wrapper does not contain constructors"); + throw new NoSuchMethodException("Primitive wrapper does not contain constructors: " + + type.getName()); } if (type.isInterface()) { - throw new NoSuchMethodException("Interface does not contain constructors"); + throw new NoSuchMethodException("Interface does not contain constructors: " + + type.getName()); } if (!FinderUtils.isExported(type)) { - throw new NoSuchMethodException("Class is not accessible"); + throw new NoSuchMethodException("Class is not accessible: " + type.getName()); } if (Modifier.isAbstract(type.getModifiers())) { - throw new NoSuchMethodException("Abstract class cannot be instantiated"); + throw new NoSuchMethodException("Abstract class cannot be instantiated: " + + type.getName()); } if (!Modifier.isPublic(type.getModifiers()) || !isPackageAccessible(type)) { - throw new NoSuchMethodException("Class is not accessible"); + throw new NoSuchMethodException("Class is not accessible: " + type.getName()); } PrimitiveWrapperMap.replacePrimitivesWithWrappers(args); Signature signature = new Signature(type, args); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.desktop/share/classes/javax/imageio/ImageReader.java --- a/jdk/src/java.desktop/share/classes/javax/imageio/ImageReader.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageReader.java Wed Jul 05 22:16:00 2017 +0200 @@ -2461,16 +2461,16 @@ try { bundle = ResourceBundle.getBundle(baseName, locale, this.getClass().getModule()); } catch (MissingResourceException mre) { - throw new IllegalArgumentException("Bundle not found!"); + throw new IllegalArgumentException("Bundle not found!", mre); } String warning = null; try { warning = bundle.getString(keyword); } catch (ClassCastException cce) { - throw new IllegalArgumentException("Resource is not a String!"); + throw new IllegalArgumentException("Resource is not a String!", cce); } catch (MissingResourceException mre) { - throw new IllegalArgumentException("Resource is missing!"); + throw new IllegalArgumentException("Resource is missing!", mre); } listener.warningOccurred(this, warning); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.desktop/share/classes/javax/imageio/ImageWriter.java --- a/jdk/src/java.desktop/share/classes/javax/imageio/ImageWriter.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageWriter.java Wed Jul 05 22:16:00 2017 +0200 @@ -1963,16 +1963,16 @@ try { bundle = ResourceBundle.getBundle(baseName, locale, this.getClass().getModule()); } catch (MissingResourceException mre) { - throw new IllegalArgumentException("Bundle not found!"); + throw new IllegalArgumentException("Bundle not found!", mre); } String warning = null; try { warning = bundle.getString(keyword); } catch (ClassCastException cce) { - throw new IllegalArgumentException("Resource is not a String!"); + throw new IllegalArgumentException("Resource is not a String!", cce); } catch (MissingResourceException mre) { - throw new IllegalArgumentException("Resource is missing!"); + throw new IllegalArgumentException("Resource is missing!", mre); } listener.warningOccurred(this, imageIndex, warning); diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c --- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Wed Jul 05 22:16:00 2017 +0200 @@ -442,7 +442,7 @@ #ifndef __linux__ /* SOLARIS */ if (xrenderLibHandle == NULL) { - xrenderLibHandle = dlopen("/usr/sfw/lib/libXrender.so.1", + xrenderLibHandle = dlopen("/usr/lib/libXrender.so.1", RTLD_LAZY | RTLD_GLOBAL); } #endif diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/java.desktop/unix/native/libjawt/jawt.c --- a/jdk/src/java.desktop/unix/native/libjawt/jawt.c Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/java.desktop/unix/native/libjawt/jawt.c Wed Jul 05 22:16:00 2017 +0200 @@ -39,6 +39,10 @@ */ JNIEXPORT jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt) { +#if defined(HEADLESS) + /* there are no AWT libs available at all */ + return JNI_FALSE; +#else if (awt == NULL) { return JNI_FALSE; } @@ -64,4 +68,5 @@ } return JNI_TRUE; +#endif } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,8 +68,8 @@ // master secret as a P11Key private P11Key p11Key; - // version, e.g. 0x0301 - private int version; + // whether SSLv3 is supported + private final boolean supportSSLv3; P11TlsKeyMaterialGenerator(Token token, String algorithm, long mechanism) throws PKCS11Exception { @@ -77,6 +77,11 @@ this.token = token; this.algorithm = algorithm; this.mechanism = mechanism; + + // Given the current lookup order specified in SunPKCS11.java, + // if CKM_SSL3_KEY_AND_MAC_DERIVE is not used to construct this object, + // it means that this mech is disabled or unsupported. + this.supportSSLv3 = (mechanism == CKM_SSL3_KEY_AND_MAC_DERIVE); } protected void engineInit(SecureRandom random) { @@ -89,20 +94,26 @@ if (params instanceof TlsKeyMaterialParameterSpec == false) { throw new InvalidAlgorithmParameterException(MSG); } - this.spec = (TlsKeyMaterialParameterSpec)params; + + TlsKeyMaterialParameterSpec spec = (TlsKeyMaterialParameterSpec)params; + int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); + + if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) || + (version > 0x0302)) { + throw new InvalidAlgorithmParameterException + ("Only" + (supportSSLv3? " SSL 3.0,": "") + + " TLS 1.0, and TLS 1.1 are supported (0x" + + Integer.toHexString(version) + ")"); + } try { p11Key = P11SecretKeyFactory.convertKey (token, spec.getMasterSecret(), "TlsMasterSecret"); } catch (InvalidKeyException e) { throw new InvalidAlgorithmParameterException("init() failed", e); } - version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); - if ((version < 0x0300) && (version > 0x0302)) { - throw new InvalidAlgorithmParameterException - ("Only SSL 3.0, TLS 1.0, and TLS 1.1 are supported"); - } - // we assume the token supports both the CKM_SSL3_* and the CKM_TLS_* - // mechanisms + this.spec = spec; + this.mechanism = (version == 0x0300)? + CKM_SSL3_KEY_AND_MAC_DERIVE : CKM_TLS_KEY_AND_MAC_DERIVE; } protected void engineInit(int keysize, SecureRandom random) { @@ -115,8 +126,6 @@ throw new IllegalStateException ("TlsKeyMaterialGenerator must be initialized"); } - mechanism = (version == 0x0300) ? CKM_SSL3_KEY_AND_MAC_DERIVE - : CKM_TLS_KEY_AND_MAC_DERIVE; int macBits = spec.getMacKeyLength() << 3; int ivBits = spec.getIvLength() << 3; diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,10 @@ private TlsMasterSecretParameterSpec spec; private P11Key p11Key; - int version; + CK_VERSION ckVersion; + + // whether SSLv3 is supported + private final boolean supportSSLv3; P11TlsMasterSecretGenerator(Token token, String algorithm, long mechanism) throws PKCS11Exception { @@ -69,6 +72,11 @@ this.token = token; this.algorithm = algorithm; this.mechanism = mechanism; + + // Given the current lookup order specified in SunPKCS11.java, if + // CKM_SSL3_MASTER_KEY_DERIVE is not used to construct this object, + // it means that this mech is disabled or unsupported. + supportSSLv3 = (mechanism == CKM_SSL3_MASTER_KEY_DERIVE); } protected void engineInit(SecureRandom random) { @@ -81,7 +89,17 @@ if (params instanceof TlsMasterSecretParameterSpec == false) { throw new InvalidAlgorithmParameterException(MSG); } - this.spec = (TlsMasterSecretParameterSpec)params; + + TlsMasterSecretParameterSpec spec = (TlsMasterSecretParameterSpec)params; + int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); + if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) || + (version > 0x0302)) { + throw new InvalidAlgorithmParameterException + ("Only" + (supportSSLv3? " SSL 3.0,": "") + + " TLS 1.0, and TLS 1.1 are supported (0x" + + Integer.toHexString(version) + ")"); + } + SecretKey key = spec.getPremasterSecret(); // algorithm should be either TlsRsaPremasterSecret or TlsPremasterSecret, // but we omit the check @@ -90,25 +108,7 @@ } catch (InvalidKeyException e) { throw new InvalidAlgorithmParameterException("init() failed", e); } - version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); - if ((version < 0x0300) || (version > 0x0302)) { - throw new InvalidAlgorithmParameterException - ("Only SSL 3.0, TLS 1.0, and TLS 1.1 supported"); - } - // We assume the token supports the required mechanism. If it does not, - // generateKey() will fail and the failover should take care of us. - } - - protected void engineInit(int keysize, SecureRandom random) { - throw new InvalidParameterException(MSG); - } - - protected SecretKey engineGenerateKey() { - if (spec == null) { - throw new IllegalStateException - ("TlsMasterSecretGenerator must be initialized"); - } - CK_VERSION ckVersion; + this.spec = spec; if (p11Key.getAlgorithm().equals("TlsRsaPremasterSecret")) { mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE : CKM_TLS_MASTER_KEY_DERIVE; @@ -124,6 +124,17 @@ : CKM_TLS_MASTER_KEY_DERIVE_DH; ckVersion = null; } + } + + protected void engineInit(int keysize, SecureRandom random) { + throw new InvalidParameterException(MSG); + } + + protected SecretKey engineGenerateKey() { + if (spec == null) { + throw new IllegalStateException + ("TlsMasterSecretGenerator must be initialized"); + } byte[] clientRandom = spec.getClientRandom(); byte[] serverRandom = spec.getServerRandom(); CK_SSL3_RANDOM_DATA random = @@ -139,13 +150,12 @@ long keyID = token.p11.C_DeriveKey(session.id(), new CK_MECHANISM(mechanism, params), p11Key.keyID, attributes); int major, minor; - ckVersion = params.pVersion; - if (ckVersion == null) { + if (params.pVersion == null) { major = -1; minor = -1; } else { - major = ckVersion.major; - minor = ckVersion.minor; + major = params.pVersion.major; + minor = params.pVersion.minor; } SecretKey key = P11Key.masterSecretKey(session, keyID, "TlsMasterSecret", 48 << 3, attributes, major, minor); @@ -156,5 +166,4 @@ token.releaseSession(session); } } - } diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java Wed Jul 05 22:16:00 2017 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,12 +60,20 @@ @SuppressWarnings("deprecation") private TlsRsaPremasterSecretParameterSpec spec; + // whether SSLv3 is supported + private final boolean supportSSLv3; + P11TlsRsaPremasterSecretGenerator(Token token, String algorithm, long mechanism) throws PKCS11Exception { super(); this.token = token; this.algorithm = algorithm; this.mechanism = mechanism; + + // Given the current lookup order specified in SunPKCS11.java, + // if CKM_SSL3_PRE_MASTER_KEY_GEN is not used to construct this object, + // it means that this mech is disabled or unsupported. + this.supportSSLv3 = (mechanism == CKM_SSL3_PRE_MASTER_KEY_GEN); } protected void engineInit(SecureRandom random) { @@ -78,7 +86,20 @@ if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) { throw new InvalidAlgorithmParameterException(MSG); } - this.spec = (TlsRsaPremasterSecretParameterSpec)params; + + TlsRsaPremasterSecretParameterSpec spec = + (TlsRsaPremasterSecretParameterSpec) params; + + int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion(); + + if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) || + (version > 0x0302)) { + throw new InvalidAlgorithmParameterException + ("Only" + (supportSSLv3? " SSL 3.0,": "") + + " TLS 1.0, and TLS 1.1 are supported (0x" + + Integer.toHexString(version) + ")"); + } + this.spec = spec; } protected void engineInit(int keysize, SecureRandom random) { diff -r 8ced0dd94a6e -r 552748e3d506 jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Secmod.java --- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Secmod.java Thu Sep 22 16:41:14 2016 +0000 +++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Secmod.java Wed Jul 05 22:16:00 2017 +0200 @@ -45,7 +45,7 @@ *

      *   Secmod secmod = Secmod.getInstance();
      *   if (secmod.isInitialized() == false) {
    - *       secmod.initialize("/home/myself/.mozilla", "/usr/sfw/lib/mozilla");
    + *       secmod.initialize("/home/myself/.mozilla");
      *   }
      *
      *   Provider p = secmod.getModule(ModuleType.KEYSTORE).getProvider();
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/com/sun/net/httpserver/Test5.java
    --- a/jdk/test/com/sun/net/httpserver/Test5.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/com/sun/net/httpserver/Test5.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -145,6 +145,7 @@
             socket.close();
             s = new String (b,0,count, "ISO8859_1");
             if (!compare (s, result)) {
    +            System.err.println(" Expected [" + result + "]\n actual [" + s + "]");
                 throw new RuntimeException ("wrong string result");
             }
         }
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/io/PrintStream/FormatLocale.java
    --- a/jdk/test/java/io/PrintStream/FormatLocale.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/io/PrintStream/FormatLocale.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -21,10 +21,11 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 8146156
      * @summary test whether conversion follows Locale.Category.FORMAT locale.
    + * @modules jdk.localedata
      * @run main/othervm FormatLocale
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,35 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/*
    + * @test
    + * @bug 8157464
    + * @summary Basic test for StackWalker.getCallerClass()
    + * @library src
    + * @build java.base/java.util.CSM csm/*
    + * @run main/othervm csm/jdk.test.CallerSensitiveTest
    + * @run main/othervm csm/jdk.test.CallerSensitiveTest sm
    + */
    +public class Main {
    +}
    +
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/jdk/test/CallerSensitiveTest.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/jdk/test/CallerSensitiveTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,159 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +package jdk.test;
    +
    +import java.lang.invoke.MethodHandle;
    +import java.lang.invoke.MethodHandles;
    +import java.lang.invoke.MethodHandles.Lookup;
    +import java.lang.invoke.MethodType;
    +import java.lang.reflect.Method;
    +import java.security.Permission;
    +import java.security.PermissionCollection;
    +import java.security.Permissions;
    +import java.security.Policy;
    +import java.security.ProtectionDomain;
    +import java.util.CSM.Result;
    +import java.util.function.Supplier;
    +
    +/**
    + * This test invokes StackWalker::getCallerClass via static reference,
    + * reflection, MethodHandle, lambda.  Also verify that
    + * StackWalker::getCallerClass can't be called from @CallerSensitive method.
    + */
    +public class CallerSensitiveTest {
    +    private static final String NON_CSM_CALLER_METHOD = "getCallerClass";
    +    private static final String CSM_CALLER_METHOD = "caller";
    +
    +    public static void main(String... args) throws Throwable {
    +        boolean sm = false;
    +        if (args.length > 0 && args[0].equals("sm")) {
    +            sm = true;
    +            PermissionCollection perms = new Permissions();
    +            perms.add(new StackFramePermission("retainClassReference"));
    +            Policy.setPolicy(new Policy() {
    +                @Override
    +                public boolean implies(ProtectionDomain domain, Permission p) {
    +                    return perms.implies(p);
    +                }
    +            });
    +            System.setSecurityManager(new SecurityManager());
    +        }
    +
    +        System.err.format("Test %s security manager.%n",
    +                          sm ? "with" : "without");
    +
    +        CallerSensitiveTest cstest = new CallerSensitiveTest();
    +        // test static call to java.util.CSM::caller and CSM::getCallerClass
    +        cstest.staticMethodCall();
    +        // test java.lang.reflect.Method call
    +        cstest.reflectMethodCall();
    +        // test java.lang.invoke.MethodHandle
    +        cstest.invokeMethodHandle(Lookup1.lookup);
    +        cstest.invokeMethodHandle(Lookup2.lookup);
    +        // test method ref
    +        cstest.lambda();
    +
    +        LambdaTest.lambda();
    +
    +        if (failed > 0) {
    +            throw new RuntimeException(failed + " test cases failed.");
    +        }
    +    }
    +
    +    void staticMethodCall() {
    +        java.util.CSM.caller();
    +
    +        Result result = java.util.CSM.getCallerClass();
    +        checkNonCSMCaller(CallerSensitiveTest.class, result);
    +    }
    +
    +    void reflectMethodCall() throws Throwable {
    +        Method method1 = java.util.CSM.class.getMethod(CSM_CALLER_METHOD);
    +        method1.invoke(null);
    +
    +        Method method2 = java.util.CSM.class.getMethod(NON_CSM_CALLER_METHOD);
    +        Result result = (Result) method2.invoke(null);
    +        checkNonCSMCaller(CallerSensitiveTest.class, result);
    +    }
    +
    +    void invokeMethodHandle(Lookup lookup) throws Throwable {
    +        MethodHandle mh1 = lookup.findStatic(java.util.CSM.class, CSM_CALLER_METHOD,
    +            MethodType.methodType(Class.class));
    +        Class c = (Class)mh1.invokeExact();
    +
    +        MethodHandle mh2 = lookup.findStatic(java.util.CSM.class, NON_CSM_CALLER_METHOD,
    +            MethodType.methodType(Result.class));
    +        Result result = (Result)mh2.invokeExact();
    +        checkNonCSMCaller(CallerSensitiveTest.class, result);
    +    }
    +
    +    void lambda() {
    +        Result result = LambdaTest.getCallerClass.get();
    +        checkNonCSMCaller(CallerSensitiveTest.class, result);
    +
    +        LambdaTest.caller.get();
    +    }
    +
    +    static int failed = 0;
    +
    +    static void checkNonCSMCaller(Class expected, Result result) {
    +        if (result.callers.size() != 1) {
    +            throw new RuntimeException("Expected result.callers contain one element");
    +        }
    +        if (expected != result.callers.get(0)) {
    +            System.err.format("ERROR: Expected %s but got %s%n", expected,
    +                result.callers);
    +            result.frames.stream()
    +                .forEach(f -> System.err.println("   " + f));
    +            failed++;
    +        }
    +    }
    +
    +    static class Lookup1 {
    +        static Lookup lookup = MethodHandles.lookup();
    +    }
    +
    +    static class Lookup2 {
    +        static Lookup lookup = MethodHandles.lookup();
    +    }
    +
    +    static class LambdaTest {
    +        static Supplier> caller = java.util.CSM::caller;
    +        static Supplier getCallerClass = java.util.CSM::getCallerClass;
    +
    +        static void caller() {
    +            caller.get();
    +        }
    +        static Result getCallerClass() {
    +            return getCallerClass.get();
    +        }
    +
    +        static void lambda() {
    +            Result result = LambdaTest.getCallerClass();
    +            checkNonCSMCaller(LambdaTest.class, result);
    +
    +            LambdaTest.caller();
    +        }
    +    }
    +}
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/module-info.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/csm/module-info.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,26 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +module csm {
    +    exports jdk.test;
    +}
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/StackWalker/CallerSensitiveMethod/src/java.base/java/util/CSM.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/src/java.base/java/util/CSM.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,77 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +package java.util;
    +
    +import static java.lang.StackWalker.Option.*;
    +import java.lang.StackWalker.StackFrame;
    +import java.util.stream.Collectors;
    +
    +import jdk.internal.reflect.CallerSensitive;
    +import jdk.internal.reflect.Reflection;
    +
    +public class CSM {
    +    private static StackWalker walker =
    +        StackWalker.getInstance(EnumSet.of(RETAIN_CLASS_REFERENCE,
    +                                           SHOW_HIDDEN_FRAMES,
    +                                           SHOW_REFLECT_FRAMES));
    +
    +    public static class Result {
    +        public final List> callers;
    +        public final List frames;
    +        Result(List> callers,
    +               List frames) {
    +            this.callers = callers;
    +            this.frames = frames;
    +        }
    +    }
    +
    +    /**
    +     * Returns the caller of this caller-sensitive method returned by
    +     * by Reflection::getCallerClass.
    +     *
    +     * StackWalker::getCallerClass is expected to throw UOE
    +     */
    +    @CallerSensitive
    +    public static Class caller() {
    +        Class c1 = Reflection.getCallerClass();
    +
    +        try {
    +            Class c2 = walker.getCallerClass();
    +            throw new RuntimeException("Exception not thrown by StackWalker::getCallerClass");
    +        } catch (UnsupportedOperationException e) {}
    +        return c1;
    +    }
    +
    +    /**
    +     * Returns the caller of this non-caller-sensitive method.
    +     */
    +    public static Result getCallerClass() {
    +        Class caller = walker.getCallerClass();
    +        return new Result(List.of(caller), dump());
    +    }
    +
    +    static List dump() {
    +        return walker.walk(s -> s.collect(Collectors.toList()));
    +    }
    +}
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/instrument/SimpleAgent.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/jdk/test/java/lang/instrument/SimpleAgent.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,32 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +import java.lang.instrument.Instrumentation;
    +
    +class SimpleAgent {
    +
    +    public static void premain(String args, Instrumentation inst) {
    +        System.out.println("in premain");
    +    }
    +
    +}
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/instrument/TestAgentWithLimitMods.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/jdk/test/java/lang/instrument/TestAgentWithLimitMods.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,40 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + *
    + * @test
    + * @summary Tests that the -javaagent option adds the java.instrument into
    + * the module graph
    + * @modules java.instrument
    + * @run shell MakeJAR3.sh SimpleAgent
    + * @run main/othervm -javaagent:SimpleAgent.jar -limitmods java.base TestAgentWithLimitMods
    + *
    + */
    +public class TestAgentWithLimitMods {
    +
    +    public static void main(String[] args) {
    +        System.out.println("Test passed");
    +    }
    +
    +}
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/lang/invoke/MethodHandlesTest.java
    --- a/jdk/test/java/lang/invoke/MethodHandlesTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -632,6 +632,7 @@
         }
     
         public void testFindVirtualClone0() throws Throwable {
    +        if (CAN_SKIP_WORKING)  return;
             // test some ad hoc system methods
             testFindVirtual(false, PUBLIC, Object.class, Object.class, "clone");
     
    @@ -2798,11 +2799,17 @@
                 toClauseMajor(postClauses, inits, steps, usePreds, finis);
                 MethodHandle pre = MethodHandles.loop(preClauses);
                 MethodHandle post = MethodHandles.loop(postClauses);
    +            if (verbosity >= 6) {
    +                System.out.println("pre-handle: " + pre);
    +            }
                 Object[] preResults = (Object[]) pre.invokeWithArguments(args);
                 if (verbosity >= 4) {
                     System.out.println("pre-checked: expected " + Arrays.asList(preCheckedResults[i]) + ", actual " +
                             Arrays.asList(preResults));
                 }
    +            if (verbosity >= 6) {
    +                System.out.println("post-handle: " + post);
    +            }
                 Object[] postResults = (Object[]) post.invokeWithArguments(args);
                 if (verbosity >= 4) {
                     System.out.println("post-checked: expected " + Arrays.asList(postCheckedResults[i]) + ", actual " +
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/MulticastSocket/TimeToLive.java
    --- a/jdk/test/java/net/MulticastSocket/TimeToLive.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/net/MulticastSocket/TimeToLive.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -37,26 +37,27 @@
         static int[] bad_ttls = { -1, 256 };
     
         public static void main(String[] args) throws Exception {
    -        MulticastSocket socket = new MulticastSocket(6789);
    -        int ttl = socket.getTimeToLive();
    -        System.out.println("default ttl: " + ttl);
    -        for (int i = 0; i < new_ttls.length; i++) {
    -            socket.setTimeToLive(new_ttls[i]);
    -            if (!(new_ttls[i] == socket.getTimeToLive())) {
    -                throw new RuntimeException("test failure, set/get differ: " +
    -                                           new_ttls[i] + " /  " +
    -                                           socket.getTimeToLive());
    +        try (MulticastSocket socket = new MulticastSocket()) {
    +            int ttl = socket.getTimeToLive();
    +            System.out.println("default ttl: " + ttl);
    +            for (int i = 0; i < new_ttls.length; i++) {
    +                socket.setTimeToLive(new_ttls[i]);
    +                if (!(new_ttls[i] == socket.getTimeToLive())) {
    +                    throw new RuntimeException("test failure, set/get differ: " +
    +                            new_ttls[i] + " /  " +
    +                            socket.getTimeToLive());
    +                }
                 }
    -        }
    -        for (int j = 0; j < bad_ttls.length; j++) {
    -            boolean exception = false;
    -            try {
    -                socket.setTimeToLive(bad_ttls[j]);
    -            } catch (IllegalArgumentException e) {
    -                exception = true;
    -            }
    -            if (!exception) {
    -                throw new RuntimeException("bad argument accepted: " + bad_ttls[j]);
    +            for (int j = 0; j < bad_ttls.length; j++) {
    +                boolean exception = false;
    +                try {
    +                    socket.setTimeToLive(bad_ttls[j]);
    +                } catch (IllegalArgumentException e) {
    +                    exception = true;
    +                }
    +                if (!exception) {
    +                    throw new RuntimeException("bad argument accepted: " + bad_ttls[j]);
    +                }
                 }
             }
         }
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/ServerSocket/ThreadStop.java
    --- a/jdk/test/java/net/ServerSocket/ThreadStop.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/net/ServerSocket/ThreadStop.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -68,23 +68,23 @@
             thr.start();
     
             // give server time to block in ServerSocket.accept()
    -        Thread.currentThread().sleep(2000);
    +        Thread.sleep(2000);
     
             // "stop" the thread
             thr.stop();
     
             // give thread time to stop
    -        Thread.currentThread().sleep(2000);
    +        Thread.sleep(2000);
     
             // it's platform specific if Thread.stop interrupts the
             // thread - on Linux/Windows most likely that thread is
             // still in accept() so we connect to server which causes
             // it to unblock and do JNI-stuff with a pending exception
     
    -        try {
    -            Socket s = new Socket("localhost", svr.localPort());
    -        } catch (IOException ioe) { }
    -
    +        try (Socket s = new Socket("localhost", svr.localPort())) {
    +        } catch (IOException ioe) {
    +        }
    +        thr.join();
         }
     
     }
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/Socket/InheritHandle.java
    --- a/jdk/test/java/net/Socket/InheritHandle.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/net/Socket/InheritHandle.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -27,6 +27,7 @@
        @author Chris Hegarty
      */
     
    +import java.net.BindException;
     import java.net.ServerSocket;
     import java.io.File;
     import java.io.IOException;
    @@ -74,6 +75,11 @@
             } catch (IOException ioe) {
                 System.out.println("Cannot create process");
                 ioe.printStackTrace();
    +            try {
    +                ss.close();
    +            } catch (IOException e) {
    +                e.printStackTrace();
    +            }
                 return;
             }
     
    @@ -85,9 +91,18 @@
                 System.out.println("Now close the socket and try to create another" +
                                    " one listening on the same port");
                 ss.close();
    -            ss = new ServerSocket(port);
    -            System.out.println("Second ServerSocket created successfully");
    -            ss.close();
    +            int retries = 0;
    +            while (retries < 5) {
    +                try (ServerSocket s = new ServerSocket(port);) {
    +                    System.out.println("Second ServerSocket created successfully");
    +                    break;
    +                } catch (BindException e) {
    +                    System.out.println("BindException \"" + e.getMessage() + "\", retrying...");
    +                    Thread.sleep(100L);
    +                    retries ++;
    +                    continue;
    +                }
    +            }
     
             } catch (InterruptedException ie) {
             } catch (IOException ioe) {
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/URLClassLoader/definePackage/SplitPackage.java
    --- a/jdk/test/java/net/URLClassLoader/definePackage/SplitPackage.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/net/URLClassLoader/definePackage/SplitPackage.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -27,6 +27,7 @@
      * @summary Test two URLClassLoader define Package object of the same name
      * @library /lib/testlibrary
      * @build CompilerUtils
    + * @modules jdk.compiler
      * @run testng SplitPackage
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/URLPermission/nstest/LookupTest.java
    --- a/jdk/test/java/net/URLPermission/nstest/LookupTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/net/URLPermission/nstest/LookupTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -37,6 +37,7 @@
             String url, boolean throwsSecException, boolean throwsIOException)
         {
             try {
    +            ProxySelector.setDefault(null);
                 URL u = new URL(url);
                 System.err.println ("Connecting to " + u);
                 URLConnection urlc = u.openConnection();
    @@ -71,7 +72,7 @@
                 System.out.print(port);
             } else if (cmd.equals("-runtest")) {
                 port = Integer.parseInt(args[1]);
    -            String hostsFileName = System.getProperty("test.src", ".") + "/LookupTestHosts";
    +            String hostsFileName = System.getProperty("user.dir", ".") + "/LookupTestHosts";
                 System.setProperty("jdk.net.hosts.file", hostsFileName);
                 addMappingToHostsFile("allowedAndFound.com", "127.0.0.1", hostsFileName, false);
                 addMappingToHostsFile("notAllowedButFound.com", "99.99.99.99", hostsFileName, true);
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/URLPermission/nstest/LookupTestHosts
    --- a/jdk/test/java/net/URLPermission/nstest/LookupTestHosts	Thu Sep 22 16:41:14 2016 +0000
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,2 +0,0 @@
    -127.0.0.1 allowedAndFound.com
    -99.99.99.99 notAllowedButFound.com
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/URLPermission/nstest/lookup.sh
    --- a/jdk/test/java/net/URLPermission/nstest/lookup.sh	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/net/URLPermission/nstest/lookup.sh	Wed Jul 05 22:16:00 2017 +0200
    @@ -48,6 +48,7 @@
     grant {
         permission java.net.URLPermission "http://allowedAndFound.com:${port}/-", "*:*";
         permission java.net.URLPermission "http://allowedButNotfound.com:${port}/-", "*:*";
    +    permission java.net.NetPermission "setProxySelector";
         permission java.io.FilePermission "<>", "read,write,delete";
         permission java.util.PropertyPermission "java.io.tmpdir", "read";
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/httpclient/HeadersTest1.java
    --- a/jdk/test/java/net/httpclient/HeadersTest1.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/net/httpclient/HeadersTest1.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -23,9 +23,11 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 8153142
    + * @modules java.httpclient
    + *          jdk.httpserver
      * @run main/othervm HeadersTest1
      * @summary HeadersTest1
      */
    @@ -39,9 +41,11 @@
     import java.io.InputStream;
     import java.io.OutputStream;
     import java.net.InetSocketAddress;
    -import java.net.PasswordAuthentication;
     import java.net.URI;
    -import java.net.http.*;
    +import java.net.http.HttpClient;
    +import java.net.http.HttpHeaders;
    +import java.net.http.HttpResponse;
    +import java.net.http.HttpRequest;
     import java.util.concurrent.ExecutorService;
     import java.util.concurrent.Executors;
     import java.util.List;
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/httpclient/ProxyAuthTest.java
    --- a/jdk/test/java/net/httpclient/ProxyAuthTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/net/httpclient/ProxyAuthTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -26,6 +26,7 @@
      * @test
      * @bug 8163561
      * @modules java.base/sun.net.www
    + *          java.httpclient
      * @summary Verify that Proxy-Authenticate header is correctly handled
      *
      * @run main/othervm ProxyAuthTest
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/net/httpclient/whitebox/Driver.java
    --- a/jdk/test/java/net/httpclient/whitebox/Driver.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/net/httpclient/whitebox/Driver.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -24,5 +24,6 @@
     /*
      * @test
      * @bug 8151299
    + * @modules java.httpclient
      * @run testng java.httpclient/java.net.http.SelectorTest
      */
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/Collections/EmptyNavigableMap.java
    --- a/jdk/test/java/util/Collections/EmptyNavigableMap.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/Collections/EmptyNavigableMap.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -33,7 +33,6 @@
     import java.util.Collections;
     import java.util.Comparator;
     import java.util.Iterator;
    -import java.util.NoSuchElementException;
     import java.util.NavigableMap;
     import java.util.SortedMap;
     import java.util.TreeMap;
    @@ -41,10 +40,8 @@
     import org.testng.annotations.DataProvider;
     
     import static org.testng.Assert.fail;
    -import static org.testng.Assert.assertEquals;
     import static org.testng.Assert.assertTrue;
     import static org.testng.Assert.assertFalse;
    -import static org.testng.Assert.assertSame;
     
     public class EmptyNavigableMap {
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/Collections/EmptyNavigableSet.java
    --- a/jdk/test/java/util/Collections/EmptyNavigableSet.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/Collections/EmptyNavigableSet.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -41,10 +41,9 @@
     import org.testng.annotations.DataProvider;
     
     import static org.testng.Assert.fail;
    -import static org.testng.Assert.assertEquals;
    -import static org.testng.Assert.assertTrue;
     import static org.testng.Assert.assertFalse;
     import static org.testng.Assert.assertSame;
    +import static org.testng.Assert.assertTrue;
     
     public class EmptyNavigableSet {
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/Deque/ChorusLine.java
    --- a/jdk/test/java/util/Deque/ChorusLine.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/Deque/ChorusLine.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -28,8 +28,14 @@
      * @author Martin Buchholz
      */
     
    -import java.util.*;
    -import java.util.concurrent.*;
    +import java.util.ArrayDeque;
    +import java.util.Collection;
    +import java.util.Deque;
    +import java.util.Iterator;
    +import java.util.LinkedList;
    +import java.util.NoSuchElementException;
    +import java.util.concurrent.ConcurrentLinkedDeque;
    +import java.util.concurrent.LinkedBlockingDeque;
     
     public class ChorusLine {
         private interface Tweaker {
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/PriorityQueue/ForgetMeNot.java
    --- a/jdk/test/java/util/PriorityQueue/ForgetMeNot.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/PriorityQueue/ForgetMeNot.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -28,7 +28,11 @@
      * @author Martin Buchholz
      */
     
    -import java.util.*;
    +import java.util.Arrays;
    +import java.util.Iterator;
    +import java.util.NoSuchElementException;
    +import java.util.PriorityQueue;
    +import java.util.Queue;
     
     public class ForgetMeNot {
         private static void checkQ(PriorityQueue q, Integer...elts) {
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/PriorityQueue/PriorityQueueSort.java
    --- a/jdk/test/java/util/PriorityQueue/PriorityQueueSort.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/PriorityQueue/PriorityQueueSort.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -37,7 +37,13 @@
      * @summary Checks that a priority queue returns elements in sorted order across various operations
      */
     
    -import java.util.*;
    +import java.util.ArrayList;
    +import java.util.Collections;
    +import java.util.Comparator;
    +import java.util.Iterator;
    +import java.util.List;
    +import java.util.Queue;
    +import java.util.PriorityQueue;
     
     public class PriorityQueueSort {
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/PriorityQueue/RemoveContains.java
    --- a/jdk/test/java/util/PriorityQueue/RemoveContains.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/PriorityQueue/RemoveContains.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -28,8 +28,17 @@
      * @author  Martin Buchholz
      */
     
    -import java.util.*;
    -import java.util.concurrent.*;
    +import java.util.ArrayDeque;
    +import java.util.Arrays;
    +import java.util.Comparator;
    +import java.util.List;
    +import java.util.PriorityQueue;
    +import java.util.Queue;
    +import java.util.concurrent.ArrayBlockingQueue;
    +import java.util.concurrent.LinkedBlockingDeque;
    +import java.util.concurrent.LinkedBlockingQueue;
    +import java.util.concurrent.PriorityBlockingQueue;
    +import java.util.concurrent.LinkedTransferQueue;
     
     public class RemoveContains {
         static volatile int passed = 0, failed = 0;
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/Executors/AutoShutdown.java
    --- a/jdk/test/java/util/concurrent/Executors/AutoShutdown.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/Executors/AutoShutdown.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -31,8 +31,6 @@
      */
     
     import static java.util.concurrent.Executors.defaultThreadFactory;
    -import static java.util.concurrent.Executors.newFixedThreadPool;
    -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
     import static java.util.concurrent.Executors.newSingleThreadExecutor;
     
     import static java.util.concurrent.TimeUnit.MILLISECONDS;
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java
    --- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/CoreThreadTimeOut.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -83,15 +83,18 @@
             tpe.allowCoreThreadTimeOut(true);
             check(tpe.allowsCoreThreadTimeOut());
             equal(countExecutorThreads(), 0);
    -        long t0 = System.nanoTime();
    -        for (int i = 0; i < threadCount; i++)
    -            tpe.submit(new Runnable() { public void run() {}});
    -        int count = countExecutorThreads();
    -        if (millisElapsedSince(t0) < timeoutMillis)
    -            equal(count, threadCount);
    +        long startTime = System.nanoTime();
    +        for (int i = 0; i < threadCount; i++) {
    +            tpe.submit(() -> {});
    +            int count = countExecutorThreads();
    +            if (millisElapsedSince(startTime) < timeoutMillis)
    +                equal(count, i + 1);
    +        }
             while (countExecutorThreads() > 0 &&
    -               millisElapsedSince(t0) < 10 * 1000);
    +               millisElapsedSince(startTime) < LONG_DELAY_MS)
    +            Thread.yield();
             equal(countExecutorThreads(), 0);
    +        check(millisElapsedSince(startTime) >= timeoutMillis);
             tpe.shutdown();
             check(tpe.allowsCoreThreadTimeOut());
             check(tpe.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java
    --- a/jdk/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -303,7 +303,7 @@
     
         class Counter extends CheckedRunnable {
             final AtomicIntegerArray aa;
    -        volatile int counts;
    +        int decs;
             Counter(AtomicIntegerArray a) { aa = a; }
             public void realRun() {
                 for (;;) {
    @@ -314,7 +314,7 @@
                         if (v != 0) {
                             done = false;
                             if (aa.compareAndSet(i, v, v - 1))
    -                            ++counts;
    +                            decs++;
                         }
                     }
                     if (done)
    @@ -334,13 +334,11 @@
                 aa.set(i, countdown);
             Counter c1 = new Counter(aa);
             Counter c2 = new Counter(aa);
    -        Thread t1 = new Thread(c1);
    -        Thread t2 = new Thread(c2);
    -        t1.start();
    -        t2.start();
    +        Thread t1 = newStartedThread(c1);
    +        Thread t2 = newStartedThread(c2);
             t1.join();
             t2.join();
    -        assertEquals(c1.counts+c2.counts, SIZE * countdown);
    +        assertEquals(c1.decs + c2.decs, SIZE * countdown);
         }
     
         /**
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/AtomicLongArrayTest.java
    --- a/jdk/test/java/util/concurrent/tck/AtomicLongArrayTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/AtomicLongArrayTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -302,7 +302,7 @@
     
         class Counter extends CheckedRunnable {
             final AtomicLongArray aa;
    -        volatile long counts;
    +        int decs;
             Counter(AtomicLongArray a) { aa = a; }
             public void realRun() {
                 for (;;) {
    @@ -313,7 +313,7 @@
                         if (v != 0) {
                             done = false;
                             if (aa.compareAndSet(i, v, v - 1))
    -                            ++counts;
    +                            decs++;
                         }
                     }
                     if (done)
    @@ -333,13 +333,11 @@
                 aa.set(i, countdown);
             Counter c1 = new Counter(aa);
             Counter c2 = new Counter(aa);
    -        Thread t1 = new Thread(c1);
    -        Thread t2 = new Thread(c2);
    -        t1.start();
    -        t2.start();
    +        Thread t1 = newStartedThread(c1);
    +        Thread t2 = newStartedThread(c2);
             t1.join();
             t2.join();
    -        assertEquals(c1.counts+c2.counts, SIZE * countdown);
    +        assertEquals(c1.decs + c2.decs, SIZE * countdown);
         }
     
         /**
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/CompletableFutureTest.java
    --- a/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -388,7 +388,7 @@
             checkCompletedNormally(f, "test");
         }
     
    -    abstract class CheckedAction {
    +    abstract static class CheckedAction {
             int invocationCount = 0;
             final ExecutionMode m;
             CheckedAction(ExecutionMode m) { this.m = m; }
    @@ -400,7 +400,7 @@
             void assertInvoked() { assertEquals(1, invocationCount); }
         }
     
    -    abstract class CheckedIntegerAction extends CheckedAction {
    +    abstract static class CheckedIntegerAction extends CheckedAction {
             Integer value;
             CheckedIntegerAction(ExecutionMode m) { super(m); }
             void assertValue(Integer expected) {
    @@ -409,7 +409,7 @@
             }
         }
     
    -    class IntegerSupplier extends CheckedAction
    +    static class IntegerSupplier extends CheckedAction
             implements Supplier
         {
             final Integer value;
    @@ -428,7 +428,7 @@
             return (x == null) ? null : x + 1;
         }
     
    -    class NoopConsumer extends CheckedIntegerAction
    +    static class NoopConsumer extends CheckedIntegerAction
             implements Consumer
         {
             NoopConsumer(ExecutionMode m) { super(m); }
    @@ -438,7 +438,7 @@
             }
         }
     
    -    class IncFunction extends CheckedIntegerAction
    +    static class IncFunction extends CheckedIntegerAction
             implements Function
         {
             IncFunction(ExecutionMode m) { super(m); }
    @@ -456,7 +456,7 @@
                 - ((y == null) ? 99 : y.intValue());
         }
     
    -    class SubtractAction extends CheckedIntegerAction
    +    static class SubtractAction extends CheckedIntegerAction
             implements BiConsumer
         {
             SubtractAction(ExecutionMode m) { super(m); }
    @@ -466,7 +466,7 @@
             }
         }
     
    -    class SubtractFunction extends CheckedIntegerAction
    +    static class SubtractFunction extends CheckedIntegerAction
             implements BiFunction
         {
             SubtractFunction(ExecutionMode m) { super(m); }
    @@ -476,14 +476,14 @@
             }
         }
     
    -    class Noop extends CheckedAction implements Runnable {
    +    static class Noop extends CheckedAction implements Runnable {
             Noop(ExecutionMode m) { super(m); }
             public void run() {
                 invoked();
             }
         }
     
    -    class FailingSupplier extends CheckedAction
    +    static class FailingSupplier extends CheckedAction
             implements Supplier
         {
             final CFException ex;
    @@ -494,7 +494,7 @@
             }
         }
     
    -    class FailingConsumer extends CheckedIntegerAction
    +    static class FailingConsumer extends CheckedIntegerAction
             implements Consumer
         {
             final CFException ex;
    @@ -506,7 +506,7 @@
             }
         }
     
    -    class FailingBiConsumer extends CheckedIntegerAction
    +    static class FailingBiConsumer extends CheckedIntegerAction
             implements BiConsumer
         {
             final CFException ex;
    @@ -518,7 +518,7 @@
             }
         }
     
    -    class FailingFunction extends CheckedIntegerAction
    +    static class FailingFunction extends CheckedIntegerAction
             implements Function
         {
             final CFException ex;
    @@ -530,7 +530,7 @@
             }
         }
     
    -    class FailingBiFunction extends CheckedIntegerAction
    +    static class FailingBiFunction extends CheckedIntegerAction
             implements BiFunction
         {
             final CFException ex;
    @@ -542,7 +542,7 @@
             }
         }
     
    -    class FailingRunnable extends CheckedAction implements Runnable {
    +    static class FailingRunnable extends CheckedAction implements Runnable {
             final CFException ex;
             FailingRunnable(ExecutionMode m) { super(m); ex = new CFException(); }
             public void run() {
    @@ -551,7 +551,7 @@
             }
         }
     
    -    class CompletableFutureInc extends CheckedIntegerAction
    +    static class CompletableFutureInc extends CheckedIntegerAction
             implements Function>
         {
             CompletableFutureInc(ExecutionMode m) { super(m); }
    @@ -564,7 +564,7 @@
             }
         }
     
    -    class FailingCompletableFutureFunction extends CheckedIntegerAction
    +    static class FailingCompletableFutureFunction extends CheckedIntegerAction
             implements Function>
         {
             final CFException ex;
    @@ -3604,29 +3604,53 @@
          * copy returns a CompletableFuture that is completed normally,
          * with the same value, when source is.
          */
    -    public void testCopy() {
    +    public void testCopy_normalCompletion() {
    +        for (boolean createIncomplete : new boolean[] { true, false })
    +        for (Integer v1 : new Integer[] { 1, null })
    +    {
             CompletableFuture f = new CompletableFuture<>();
    +        if (!createIncomplete) assertTrue(f.complete(v1));
             CompletableFuture g = f.copy();
    -        checkIncomplete(f);
    -        checkIncomplete(g);
    -        f.complete(1);
    -        checkCompletedNormally(f, 1);
    -        checkCompletedNormally(g, 1);
    -    }
    +        if (createIncomplete) {
    +            checkIncomplete(f);
    +            checkIncomplete(g);
    +            assertTrue(f.complete(v1));
    +        }
    +        checkCompletedNormally(f, v1);
    +        checkCompletedNormally(g, v1);
    +    }}
     
         /**
          * copy returns a CompletableFuture that is completed exceptionally
          * when source is.
          */
    -    public void testCopy2() {
    +    public void testCopy_exceptionalCompletion() {
    +        for (boolean createIncomplete : new boolean[] { true, false })
    +    {
    +        CFException ex = new CFException();
             CompletableFuture f = new CompletableFuture<>();
    +        if (!createIncomplete) f.completeExceptionally(ex);
             CompletableFuture g = f.copy();
    -        checkIncomplete(f);
    -        checkIncomplete(g);
    -        CFException ex = new CFException();
    -        f.completeExceptionally(ex);
    +        if (createIncomplete) {
    +            checkIncomplete(f);
    +            checkIncomplete(g);
    +            f.completeExceptionally(ex);
    +        }
             checkCompletedExceptionally(f, ex);
             checkCompletedWithWrappedException(g, ex);
    +    }}
    +
    +    /**
    +     * Completion of a copy does not complete its source.
    +     */
    +    public void testCopy_oneWayPropagation() {
    +        CompletableFuture f = new CompletableFuture<>();
    +        assertTrue(f.copy().complete(1));
    +        assertTrue(f.copy().complete(null));
    +        assertTrue(f.copy().cancel(true));
    +        assertTrue(f.copy().cancel(false));
    +        assertTrue(f.copy().completeExceptionally(new CFException()));
    +        checkIncomplete(f);
         }
     
         /**
    @@ -3991,7 +4015,10 @@
                 .collect(Collectors.toList());
     
             List> stages = new ArrayList<>();
    -        stages.add(new CompletableFuture().minimalCompletionStage());
    +        CompletionStage min =
    +            new CompletableFuture().minimalCompletionStage();
    +        stages.add(min);
    +        stages.add(min.thenApply(x -> x));
             stages.add(CompletableFuture.completedStage(1));
             stages.add(CompletableFuture.failedStage(new CFException()));
     
    @@ -4027,6 +4054,131 @@
                 throw new Error("Methods did not throw UOE: " + bugs);
         }
     
    +    /**
    +     * minimalStage.toCompletableFuture() returns a CompletableFuture that
    +     * is completed normally, with the same value, when source is.
    +     */
    +    public void testMinimalCompletionStage_toCompletableFuture_normalCompletion() {
    +        for (boolean createIncomplete : new boolean[] { true, false })
    +        for (Integer v1 : new Integer[] { 1, null })
    +    {
    +        CompletableFuture f = new CompletableFuture<>();
    +        CompletionStage minimal = f.minimalCompletionStage();
    +        if (!createIncomplete) assertTrue(f.complete(v1));
    +        CompletableFuture g = minimal.toCompletableFuture();
    +        if (createIncomplete) {
    +            checkIncomplete(f);
    +            checkIncomplete(g);
    +            assertTrue(f.complete(v1));
    +        }
    +        checkCompletedNormally(f, v1);
    +        checkCompletedNormally(g, v1);
    +    }}
    +
    +    /**
    +     * minimalStage.toCompletableFuture() returns a CompletableFuture that
    +     * is completed exceptionally when source is.
    +     */
    +    public void testMinimalCompletionStage_toCompletableFuture_exceptionalCompletion() {
    +        for (boolean createIncomplete : new boolean[] { true, false })
    +    {
    +        CFException ex = new CFException();
    +        CompletableFuture f = new CompletableFuture<>();
    +        CompletionStage minimal = f.minimalCompletionStage();
    +        if (!createIncomplete) f.completeExceptionally(ex);
    +        CompletableFuture g = minimal.toCompletableFuture();
    +        if (createIncomplete) {
    +            checkIncomplete(f);
    +            checkIncomplete(g);
    +            f.completeExceptionally(ex);
    +        }
    +        checkCompletedExceptionally(f, ex);
    +        checkCompletedWithWrappedException(g, ex);
    +    }}
    +
    +    /**
    +     * minimalStage.toCompletableFuture() gives mutable CompletableFuture
    +     */
    +    public void testMinimalCompletionStage_toCompletableFuture_mutable() {
    +        for (Integer v1 : new Integer[] { 1, null })
    +    {
    +        CompletableFuture f = new CompletableFuture<>();
    +        CompletionStage minimal = f.minimalCompletionStage();
    +        CompletableFuture g = minimal.toCompletableFuture();
    +        assertTrue(g.complete(v1));
    +        checkCompletedNormally(g, v1);
    +        checkIncomplete(f);
    +        checkIncomplete(minimal.toCompletableFuture());
    +    }}
    +
    +    /**
    +     * minimalStage.toCompletableFuture().join() awaits completion
    +     */
    +    public void testMinimalCompletionStage_toCompletableFuture_join() throws Exception {
    +        for (boolean createIncomplete : new boolean[] { true, false })
    +        for (Integer v1 : new Integer[] { 1, null })
    +    {
    +        CompletableFuture f = new CompletableFuture<>();
    +        if (!createIncomplete) assertTrue(f.complete(v1));
    +        CompletionStage minimal = f.minimalCompletionStage();
    +        if (createIncomplete) assertTrue(f.complete(v1));
    +        assertEquals(v1, minimal.toCompletableFuture().join());
    +        assertEquals(v1, minimal.toCompletableFuture().get());
    +        checkCompletedNormally(minimal.toCompletableFuture(), v1);
    +    }}
    +
    +    /**
    +     * Completion of a toCompletableFuture copy of a minimal stage
    +     * does not complete its source.
    +     */
    +    public void testMinimalCompletionStage_toCompletableFuture_oneWayPropagation() {
    +        CompletableFuture f = new CompletableFuture<>();
    +        CompletionStage g = f.minimalCompletionStage();
    +        assertTrue(g.toCompletableFuture().complete(1));
    +        assertTrue(g.toCompletableFuture().complete(null));
    +        assertTrue(g.toCompletableFuture().cancel(true));
    +        assertTrue(g.toCompletableFuture().cancel(false));
    +        assertTrue(g.toCompletableFuture().completeExceptionally(new CFException()));
    +        checkIncomplete(g.toCompletableFuture());
    +        f.complete(1);
    +        checkCompletedNormally(g.toCompletableFuture(), 1);
    +    }
    +
    +    /** Demo utility method for external reliable toCompletableFuture */
    +    static  CompletableFuture toCompletableFuture(CompletionStage stage) {
    +        CompletableFuture f = new CompletableFuture<>();
    +        stage.handle((T t, Throwable ex) -> {
    +                         if (ex != null) f.completeExceptionally(ex);
    +                         else f.complete(t);
    +                         return null;
    +                     });
    +        return f;
    +    }
    +
    +    /** Demo utility method to join a CompletionStage */
    +    static  T join(CompletionStage stage) {
    +        return toCompletableFuture(stage).join();
    +    }
    +
    +    /**
    +     * Joining a minimal stage "by hand" works
    +     */
    +    public void testMinimalCompletionStage_join_by_hand() {
    +        for (boolean createIncomplete : new boolean[] { true, false })
    +        for (Integer v1 : new Integer[] { 1, null })
    +    {
    +        CompletableFuture f = new CompletableFuture<>();
    +        CompletionStage minimal = f.minimalCompletionStage();
    +        CompletableFuture g = new CompletableFuture<>();
    +        if (!createIncomplete) assertTrue(f.complete(v1));
    +        minimal.thenAccept((x) -> g.complete(x));
    +        if (createIncomplete) assertTrue(f.complete(v1));
    +        g.join();
    +        checkCompletedNormally(g, v1);
    +        checkCompletedNormally(f, v1);
    +        assertEquals(v1, join(minimal));
    +    }}
    +
         static class Monad {
             static class ZeroException extends RuntimeException {
                 public ZeroException() { super("monadic zero"); }
    @@ -4317,6 +4469,22 @@
                 assertTrue(neverCompleted.thenRun(() -> {}).cancel(true));
         }
     
    +    /**
    +     * Checks for garbage retention when MinimalStage.toCompletableFuture()
    +     * is invoked many times.
    +     * 8161600: Garbage retention when source CompletableFutures are never completed
    +     *
    +     * As of 2016-07, fails with OOME:
    +     * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testToCompletableFutureGarbageRetention tck
    +     */
    +    public void testToCompletableFutureGarbageRetention() throws Throwable {
    +        final int n = expensiveTests ? 900_000 : 10;
    +        CompletableFuture neverCompleted = new CompletableFuture<>();
    +        CompletionStage minimal = neverCompleted.minimalCompletionStage();
    +        for (int i = 0; i < n; i++)
    +            assertTrue(minimal.toCompletableFuture().cancel(true));
    +    }
    +
     //     static  U join(CompletionStage stage) {
     //         CompletableFuture f = new CompletableFuture<>();
     //         stage.whenComplete((v, ex) -> {
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java
    --- a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1024,7 +1024,7 @@
     
         static NavigableMap newMap(Class cl) throws Exception {
             NavigableMap result =
    -            (NavigableMap) cl.newInstance();
    +            (NavigableMap) cl.getConstructor().newInstance();
             assertEquals(0, result.size());
             assertFalse(result.keySet().iterator().hasNext());
             return result;
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java
    --- a/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -725,7 +725,8 @@
         }
     
         static NavigableSet newSet(Class cl) throws Exception {
    -        NavigableSet result = (NavigableSet) cl.newInstance();
    +        NavigableSet result =
    +            (NavigableSet) cl.getConstructor().newInstance();
             assertEquals(0, result.size());
             assertFalse(result.iterator().hasNext());
             return result;
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/CyclicBarrierTest.java
    --- a/jdk/test/java/util/concurrent/tck/CyclicBarrierTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/CyclicBarrierTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -40,6 +40,7 @@
     import java.util.concurrent.CyclicBarrier;
     import java.util.concurrent.TimeoutException;
     import java.util.concurrent.atomic.AtomicBoolean;
    +import java.util.concurrent.atomic.AtomicInteger;
     
     import junit.framework.Test;
     import junit.framework.TestSuite;
    @@ -52,11 +53,6 @@
             return new TestSuite(CyclicBarrierTest.class);
         }
     
    -    private volatile int countAction;
    -    private class MyAction implements Runnable {
    -        public void run() { ++countAction; }
    -    }
    -
         /**
          * Spin-waits till the number of waiters == numberOfWaiters.
          */
    @@ -114,14 +110,16 @@
          * The supplied barrier action is run at barrier
          */
         public void testBarrierAction() throws Exception {
    -        countAction = 0;
    -        CyclicBarrier b = new CyclicBarrier(1, new MyAction());
    +        final AtomicInteger count = new AtomicInteger(0);
    +        final Runnable incCount = new Runnable() { public void run() {
    +            count.getAndIncrement(); }};
    +        CyclicBarrier b = new CyclicBarrier(1, incCount);
             assertEquals(1, b.getParties());
             assertEquals(0, b.getNumberWaiting());
             b.await();
             b.await();
             assertEquals(0, b.getNumberWaiting());
    -        assertEquals(2, countAction);
    +        assertEquals(2, count.get());
         }
     
         /**
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/DelayQueueTest.java
    --- a/jdk/test/java/util/concurrent/tck/DelayQueueTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/DelayQueueTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -121,10 +121,8 @@
             }
     
             public boolean equals(Object other) {
    -            return equals((NanoDelay)other);
    -        }
    -        public boolean equals(NanoDelay other) {
    -            return other.trigger == trigger;
    +            return (other instanceof NanoDelay) &&
    +                this.trigger == ((NanoDelay)other).trigger;
             }
     
             // suppress [overrides] javac warning
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/ForkJoinPoolTest.java
    --- a/jdk/test/java/util/concurrent/tck/ForkJoinPoolTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/ForkJoinPoolTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -51,6 +51,7 @@
     import java.util.concurrent.RecursiveTask;
     import java.util.concurrent.RejectedExecutionException;
     import java.util.concurrent.atomic.AtomicBoolean;
    +import java.util.concurrent.atomic.AtomicInteger;
     import java.util.concurrent.locks.ReentrantLock;
     
     import junit.framework.AssertionFailedError;
    @@ -84,13 +85,6 @@
     
         // Some classes to test extension and factory methods
     
    -    static class MyHandler implements Thread.UncaughtExceptionHandler {
    -        volatile int catches = 0;
    -        public void uncaughtException(Thread t, Throwable e) {
    -            ++catches;
    -        }
    -    }
    -
         static class MyError extends Error {}
     
         // to test handlers
    @@ -101,9 +95,9 @@
     
         static class FailingThreadFactory
                 implements ForkJoinPool.ForkJoinWorkerThreadFactory {
    -        volatile int calls = 0;
    +        final AtomicInteger calls = new AtomicInteger(0);
             public ForkJoinWorkerThread newThread(ForkJoinPool p) {
    -            if (++calls > 1) return null;
    +            if (calls.incrementAndGet() > 1) return null;
                 return new FailingFJWSubclass(p);
             }
         }
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/JSR166TestCase.java
    --- a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1032,14 +1032,17 @@
             ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
             System.err.println("------ stacktrace dump start ------");
             for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
    -            String name = info.getThreadName();
    +            final String name = info.getThreadName();
    +            String lockName;
                 if ("Signal Dispatcher".equals(name))
                     continue;
                 if ("Reference Handler".equals(name)
    -                && info.getLockName().startsWith("java.lang.ref.Reference$Lock"))
    +                && (lockName = info.getLockName()) != null
    +                && lockName.startsWith("java.lang.ref.Reference$Lock"))
                     continue;
                 if ("Finalizer".equals(name)
    -                && info.getLockName().startsWith("java.lang.ref.ReferenceQueue$Lock"))
    +                && (lockName = info.getLockName()) != null
    +                && lockName.startsWith("java.lang.ref.ReferenceQueue$Lock"))
                     continue;
                 if ("checkForWedgedTest".equals(name))
                     continue;
    @@ -1783,7 +1786,7 @@
          * A CyclicBarrier that uses timed await and fails with
          * AssertionFailedErrors instead of throwing checked exceptions.
          */
    -    public class CheckedBarrier extends CyclicBarrier {
    +    public static class CheckedBarrier extends CyclicBarrier {
             public CheckedBarrier(int parties) { super(parties); }
     
             public int await() {
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/ScheduledExecutorTest.java
    --- a/jdk/test/java/util/concurrent/tck/ScheduledExecutorTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/ScheduledExecutorTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -537,15 +537,14 @@
          * isShutdown is false before shutdown, true after
          */
         public void testIsShutdown() {
    -
             final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
    -        try {
    -            assertFalse(p.isShutdown());
    +        assertFalse(p.isShutdown());
    +        try (PoolCleaner cleaner = cleaner(p)) {
    +            try {
    +                p.shutdown();
    +                assertTrue(p.isShutdown());
    +            } catch (SecurityException ok) {}
             }
    -        finally {
    -            try { p.shutdown(); } catch (SecurityException ok) { return; }
    -        }
    -        assertTrue(p.isShutdown());
         }
     
         /**
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/TreeMapTest.java
    --- a/jdk/test/java/util/concurrent/tck/TreeMapTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/TreeMapTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -829,7 +829,7 @@
     
         static NavigableMap newMap(Class cl) throws Exception {
             NavigableMap result
    -            = (NavigableMap) cl.newInstance();
    +            = (NavigableMap) cl.getConstructor().newInstance();
             assertEquals(0, result.size());
             assertFalse(result.keySet().iterator().hasNext());
             return result;
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/java/util/concurrent/tck/TreeSetTest.java
    --- a/jdk/test/java/util/concurrent/tck/TreeSetTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/java/util/concurrent/tck/TreeSetTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -722,7 +722,8 @@
         }
     
         static NavigableSet newSet(Class cl) throws Exception {
    -        NavigableSet result = (NavigableSet) cl.newInstance();
    +        NavigableSet result =
    +            (NavigableSet) cl.getConstructor().newInstance();
             assertEquals(0, result.size());
             assertFalse(result.iterator().hasNext());
             return result;
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/jdk/internal/misc/Unsafe/TestBadHostClass.java
    --- a/jdk/test/jdk/internal/misc/Unsafe/TestBadHostClass.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/jdk/internal/misc/Unsafe/TestBadHostClass.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -25,7 +25,6 @@
      * @test
      * @bug 8058575
      * @summary Test that bad host classes cause exceptions to get thrown.
    - * @library /test/lib
      * @modules java.base/jdk.internal.misc
      *          java.base/jdk.internal.org.objectweb.asm
      * @run main TestBadHostClass
    @@ -35,7 +34,6 @@
     import java.lang.*;
     import java.lang.reflect.Field;
     import jdk.internal.misc.Unsafe;
    -import jdk.test.lib.unsafe.UnsafeHelper;
     import jdk.internal.org.objectweb.asm.ClassWriter;
     import static jdk.internal.org.objectweb.asm.Opcodes.*;
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/jprt.config
    --- a/jdk/test/jprt.config	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/jprt.config	Wed Jul 05 22:16:00 2017 +0200
    @@ -82,15 +82,12 @@
         fi
     
         # Add basic solaris system paths
    -    path4sdk=/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin
    +    path4sdk=/usr/bin:/usr/gnu/bin
     
         # Find GNU make
    -    make=/usr/sfw/bin/gmake
    +    make=/usr/bin/gmake
         if [ ! -f ${make} ] ; then
    -	make=/opt/sfw/bin/gmake
    -	if [ ! -f ${make} ] ; then
    -	    make=${slashjava}/devtools/${solaris_arch}/bin/gnumake
    -        fi 
    +	make=${slashjava}/devtools/${solaris_arch}/bin/gnumake
         fi
         fileMustExist "${make}" make
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/start-Xvfb.sh
    --- a/jdk/test/start-Xvfb.sh	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/start-Xvfb.sh	Wed Jul 05 22:16:00 2017 +0200
    @@ -59,9 +59,6 @@
       /usr/bin/nohup /usr/bin/X11/Xvfb -fbdir ${currentDir} -pixdepths 8 16 24 32 ${DISPLAY} > ${currentDir}/nohup.$$ 2>&1 &
     fi
     WM="/usr/bin/X11/fvwm2"
    -if [ ! -x ${WM} ] ; then
    -  WM="/opt/sfw/bin/fvwm2"
    -fi
     #
     # Wait for Xvfb to initialize:
     sleep 5
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/nio/cs/TestUnmappable.java
    --- a/jdk/test/sun/nio/cs/TestUnmappable.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/nio/cs/TestUnmappable.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -28,11 +28,11 @@
      * @bug 8008386
      * @summary (cs) Unmappable leading should be decoded to replacement.
      *          Tests for Shift_JIS and MS932 decoding
    + * @modules jdk.charsets
      * @run main TestUnmappable
      */
     
    -import java.nio.*;
    -import java.nio.charset.*;
    +import java.nio.charset.Charset;
     
     public class TestUnmappable {
         public static void main(String args[]) throws Exception {
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java
    --- a/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -23,7 +23,7 @@
     
     /*
      * @test
    - * @bug 6316539
    + * @bug 6316539 8136355
      * @summary Known-answer-test for TlsKeyMaterial generator
      * @author Andreas Sterbenz
      * @library ..
    @@ -37,6 +37,7 @@
     import java.nio.file.Files;
     import java.nio.file.Paths;
     import java.security.Provider;
    +import java.security.InvalidAlgorithmParameterException;
     import java.util.Arrays;
     import javax.crypto.KeyGenerator;
     import javax.crypto.SecretKey;
    @@ -139,21 +140,28 @@
                             keyLength, expandedKeyLength, ivLength, macLength,
                             null, -1, -1);
     
    -                    kg.init(spec);
    -                    TlsKeyMaterialSpec result =
    -                        (TlsKeyMaterialSpec)kg.generateKey();
    -                    match(lineNumber, clientCipherBytes,
    -                        result.getClientCipherKey(), cipherAlgorithm);
    -                    match(lineNumber, serverCipherBytes,
    -                        result.getServerCipherKey(), cipherAlgorithm);
    -                    match(lineNumber, clientIv, result.getClientIv(), "");
    -                    match(lineNumber, serverIv, result.getServerIv(), "");
    -                    match(lineNumber, clientMacBytes, result.getClientMacKey(), "");
    -                    match(lineNumber, serverMacBytes, result.getServerMacKey(), "");
    -
    -                } else {
    +                    try {
    +                        kg.init(spec);
    +                        TlsKeyMaterialSpec result =
    +                            (TlsKeyMaterialSpec)kg.generateKey();
    +                        match(lineNumber, clientCipherBytes,
    +                            result.getClientCipherKey(), cipherAlgorithm);
    +                        match(lineNumber, serverCipherBytes,
    +                            result.getServerCipherKey(), cipherAlgorithm);
    +                        match(lineNumber, clientIv, result.getClientIv(), "");
    +                        match(lineNumber, serverIv, result.getServerIv(), "");
    +                        match(lineNumber, clientMacBytes, result.getClientMacKey(), "");
    +                        match(lineNumber, serverMacBytes, result.getServerMacKey(), "");
    +                    } catch (InvalidAlgorithmParameterException iape) {
    +                        // SSLv3 support is removed in S12
    +                        if (major == 3 && minor == 0) {
    +                            System.out.println("Skip testing SSLv3");
    +                            continue;
    +                        }
    +                    }
    +               } else {
                         throw new Exception("Unknown line: " + line);
    -                }
    +               }
                 }
                 if (n == 0) {
                     throw new Exception("no tests");
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java
    --- a/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -23,7 +23,7 @@
     
     /*
      * @test
    - * @bug 6316539
    + * @bug 6316539 8136355
      * @summary Known-answer-test for TlsMasterSecret generator
      * @author Andreas Sterbenz
      * @library ..
    @@ -38,6 +38,7 @@
     import java.nio.file.Files;
     import java.nio.file.Paths;
     import java.security.Provider;
    +import java.security.InvalidAlgorithmParameterException;
     import java.util.Arrays;
     import javax.crypto.KeyGenerator;
     import javax.crypto.SecretKey;
    @@ -116,15 +117,24 @@
                             new TlsMasterSecretParameterSpec(premasterKey,
                                 protoMajor, protoMinor, clientRandom, serverRandom,
                                 null, -1, -1);
    -                    kg.init(spec);
    -                    TlsMasterSecret key = (TlsMasterSecret)kg.generateKey();
    -                    byte[] enc = key.getEncoded();
    -                    if (Arrays.equals(master, enc) == false) {
    -                        throw new Exception("mismatch line: " + lineNumber);
    -                    }
    -                    if ((preMajor != key.getMajorVersion()) ||
    -                            (preMinor != key.getMinorVersion())) {
    -                        throw new Exception("version mismatch line: " + lineNumber);
    +
    +                    try {
    +                        kg.init(spec);
    +                        TlsMasterSecret key = (TlsMasterSecret)kg.generateKey();
    +                        byte[] enc = key.getEncoded();
    +                        if (Arrays.equals(master, enc) == false) {
    +                            throw new Exception("mismatch line: " + lineNumber);
    +                        }
    +                        if ((preMajor != key.getMajorVersion()) ||
    +                                (preMinor != key.getMinorVersion())) {
    +                           throw new Exception("version mismatch line: " + lineNumber);
    +                        }
    +                    } catch (InvalidAlgorithmParameterException iape) {
    +                        // SSLv3 support is removed in S12
    +                        if (preMajor == 3 && preMinor == 0) {
    +                            System.out.println("Skip testing SSLv3");
    +                            continue;
    +                        }
                         }
                     } else {
                         throw new Exception("Unknown line: " + line);
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/pkcs11/tls/TestPremaster.java
    --- a/jdk/test/sun/security/pkcs11/tls/TestPremaster.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/pkcs11/tls/TestPremaster.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -23,7 +23,7 @@
     
     /*
      * @test
    - * @bug 6316539
    + * @bug 6316539 8136355
      * @summary Basic tests for TlsRsaPremasterSecret generator
      * @author Andreas Sterbenz
      * @library ..
    @@ -34,6 +34,7 @@
      */
     
     import java.security.Provider;
    +import java.security.InvalidAlgorithmParameterException;
     import javax.crypto.KeyGenerator;
     import javax.crypto.SecretKey;
     import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
    @@ -61,7 +62,7 @@
                 System.out.println("OK: " + e);
             }
     
    -        int[] protocolVersions = {0x0300, 0x0301, 0x0302, 0x0400};
    +        int[] protocolVersions = {0x0300, 0x0301, 0x0302};
             for (int clientVersion : protocolVersions) {
                 for (int serverVersion : protocolVersions) {
                     test(kg, clientVersion, serverVersion);
    @@ -81,8 +82,18 @@
                     "Testing RSA pre-master secret key generation between " +
                     "client (0x%04X) and server(0x%04X)%n",
                     clientVersion, serverVersion);
    -        kg.init(new TlsRsaPremasterSecretParameterSpec(
    +        try {
    +            kg.init(new TlsRsaPremasterSecretParameterSpec(
                                         clientVersion, serverVersion));
    +        } catch (InvalidAlgorithmParameterException iape) {
    +            // S12 removed support for SSL v3.0
    +            if (clientVersion == 0x300 || serverVersion == 0x300) {
    +                System.out.println("Skip testing SSLv3 due to no support");
    +                return;
    +            }
    +            // unexpected, pass it up
    +            throw iape;
    +        }
             SecretKey key = kg.generateKey();
             byte[] encoded = key.getEncoded();
             if (encoded != null) {  // raw key material may be not extractable
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/README.txt
    --- a/jdk/test/sun/security/smartcardio/README.txt	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/smartcardio/README.txt	Wed Jul 05 22:16:00 2017 +0200
    @@ -1,17 +1,17 @@
     
     Rough hints for setting up MUSCLE on Solaris:
     
    -Make sure you have libusb, usually in /usr/sfw:
    +Make sure you have libusb, usually in /usr/lib:
     
    -ls -l /usr/sfw/lib/libusb.so
    -lrwxrwxrwx   1 root     other         11 Jan 12 16:02 /usr/sfw/lib/libusb.so -> libusb.so.1
    +ls -l /usr/lib/libusb.so
    +lrwxrwxrwx   1 root     other         11 Jan 12 16:02 /usr/lib/libusb.so -> libusb.so.1
     
     Get PCSC and CCID.
     -rwx------   1 user staff     529540 Jun 16 18:24 ccid-1.0.1.tar.gz
     -rwx------   1 user staff     842654 Jun 16 18:24 pcsc-lite-1.3.1.tar.gz
     
     Unpack pcsc
    -Run ./configure --enable-libusb=/usr/sfw (??)
    +Run ./configure --enable-libusb (??)
     gnumake
     Make /usr/local writeable for user
     gnumake install
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestChannel.java
    --- a/jdk/test/sun/security/smartcardio/TestChannel.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/smartcardio/TestChannel.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -21,11 +21,12 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 6239117
      * @summary test logical channels work
      * @author Andreas Sterbenz
    + * @modules java.smartcardio/javax.smartcardio
      * @run main/manual TestChannel
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestConnect.java
    --- a/jdk/test/sun/security/smartcardio/TestConnect.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/smartcardio/TestConnect.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -21,11 +21,12 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 6293769 6294527 6309280
      * @summary test connect() works
      * @author Andreas Sterbenz
    + * @modules java.smartcardio/javax.smartcardio
      * @run main/manual TestConnect
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestConnectAgain.java
    --- a/jdk/test/sun/security/smartcardio/TestConnectAgain.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/smartcardio/TestConnectAgain.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -21,11 +21,12 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 6239117
      * @summary test connect works correctly if called multiple times/card removed
      * @author Andreas Sterbenz
    + * @modules java.smartcardio/javax.smartcardio
      * @run main/manual TestConnectAgain
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestControl.java
    --- a/jdk/test/sun/security/smartcardio/TestControl.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/smartcardio/TestControl.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -21,11 +21,12 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 6239117 6470320
      * @summary test if transmitControlCommand() works
      * @author Andreas Sterbenz
    + * @modules java.smartcardio/javax.smartcardio
      * @run main/manual TestControl
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestDefault.java
    --- a/jdk/test/sun/security/smartcardio/TestDefault.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/smartcardio/TestDefault.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -21,11 +21,12 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 6327047
      * @summary verify that TerminalFactory.getDefault() works
      * @author Andreas Sterbenz
    + * @modules java.smartcardio/javax.smartcardio
      * @run main/manual TestDefault
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestDirect.java
    --- a/jdk/test/sun/security/smartcardio/TestDirect.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/smartcardio/TestDirect.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -21,10 +21,11 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 8046343
      * @summary Make sure that direct protocol is available
    + * @modules java.smartcardio/javax.smartcardio
      * @run main/manual TestDirect
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestExclusive.java
    --- a/jdk/test/sun/security/smartcardio/TestExclusive.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/smartcardio/TestExclusive.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -21,11 +21,12 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 6239117
      * @summary verify that beginExclusive()/endExclusive() works
      * @author Andreas Sterbenz
    + * @modules java.smartcardio/javax.smartcardio
      * @run main/manual TestExclusive
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestMultiplePresent.java
    --- a/jdk/test/sun/security/smartcardio/TestMultiplePresent.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/smartcardio/TestMultiplePresent.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -21,11 +21,12 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 6239117 6445367
      * @summary test that CardTerminals.waitForCard() works
      * @author Andreas Sterbenz
    + * @modules java.smartcardio/javax.smartcardio
      * @run main/manual TestMultiplePresent
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestPresent.java
    --- a/jdk/test/sun/security/smartcardio/TestPresent.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/smartcardio/TestPresent.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -21,11 +21,12 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 6293769 6294527
      * @summary test that the isCardPresent()/waitForX() APIs work correctly
      * @author Andreas Sterbenz
    + * @modules java.smartcardio/javax.smartcardio
      * @run main/manual TestPresent
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/smartcardio/TestTransmit.java
    --- a/jdk/test/sun/security/smartcardio/TestTransmit.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/smartcardio/TestTransmit.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -21,11 +21,12 @@
      * questions.
      */
     
    -/**
    +/*
      * @test
      * @bug 6293769 6294527
      * @summary test transmit() works
      * @author Andreas Sterbenz
    + * @modules java.smartcardio/javax.smartcardio
      * @run main/manual TestTransmit
      */
     
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/ssl/SocketCreation/SocketCreation.java
    --- a/jdk/test/sun/security/ssl/SocketCreation/SocketCreation.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/ssl/SocketCreation/SocketCreation.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -139,7 +139,7 @@
                 (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
     
             System.out.println("Server: Will call createServerSocket(int)");
    -        ServerSocket sslServerSocket = sslssf.createServerSocket(serverPort);
    +        ServerSocket sslServerSocket = sslssf.createServerSocket(0);
             serverPort = sslServerSocket.getLocalPort();
     
             System.out.println("Server: Will accept on SSL server socket...");
    @@ -157,7 +157,7 @@
                 (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
     
             System.out.println("Server: Will call createServerSocket(int, int)");
    -        ServerSocket sslServerSocket = sslssf.createServerSocket(serverPort,
    +        ServerSocket sslServerSocket = sslssf.createServerSocket(0,
                                                                      1);
             serverPort = sslServerSocket.getLocalPort();
     
    @@ -177,7 +177,7 @@
     
             System.out.println("Server: Will call createServerSocket(int, " +
                                " int, InetAddress)");
    -        ServerSocket sslServerSocket = sslssf.createServerSocket(serverPort,
    +        ServerSocket sslServerSocket = sslssf.createServerSocket(0,
                                              1,
                                              InetAddress.getByName("localhost"));
             serverPort = sslServerSocket.getLocalPort();
    @@ -203,14 +203,15 @@
             if (sslServerSocket.isBound())
                 throw new Exception("Server socket is already bound!");
     
    -        System.out.println("Server: Will bind SSL server socket to port " +
    -                           serverPort + "...");
    -
    -        sslServerSocket.bind(new java.net.InetSocketAddress(serverPort));
    +        sslServerSocket.bind(new java.net.InetSocketAddress(0));
     
             if (!sslServerSocket.isBound())
                 throw new Exception("Server socket is not bound!");
     
    +        serverPort = sslServerSocket.getLocalPort();
    +        System.out.println("Server: Bound SSL server socket to port " +
    +                serverPort + "...");
    +
             serverReady = true;
     
             System.out.println("Server: Will accept on SSL server socket...");
    @@ -224,11 +225,10 @@
             SSLSocketFactory sslsf =
                 (SSLSocketFactory) SSLSocketFactory.getDefault();
     
    -        System.out.println("Server: Will create normal server socket bound"
    -                           + " to port " + serverPort + "...");
    -
    -        ServerSocket ss = new ServerSocket(serverPort);
    +        ServerSocket ss = new ServerSocket(0);
             serverPort = ss.getLocalPort();
    +        System.out.println("Server: Created normal server socket bound"
    +                + " to port " + serverPort + "...");
             System.out.println("Server: Will accept on server socket...");
             serverReady = true;
             Socket s = ss.accept();
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/sun/security/tools/keytool/KeyToolTest.java
    --- a/jdk/test/sun/security/tools/keytool/KeyToolTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/sun/security/tools/keytool/KeyToolTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1761,7 +1761,7 @@
             //PKCS#11 tests
     
             //   1. sccs edit cert8.db key3.db
    -        //Runtime.getRuntime().exec("/usr/ccs/bin/sccs edit cert8.db key3.db");
    +        //Runtime.getRuntime().exec("/usr/bin/sccs edit cert8.db key3.db");
             testOK("", p11Arg + ("-storepass test12 -genkey -alias genkey" +
                     " -dname cn=genkey -keysize 512 -keyalg rsa"));
             testOK("", p11Arg + "-storepass test12 -list");
    @@ -1781,7 +1781,7 @@
             testOK("", p11Arg + "-storepass test12 -list");
             assertTrue(out.indexOf("Your keystore contains 0 entries") != -1);
             //(check for empty database listing)
    -        //Runtime.getRuntime().exec("/usr/ccs/bin/sccs unedit cert8.db key3.db");
    +        //Runtime.getRuntime().exec("/usr/bin/sccs unedit cert8.db key3.db");
             remove("genkey.cert");
             remove("genkey.certreq");
             //  12. sccs unedit cert8.db key3.db
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/tools/launcher/RunpathTest.java
    --- a/jdk/test/tools/launcher/RunpathTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/tools/launcher/RunpathTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -40,7 +40,7 @@
         }
     
         final String findElfReader() {
    -        String[] paths = {"/bin", "/sbin", "/usr/bin", "/usr/sbin", "/usr/ccs/bin"};
    +        String[] paths = {"/usr/sbin", "/usr/bin"};
             final String cmd = isSolaris ? "elfdump" : "readelf";
             for (String x : paths) {
                 File p = new File(x);
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/tools/launcher/TooSmallStackSize.java
    --- a/jdk/test/tools/launcher/TooSmallStackSize.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/tools/launcher/TooSmallStackSize.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -35,6 +35,11 @@
      * stack size for the platform (as provided by the JVM error message when a very
      * small stack is used), and then verify that the JVM can be launched with that stack
      * size without a crash or any error messages.
    + *
    + * Note: The '-Xss' and '-XX:ThreadStackSize=' options
    + * both control Java thread stack size. This repo's version of the test
    + * exercises the '-Xss' option. The hotspot repo's version of the test
    + * exercises the '-XX:ThreadStackSize' VM option.
      */
     
     public class TooSmallStackSize extends TestHelper {
    @@ -59,7 +64,7 @@
         static String getMinStackAllowed(TestResult tr) {
             /*
              * The JVM output will contain in one of the lines:
    -         *   "The stack size specified is too small, Specify at least 100k"
    +         *   "The Java thread stack size specified is too small. Specify at least 100k"
              * Although the actual size will vary. We need to extract this size
              * string from the output and return it.
              */
    @@ -73,6 +78,9 @@
                 }
             }
     
    +        System.out.println("Expect='" + matchStr + "'");
    +        System.out.println("Actual:");
    +        printTestOutput(tr);
             System.out.println("FAILED: Could not get the stack size from the output");
             throw new RuntimeException("test fails");
         }
    @@ -96,11 +104,15 @@
                 System.out.println("PASSED: got no error message with stack size of " + stackSize);
                 min_stack_allowed = stackSize;
             } else {
    -            if (tr.contains("The stack size specified is too small")) {
    +            String matchStr = "The Java thread stack size specified is too small";
    +            if (tr.contains(matchStr)) {
                     System.out.println("PASSED: got expected error message with stack size of " + stackSize);
                     min_stack_allowed = getMinStackAllowed(tr);
                 } else {
                     // Likely a crash
    +                System.out.println("Expect='" + matchStr + "'");
    +                System.out.println("Actual:");
    +                printTestOutput(tr);
                     System.out.println("FAILED: Did not get expected error message with stack size of " + stackSize);
                     throw new RuntimeException("test fails");
                 }
    @@ -123,6 +135,8 @@
                 System.out.println("PASSED: VM launched with minimum allowed stack size of " + stackSize);
             } else {
                 // Likely a crash
    +            System.out.println("Test output:");
    +            printTestOutput(tr);
                 System.out.println("FAILED: VM failed to launch with minimum allowed stack size of " + stackSize);
                 throw new RuntimeException("test fails");
             }
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/tools/launcher/modules/addmods/AddModsTest.java
    --- a/jdk/test/tools/launcher/modules/addmods/AddModsTest.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/tools/launcher/modules/addmods/AddModsTest.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -31,6 +31,7 @@
      * @summary Basic test for java --add-modules
      */
     
    +import java.io.File;
     import java.nio.file.Path;
     import java.nio.file.Paths;
     
    @@ -224,6 +225,27 @@
     
     
         /**
    +     * Tests {@code --add-modules} be specified more than once.
    +     */
    +    public void testWithMultipleAddModules() throws Exception {
    +
    +        String modulepath = MODS1_DIR.toString() + File.pathSeparator +
    +                                MODS2_DIR.toString();
    +        int exitValue
    +            = executeTestJava("--module-path", modulepath,
    +            "--add-modules", LOGGER_MODULE,
    +            "--add-modules", TEST_MODULE,
    +            "-m", TEST_MID,
    +            "logger.Logger")
    +            .outputTo(System.out)
    +            .errorTo(System.out)
    +            .getExitValue();
    +
    +        assertTrue(exitValue == 0);
    +    }
    +
    +
    +    /**
          * Attempt to run with a bad module name specified to --add-modules
          */
         public void testRunWithBadAddMods() throws Exception {
    diff -r 8ced0dd94a6e -r 552748e3d506 jdk/test/tools/pack200/Pack200Test.java
    --- a/jdk/test/tools/pack200/Pack200Test.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/jdk/test/tools/pack200/Pack200Test.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -24,6 +24,7 @@
      /*
       * @test
       * @bug 6521334 6712743 8007902 8151901
    +  * @requires (sun.arch.data.model == "64" & os.maxMemory >= 4g)
       * @summary test general packer/unpacker functionality
       *          using native and java unpackers
       * @compile -XDignore.symbol.file Utils.java Pack200Test.java
    diff -r 8ced0dd94a6e -r 552748e3d506 make/MainSupport.gmk
    --- a/make/MainSupport.gmk	Thu Sep 22 16:41:14 2016 +0000
    +++ b/make/MainSupport.gmk	Wed Jul 05 22:16:00 2017 +0200
    @@ -31,11 +31,13 @@
     _MAINSUPPORT_GMK := 1
     
     # Run the tests specified by $1, with PRODUCT_HOME specified by $2
    +# JT_JAVA is picked up by the jtreg launcher and used to run Jtreg itself.
     define RunTests
     	($(CD) $(SRC_ROOT)/test && $(MAKE) $(MAKE_ARGS) -j1 -k MAKEFLAGS= \
     	    JT_HOME=$(JT_HOME) PRODUCT_HOME=$(strip $2) \
     	    TEST_IMAGE_DIR=$(TEST_IMAGE_DIR) \
     	    ALT_OUTPUTDIR=$(OUTPUT_ROOT) TEST_JOBS=$(TEST_JOBS) \
    +	    JT_JAVA=$(BOOT_JDK) \
     	    JOBS=$(JOBS) $1) || true
     endef
     
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/.hgtags
    --- a/nashorn/.hgtags	Thu Sep 22 16:41:14 2016 +0000
    +++ b/nashorn/.hgtags	Wed Jul 05 22:16:00 2017 +0200
    @@ -370,3 +370,4 @@
     e05400ba935753c77697af936db24657eb811022 jdk-9+134
     cb00d5ef023a18a66fcb4311ed4474d4145c66e9 jdk-9+135
     f11b8f5c4ccbf9c87d283815abac6c0117fba3c0 jdk-9+136
    +17ed43add2f9e3528686cd786ae2ed49c8ed36e9 jdk-9+137
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java
    --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -2512,7 +2512,8 @@
             final List elements = objectNode.getElements();
     
             final List> tuples = new ArrayList<>();
    -        final List gettersSetters = new ArrayList<>();
    +        // List below will contain getter/setter properties and properties with computed keys (ES6)
    +        final List specialProperties = new ArrayList<>();
             final int ccp = getCurrentContinuationEntryPoint();
             final List ranges = objectNode.getSplitRanges();
     
    @@ -2522,11 +2523,14 @@
             for (final PropertyNode propertyNode : elements) {
                 final Expression value = propertyNode.getValue();
                 final String key = propertyNode.getKeyName();
    +            final boolean isComputedOrAccessor = propertyNode.isComputed() || value == null;
    +
                 // Just use a pseudo-symbol. We just need something non null; use the name and zero flags.
    -            final Symbol symbol = value == null ? null : new Symbol(key, 0);
    -
    -            if (value == null) {
    -                gettersSetters.add(propertyNode);
    +            final Symbol symbol = isComputedOrAccessor ? null : new Symbol(key, 0);
    +
    +            if (isComputedOrAccessor) {
    +                // Properties with computed names or getter/setters need special handling.
    +                specialProperties.add(propertyNode);
                 } else if (propertyNode.getKey() instanceof IdentNode &&
                            key.equals(ScriptObject.PROTO_PROPERTY_NAME)) {
                     // ES6 draft compliant __proto__ inside object literal
    @@ -2542,7 +2546,7 @@
     
                 //for literals, a value of null means object type, i.e. the value null or getter setter function
                 //(I think)
    -            final Class valueType = (!useDualFields() || value == null || value.getType().isBoolean()) ? Object.class : value.getType().getTypeClass();
    +            final Class valueType = (!useDualFields() || isComputedOrAccessor || value.getType().isBoolean()) ? Object.class : value.getType().getTypeClass();
                 tuples.add(new MapTuple(key, symbol, Type.typeFor(valueType), value) {
                     @Override
                     public Class getValueType() {
    @@ -2590,26 +2594,41 @@
                 method.invoke(ScriptObject.SET_GLOBAL_OBJECT_PROTO);
             }
     
    -        for (final PropertyNode propertyNode : gettersSetters) {
    -            final FunctionNode getter = propertyNode.getGetter();
    -            final FunctionNode setter = propertyNode.getSetter();
    -
    -            assert getter != null || setter != null;
    -
    -            method.dup().loadKey(propertyNode.getKey());
    -            if (getter == null) {
    -                method.loadNull();
    +        for (final PropertyNode propertyNode : specialProperties) {
    +
    +            method.dup();
    +
    +            if (propertyNode.isComputed()) {
    +                assert propertyNode.getKeyName() == null;
    +                loadExpressionAsObject(propertyNode.getKey());
    +            } else {
    +                method.loadKey(propertyNode.getKey());
    +            }
    +
    +            if (propertyNode.getValue() != null) {
    +                loadExpressionAsObject(propertyNode.getValue());
    +                method.load(0);
    +                method.invoke(ScriptObject.GENERIC_SET);
                 } else {
    -                getter.accept(this);
    -            }
    -
    -            if (setter == null) {
    -                method.loadNull();
    -            } else {
    -                setter.accept(this);
    -            }
    -
    -            method.invoke(ScriptObject.SET_USER_ACCESSORS);
    +                final FunctionNode getter = propertyNode.getGetter();
    +                final FunctionNode setter = propertyNode.getSetter();
    +
    +                assert getter != null || setter != null;
    +
    +                if (getter == null) {
    +                    method.loadNull();
    +                } else {
    +                    getter.accept(this);
    +                }
    +
    +                if (setter == null) {
    +                    method.loadNull();
    +                } else {
    +                    setter.accept(this);
    +                }
    +
    +                method.invoke(ScriptObject.SET_USER_ACCESSORS);
    +            }
             }
         }
     
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/PropertyNode.java
    --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/PropertyNode.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/PropertyNode.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -86,11 +86,11 @@
         }
     
         /**
    -     * Get the name of the property key
    -     * @return key name
    +     * Get the name of the property key, or {@code null} if key is a computed name.
    +     * @return key name or null
          */
         public String getKeyName() {
    -        return key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : null;
    +        return !computed && key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : null;
         }
     
         @Override
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java
    --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1176,10 +1176,9 @@
                         labelStatement();
                         return;
                     }
    -                final boolean allowPropertyFunction = (reparseFlags & ScriptFunctionData.IS_PROPERTY_ACCESSOR) != 0;
    -                final boolean isES6Method = (reparseFlags & ScriptFunctionData.IS_ES6_METHOD) != 0;
    -                if(allowPropertyFunction) {
    -                    final String ident = (String)getValue();
    +
    +                if ((reparseFlags & ScriptFunctionData.IS_PROPERTY_ACCESSOR) != 0) {
    +                    final String ident = (String) getValue();
                         final long propertyToken = token;
                         final int propertyLine = line;
                         if (GET_NAME.equals(ident)) {
    @@ -1191,19 +1190,22 @@
                             addPropertyFunctionStatement(propertySetterFunction(propertyToken, propertyLine));
                             return;
                         }
    -                } else if (isES6Method) {
    -                    final String ident = (String)getValue();
    -                    IdentNode identNode = createIdentNode(token, finish, ident).setIsPropertyName();
    -                    final long propertyToken = token;
    -                    final int propertyLine = line;
    -                    next();
    -                    // Code below will need refinement once we fully support ES6 class syntax
    -                    final int flags = CONSTRUCTOR_NAME.equals(ident) ? FunctionNode.ES6_IS_CLASS_CONSTRUCTOR : FunctionNode.ES6_IS_METHOD;
    -                    addPropertyFunctionStatement(propertyMethodFunction(identNode, propertyToken, propertyLine, false, flags, false));
    -                    return;
                     }
                 }
     
    +            if ((reparseFlags & ScriptFunctionData.IS_ES6_METHOD) != 0
    +                    && (type == IDENT || type == LBRACKET || isNonStrictModeIdent())) {
    +                final String ident = (String)getValue();
    +                final long propertyToken = token;
    +                final int propertyLine = line;
    +                final Expression propertyKey = propertyName();
    +
    +                // Code below will need refinement once we fully support ES6 class syntax
    +                final int flags = CONSTRUCTOR_NAME.equals(ident) ? FunctionNode.ES6_IS_CLASS_CONSTRUCTOR : FunctionNode.ES6_IS_METHOD;
    +                addPropertyFunctionStatement(propertyMethodFunction(propertyKey, propertyToken, propertyLine, false, flags, false));
    +                return;
    +            }
    +
                 expressionStatement();
                 break;
             }
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java
    --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -186,7 +186,10 @@
     
         /** Method handle for setting the user accessors of a ScriptObject */
         //TODO fastpath this
    -    public static final Call SET_USER_ACCESSORS = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
    +    public static final Call SET_USER_ACCESSORS = virtualCallNoLookup(ScriptObject.class, "setUserAccessors", void.class, Object.class, ScriptFunction.class, ScriptFunction.class);
    +
    +    /** Method handle for generic property setter */
    +    public static final Call GENERIC_SET = virtualCallNoLookup(ScriptObject.class, "set", void.class, Object.class, Object.class, int.class);
     
         static final MethodHandle[] SET_SLOW = new MethodHandle[] {
             findOwnMH_V("set", void.class, Object.class, int.class, int.class),
    @@ -1063,12 +1066,13 @@
          * @param getter {@link UserAccessorProperty} defined getter, or null if none
          * @param setter {@link UserAccessorProperty} defined setter, or null if none
          */
    -    public final void setUserAccessors(final String key, final ScriptFunction getter, final ScriptFunction setter) {
    -        final Property oldProperty = getMap().findProperty(key);
    +    public final void setUserAccessors(final Object key, final ScriptFunction getter, final ScriptFunction setter) {
    +        final Object realKey = JSType.toPropertyKey(key);
    +        final Property oldProperty = getMap().findProperty(realKey);
             if (oldProperty instanceof UserAccessorProperty) {
                 modifyOwnProperty(oldProperty, oldProperty.getFlags(), getter, setter);
             } else {
    -            addOwnProperty(newUserAccessors(key, oldProperty != null ? oldProperty.getFlags() : 0, getter, setter));
    +            addOwnProperty(newUserAccessors(realKey, oldProperty != null ? oldProperty.getFlags() : 0, getter, setter));
             }
         }
     
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Functions.properties
    --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Functions.properties	Thu Sep 22 16:41:14 2016 +0000
    +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Functions.properties	Wed Jul 05 22:16:00 2017 +0200
    @@ -190,3 +190,105 @@
     
     Number.prototype.toPrecision=returns a string representing the number to a specified precision in fixed-point or exponential notation
     
    +Date.parse=returns a number, the UTC time value corresponding to the date and time interpreted from the given string argument, returns NAN if the argument is not recognized
    +
    +Date.UTC=returns the number of milliseconds in the given date object since January 1, 1970, 00:00:00 universal time
    +
    +Date.now=returns the number of milliseconds elapsed since January 1, 1970, 00:00:00 UTC
    +
    +Date.prototype.toString=returns the string value representing the given date object
    +
    +Date.prototype.toDateString=returns the string value representing the date portion of the given date object
    +
    +Date.prototype.toTimeString=returns the string value representing the time portion of the given date object
    +
    +Date.prototype.toLocaleString=returns the string value representing the date according to language specific conventions
    +
    +Date.prototype.toLocaleDateString=returns the string value representing the date portion of the given date object according to language specific conventions
    +
    +Date.prototype.toLocaleTimeString=returns the string value representing the time portion of the given date object according to language specific conventions
    +
    +Date.prototype.valueOf=returns the number of milliseconds between January 1, 1970, 00:00:00 UTC and the given date
    +
    +Date.prototype.getTime=returns the number representing milliseconds elapsed between January 1, 1970, 00:00:00 UTC and the given date
    +
    +Date.prototype.getFullYear=returns the year of the given date according to local time
    +
    +Date.prototype.getUTCFullYear=returns the year of the given date according to universal time
    +
    +Date.prototype.getMonth=returns the month between 0 to 11 of the given date according to local time
    +
    +Date.prototype.getUTCMonth=returns the month between 0 and 11 of the given date according to universal time
    +
    +Date.prototype.getDate=returns the day of the month for the given date according to local time
    +
    +Date.prototype.getUTCDate=returns the day of the month for the given date according to universal time
    +
    +Date.prototype.getDay=returns the day of the week for the given date according to local time, 0 represents Sunday
    +
    +Date.prototype.getUTCDay=returns the day of the week for the given date according to universal time, 0 represents Sunday
    +
    +Date.prototype.getHours=returns the hour in the given date, according to local time
    +
    +Date.prototype.getUTCHours=returns the hour in the given date, according to universal time
    +
    +Date.prototype.getMinutes=returns the minutes in the given date, according to local time
    +
    +Date.prototype.getUTCMinutes=returns the minutes in the given date, according to universal time
    +
    +Date.prototype.getSeconds=returns the seconds in the given date, according to local time
    +
    +Date.prototype.getUTCSeconds=returns the seconds in the given date, according to universal time
    +
    +Date.prototype.getMilliseconds=returns the milliseconds in the given date, according to local time
    +
    +Date.prototype.getUTCMilliseconds=returns the milliseconds in the given date, according to universal time
    +
    +Date.prototype.getTimezoneOffset=returns the difference between local time and UTC time in minutes
    +
    +Date.prototype.setTime=sets the date object to the time given, which is represented by the number of milliseconds since January 1, 1970, 00:00:00 UTC
    +
    +Date.prototype.setMilliseconds=sets the milliseconds for the given date according to local time
    +
    +Date.prototype.setUTCMilliseconds=sets the milliseconds for the given date according to universal time
    +
    +Date.prototype.setSeconds=sets the seconds for the given date according to local time
    +
    +Date.prototype.setUTCSeconds=sets the seconds for the given date according to universal time
    +
    +Date.prototype.setMinutes=sets the minutes for the given date according to local time
    +
    +Date.prototype.setUTCMinutes=sets the minutes for the given date according to universal time
    +
    +Date.prototype.setHours=sets the hours for the given date according to local time
    +
    +Date.prototype.setUTCHours=sets the hours for the given date according to universal time
    +
    +Date.prototype.setDate=sets the day of the month for the given date according to local time
    +
    +Date.prototype.setUTCDate=sets the day of the month for the given date according to universal time
    +
    +Date.prototype.setMonth=sets the month for the given date according to the currently set year
    +
    +Date.prototype.setUTCMonth=sets the month for the given date according to the universal time
    +
    +Date.prototype.setFullYear=sets the full year for the given date according to local time
    +
    +Date.prototype.toUTCString=converts the given date to a string using UTC time zone
    +
    +Date.prototype.toISOString=returns the string value in ISO 8601 format for the given date according to universal time
    +
    +Date.prototype.toJSON=returns the string representation of the given date
    +
    +RegExp.prototype.exec=returns an array object containing the results of match of given string against regular expression, null if no match found
    +
    +RegExp.prototype.test=returns true if match of given string against regular expression found, else returns false
    +
    +RegExp.prototype.toString=returns string representation of regular expression
    +
    +Error.prototype.toString=returns string representation of error object
    +
    +JSON.parse=returns an object by parsing given string as JSON
    +
    +JSON.stringify=returns a JSON string corresponding to the given ECMAScript value
    +
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property-duplicate.js
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/nashorn/test/script/basic/es6/computed-property-duplicate.js	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,44 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8164467: ES6 computed properties are implemented wrongly
    + *
    + * @test
    + * @run
    + * @option --language=es6
    + */
    +
    +var obj = {
    +    get ['a']() {
    +        throw new Error('should not be called');
    +    },
    +    get ['a']() {
    +        throw new Error('should not be called');
    +    },
    +    get ['a']() {
    +        return 'a';
    +    }
    +};
    +
    +Assert.assertEquals(obj.a, 'a');
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property-getter.js
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/nashorn/test/script/basic/es6/computed-property-getter.js	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,66 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8164467: ES6 computed properties are implemented wrongly
    + *
    + * @test
    + * @run
    + * @option --language=es6
    + */
    +
    +function f(x) {
    +    return x;
    +}
    +
    +var d = 'd';
    +var n = 3;
    +var s1 = Symbol();
    +var s2 = Symbol();
    +
    +var object = {
    +    get a() {  return 'a' },
    +    get ['b']() { return 'b' },
    +    get [f('c')]() { return 'c' },
    +    get [d]() { return d },
    +    get [1]() { return 1 },
    +    get [f(2)]() { return 2 },
    +    get [n]() { return 3 },
    +    get [s1]() { return s1 },
    +    get [f(s2)]() { return s2 }
    +};
    +
    +
    +Assert.assertEquals(object.a, 'a');
    +Assert.assertEquals(object.b, 'b');
    +Assert.assertEquals(object.c, 'c');
    +Assert.assertEquals(object.d, 'd');
    +Assert.assertEquals(object[1], 1);
    +Assert.assertEquals(object[2], 2);
    +Assert.assertEquals(object[3], 3);
    +Assert.assertEquals(object[s1], s1);
    +Assert.assertEquals(object[s2], s2);
    +
    +for (var s of ['a', 'b', 'c', 'd', 1, 2, 3, s1, s2]) {
    +    Assert.assertEquals(object[s], s);
    +}
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property-method.js
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/nashorn/test/script/basic/es6/computed-property-method.js	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,66 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8164467: ES6 computed properties are implemented wrongly
    + *
    + * @test
    + * @run
    + * @option --language=es6
    + */
    +
    +function f(x) {
    +    return x;
    +}
    +
    +var d = 'd';
    +var n = 3;
    +var s1 = Symbol();
    +var s2 = Symbol();
    +
    +var object = {
    +    a() {  return 'a' },
    +    ['b']() { return 'b' },
    +    [f('c')]() { return 'c' },
    +    [d]() { return d },
    +    [1]() { return 1 },
    +    [f(2)]() { return 2 },
    +    [n]() { return 3 },
    +    [s1]() { return s1 },
    +    [f(s2)]() { return s2 }
    +};
    +
    +
    +Assert.assertEquals(object.a(), 'a');
    +Assert.assertEquals(object.b(), 'b');
    +Assert.assertEquals(object.c(), 'c');
    +Assert.assertEquals(object.d(), 'd');
    +Assert.assertEquals(object[1](), 1);
    +Assert.assertEquals(object[2](), 2);
    +Assert.assertEquals(object[3](), 3);
    +Assert.assertEquals(object[s1](), s1);
    +Assert.assertEquals(object[s2](), s2);
    +
    +for (var s of ['a', 'b', 'c', 'd', 1, 2, 3, s1, s2]) {
    +    Assert.assertEquals(object[s](), s);
    +}
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property-number.js
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/nashorn/test/script/basic/es6/computed-property-number.js	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,54 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8164467: ES6 computed properties are implemented wrongly
    + *
    + * @test
    + * @run
    + * @option --language=es6
    + */
    +
    +function f(x) {
    +    return x;
    +}
    +
    +var object = {
    +    [1.5]: 'a',
    +    get [f(1e+40)]() { return 'b' },
    +    [0.0001]: 'c',
    +    [-0]: 'd',
    +    [Infinity]: 'e',
    +    [-Infinity]: 'f',
    +    [NaN]: 'g'
    +
    +};
    +
    +
    +Assert.assertEquals(object['1.5'], 'a');
    +Assert.assertEquals(object['1e+40'], 'b');
    +Assert.assertEquals(object['0.0001'], 'c');
    +Assert.assertEquals(object[0], 'd');
    +Assert.assertEquals(object[Infinity], 'e');
    +Assert.assertEquals(object[-Infinity], 'f');
    +Assert.assertEquals(object[NaN], 'g');
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property-setter.js
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/nashorn/test/script/basic/es6/computed-property-setter.js	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,43 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8164467: ES6 computed properties are implemented wrongly
    + *
    + * @test
    + * @run
    + * @option --language=es6
    + */
    +
    +var counter = 0;
    +
    +var obj = {
    +    set ['a'](x) {
    +        counter++;
    +    }
    +};
    +
    +obj.a = 'a';
    +Assert.assertTrue(counter === 1);
    +obj.a = 'a';
    +Assert.assertTrue(counter === 2);
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/basic/es6/computed-property.js
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/nashorn/test/script/basic/es6/computed-property.js	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,66 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8164467: ES6 computed properties are implemented wrongly
    + *
    + * @test
    + * @run
    + * @option --language=es6
    + */
    +
    +function f(x) {
    +    return x;
    +}
    +
    +var d = 'd';
    +var n = 3;
    +var s1 = Symbol();
    +var s2 = Symbol();
    +
    +var object = {
    +    a: 'a',
    +    ['b']: 'b',
    +    [f('c')]: 'c',
    +    [d]: d,
    +    [1]: 1,
    +    [f(2)]: 2,
    +    [n]: 3,
    +    [s1]: s1,
    +    [f(s2)]: s2
    +};
    +
    +
    +Assert.assertEquals(object.a, 'a');
    +Assert.assertEquals(object.b, 'b');
    +Assert.assertEquals(object.c, 'c');
    +Assert.assertEquals(object.d, 'd');
    +Assert.assertEquals(object[1], 1);
    +Assert.assertEquals(object[2], 2);
    +Assert.assertEquals(object[3], 3);
    +Assert.assertEquals(object[s1], s1);
    +Assert.assertEquals(object[s2], s2);
    +
    +for (var s of ['a', 'b', 'c', 'd', 1, 2, 3, s1, s2]) {
    +    Assert.assertEquals(object[s], s);
    +}
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/trusted/JDK-8006529.js
    --- a/nashorn/test/script/trusted/JDK-8006529.js	Thu Sep 22 16:41:14 2016 +0000
    +++ b/nashorn/test/script/trusted/JDK-8006529.js	Wed Jul 05 22:16:00 2017 +0200
    @@ -38,7 +38,7 @@
      * We cannot use direct Java class (via dynalink bean linker) to Compiler
      * and FunctionNode because of package-access check and so reflective calls.
      */
    -
    +var Reflector           = Java.type("jdk.nashorn.test.models.Reflector");
     var forName             = java.lang.Class["forName(String)"];
     var Parser              = forName("jdk.nashorn.internal.parser.Parser").static
     var Compiler            = forName("jdk.nashorn.internal.codegen.Compiler").static
    @@ -69,7 +69,11 @@
     var lhsMethod = BinaryNode.class.getMethod("lhs")
     var binaryRhsMethod = BinaryNode.class.getMethod("rhs")
     var debugIdMethod = Debug.class.getMethod("id", java.lang.Object.class)
    -var compilePhases = CompilationPhases.class.getField("COMPILE_UPTO_BYTECODE").get(null);
    +var compilePhases = Reflector.get(CompilationPhases.class.getField("COMPILE_UPTO_BYTECODE"), null);
    +
    +function invoke(m, obj) {
    +    return Reflector.invoke(m, obj);
    +}
     
     // These are method names of methods in FunctionNode class
     var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'usesSelfSymbol', 'isSplit', 'hasEval', 'allVarsInScope', 'isStrict']
    @@ -86,7 +90,7 @@
     
     // returns functionNode.getBody().getStatements().get(0)
     function getFirstFunction(functionNode) {
    -    var f = findFunction(getBodyMethod.invoke(functionNode))
    +    var f = findFunction(invoke(getBodyMethod, functionNode))
         if (f == null) {
             throw new Error();
         }
    @@ -95,7 +99,7 @@
     
     function findFunction(node) {
         if(node instanceof Block) {
    -        var stmts = getStatementsMethod.invoke(node)
    +        var stmts = invoke(getStatementsMethod, node)
             for(var i = 0; i < stmts.size(); ++i) {
                 var retval = findFunction(stmts.get(i))
                 if(retval != null) {
    @@ -103,13 +107,13 @@
                 }
             }
         } else if(node instanceof VarNode) {
    -        return findFunction(getInitMethod.invoke(node))
    +        return findFunction(invoke(getInitMethod, node))
         } else if(node instanceof UnaryNode) {
    -        return findFunction(rhsMethod.invoke(node))
    +        return findFunction(invoke(rhsMethod, node))
         } else if(node instanceof BinaryNode) {
    -        return findFunction(lhsMethod.invoke(node)) || findFunction(binaryRhsMethod.invoke(node))
    +        return findFunction(invoke(lhsMethod, node)) || findFunction(invoke(binaryRhsMethod, node))
         } else if(node instanceof ExpressionStatement) {
    -        return findFunction(getExpressionMethod.invoke(node))
    +        return findFunction(invoke(getExpressionMethod, node))
         } else if(node instanceof FunctionNode) {
             return node
         }
    @@ -131,12 +135,12 @@
         var ctxt = getContextMethod.invoke(null);
         var env = getEnvMethod.invoke(ctxt);
     
    -    var parser   = ParserConstructor.newInstance(env, source, ThrowErrorManager.class.newInstance());
    -    var func     = parseMethod.invoke(parser);
    +    var parser   = Reflector.newInstance(ParserConstructor, env, source, ThrowErrorManager.class.newInstance());
    +    var func     = invoke(parseMethod, parser);
     
    -    var compiler = CompilerConstructor.invoke(null, ctxt, source, false);
    +    var compiler = Reflector.invoke(CompilerConstructor, null, ctxt, source, false);
     
    -    return compileMethod.invoke(compiler, func, phases);
    +    return Reflector.invoke(compileMethod, compiler, func, phases);
     };
     
     var allAssertions = (function() {
    @@ -161,9 +165,10 @@
         }
         for(var assertion in allAssertions) {
             var expectedValue = !!assertions[assertion]
    -        var actualValue = functionNodeMethods[assertion].invoke(f)
    +        var actualValue = invoke(functionNodeMethods[assertion], f)
             if(actualValue !== expectedValue) {
    -            throw "Expected " + assertion + " === " + expectedValue + ", got " + actualValue + " for " + f + ":" + debugIdMethod.invoke(null, f);
    +            throw "Expected " + assertion + " === " + expectedValue + ", got " + actualValue + " for " + f + ":" 
    +                + invoke(debugIdMethod, null, f);
             }
         }
     }
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/trusted/event_queue.js
    --- a/nashorn/test/script/trusted/event_queue.js	Thu Sep 22 16:41:14 2016 +0000
    +++ b/nashorn/test/script/trusted/event_queue.js	Wed Jul 05 22:16:00 2017 +0200
    @@ -36,6 +36,7 @@
     print(Debug);
     print();
     
    +var Reflector     = Java.type("jdk.nashorn.test.models.Reflector");
     var forName       = java.lang.Class["forName(String)"];
     var RuntimeEvent  = forName("jdk.nashorn.internal.runtime.events.RuntimeEvent").static;
     var getValue      = RuntimeEvent.class.getMethod("getValue");
    @@ -84,19 +85,19 @@
         var e = events[i];
         print("event #" + i);
         print("\tevent class=" + e.getClass());
    -    print("\tvalueClass in event=" + getValueClass.invoke(e));
    -    var v = getValue.invoke(e);
    +    print("\tvalueClass in event=" + Reflector.invoke(getValueClass, e));
    +    var v = Reflector.invoke(getValue, e);
         print("\tclass of value=" + v.getClass());
    -    print("\treturn type=" + getReturnType.invoke(v));
    +    print("\treturn type=" + Reflector.invoke(getReturnType, v));
         lastInLoop = events[i];
     }
     
     print();
     print("in loop last class = " + lastInLoop.getClass());
    -print("in loop last value class = " + getValueClass.invoke(lastInLoop));
    -var rexInLoop = getValue.invoke(lastInLoop);
    +print("in loop last value class = " + Reflector.invoke(getValueClass, lastInLoop));
    +var rexInLoop = Reflector.invoke(getValue, lastInLoop);
     print("in loop rex class = " + rexInLoop.getClass());
    -print("in loop rex return type = " + getReturnType.invoke(rexInLoop));
    +print("in loop rex return type = " + Reflector.invoke(getReturnType, rexInLoop));
     
     //try last runtime events
     var last = Debug.getLastRuntimeEvent();
    @@ -106,10 +107,10 @@
     print();
     
     print("last class = " + last.getClass());
    -print("last value class = " + getValueClass.invoke(last));
    -var rex = getValue.invoke(last);
    +print("last value class = " + Reflector.invoke(getValueClass, last));
    +var rex = Reflector.invoke(getValue, last);
     print("rex class = " + rex.getClass());
    -print("rex return type = " + getReturnType.invoke(rex));
    +print("rex return type = " + Reflector.invoke(getReturnType, rex));
     
     //try the capacity setter
     print();
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/script/trusted/optimistic_recompilation.js
    --- a/nashorn/test/script/trusted/optimistic_recompilation.js	Thu Sep 22 16:41:14 2016 +0000
    +++ b/nashorn/test/script/trusted/optimistic_recompilation.js	Wed Jul 05 22:16:00 2017 +0200
    @@ -32,6 +32,7 @@
      * @run
      */
     
    +var Reflector     = Java.type("jdk.nashorn.test.models.Reflector");
     var forName       = java.lang.Class["forName(String)"];
     var RuntimeEvent  = forName("jdk.nashorn.internal.runtime.events.RuntimeEvent").static;
     var getValue      = RuntimeEvent.class.getMethod("getValue");
    @@ -42,6 +43,10 @@
     var setReturnTypeAndValue = [];
     var expectedValues = [];
     
    +function invoke(m, obj) {
    +    return Reflector.invoke(m, obj);
    +}
    +
     function checkExpectedRecompilation(f, expectedValues, testCase) {
         Debug.clearRuntimeEvents();
         print(f());
    @@ -51,12 +56,12 @@
         if (events.length ==  expectedValues.length) {
             for (var i in events) {
                 var e = events[i];
    -            var returnValue = getReturnValue.invoke(e);
    +            var returnValue = invoke(getReturnValue, e);
                 if (typeof returnValue != 'undefined') {
    -            setReturnTypeAndValue[i] = [getReturnType.invoke(getValue.invoke(e)), returnValue];
    +                setReturnTypeAndValue[i] = [invoke(getReturnType, invoke(getValue, e)), returnValue];
                 } else {
                     returnValue = "undefined";
    -                setReturnTypeAndValue[i] = [getReturnType.invoke(getValue.invoke(e)), returnValue];
    +                setReturnTypeAndValue[i] = [invoke(getReturnType, invoke(getValue, e)), returnValue];
                 }
                 if (!setReturnTypeAndValue[i].toString().equals(expectedValues[i].toString())) {
                     fail("The return values are not as expected. Expected value: " + expectedValues[i] + " and got: " + setReturnTypeAndValue[i] + " in test case: " + f);
    diff -r 8ced0dd94a6e -r 552748e3d506 nashorn/test/src/jdk/nashorn/test/models/Reflector.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/nashorn/test/src/jdk/nashorn/test/models/Reflector.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,92 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +package jdk.nashorn.test.models;
    +
    +import java.lang.reflect.Constructor;
    +import java.lang.reflect.Field;
    +import java.lang.reflect.Method;
    +import java.lang.reflect.Module;
    +import jdk.nashorn.internal.runtime.Context;
    +
    +/**
    + * Few tests reflectively invoke or read fields of Nashorn classes
    + * and objects - but of packages that are not exported to any module!
    + * But, those packages are qualified exported to test [java] code
    + * such as this class. So, test scripts can invoke the methods of this
    + * class instead.
    + */
    +public final class Reflector {
    +    private Reflector() {}
    +    private static final Module NASHORN_MOD = Context.class.getModule();
    +
    +    public static Object invoke(Method m, Object self, Object...args) {
    +        if (m.getDeclaringClass().getModule() != NASHORN_MOD) {
    +            throw new RuntimeException(m + " is not from Nashorn module");
    +        }
    +
    +        try {
    +            return m.invoke(self, args);
    +        } catch (final Exception e) {
    +            if (e instanceof RuntimeException) {
    +                throw (RuntimeException)e;
    +            } else {
    +                throw new RuntimeException(e);
    +            }
    +        }
    +    }
    +
    +    public static Object newInstance(Constructor c, Object...args) {
    +        if (c.getDeclaringClass().getModule() != NASHORN_MOD) {
    +            throw new RuntimeException(c + " is not from Nashorn module");
    +        }
    +
    +        try {
    +            return c.newInstance(args);
    +        } catch (final Exception e) {
    +            if (e instanceof RuntimeException) {
    +                throw (RuntimeException)e;
    +            } else {
    +                throw new RuntimeException(e);
    +            }
    +        }
    +    }
    +
    +    public static Object get(Field f, Object self) {
    +        if (f.getDeclaringClass().getModule() != NASHORN_MOD) {
    +            throw new RuntimeException(f + " is not from Nashorn module");
    +        }
    +
    +        try {
    +            return f.get(self);
    +        } catch (final Exception e) {
    +            if (e instanceof RuntimeException) {
    +                throw (RuntimeException)e;
    +            } else {
    +                throw new RuntimeException(e);
    +            }
    +        }
    +    }
    +}
    diff -r 8ced0dd94a6e -r 552748e3d506 test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherDiagnosticInfoObserver.java
    --- a/test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherDiagnosticInfoObserver.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherDiagnosticInfoObserver.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -26,8 +26,7 @@
     import com.sun.javatest.Harness;
     import com.sun.javatest.Parameters;
     import com.sun.javatest.TestResult;
    -import com.sun.javatest.regtest.RegressionParameters;
    -import com.sun.javatest.regtest.OS;
    +import com.sun.javatest.InterviewParameters;
     import jdk.test.failurehandler.*;
     
     import java.io.File;
    @@ -119,7 +118,7 @@
         @Override
         public void startingTestRun(Parameters params) {
             // TODO find a better way to get JDKs
    -        RegressionParameters rp = (RegressionParameters) params;
    +        InterviewParameters rp = (InterviewParameters) params;
             Map map = new HashMap<>();
             rp.save(map);
             compileJdk = (String) map.get("regtest.compilejdk");
    diff -r 8ced0dd94a6e -r 552748e3d506 test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherProcessInfoTimeoutHandler.java
    --- a/test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherProcessInfoTimeoutHandler.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/GatherProcessInfoTimeoutHandler.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -23,7 +23,6 @@
     
     package jdk.test.failurehandler.jtreg;
     
    -import com.sun.javatest.regtest.OS;
     import com.sun.javatest.regtest.TimeoutHandler;
     import jdk.test.failurehandler.*;
     
    diff -r 8ced0dd94a6e -r 552748e3d506 test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/OS.java
    --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    +++ b/test/failure_handler/src/share/classes/jdk/test/failurehandler/jtreg/OS.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -0,0 +1,56 @@
    +/*
    + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code is distributed in the hope that it will be useful, but WITHOUT
    + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +package jdk.test.failurehandler.jtreg;
    +
    +// Stripped down version of jtreg internal class com.sun.javatest.regtest.config.OS
    +class OS {
    +    public final String family;
    +
    +    private static OS current;
    +
    +    public static OS current() {
    +        if (current == null) {
    +            String name = System.getProperty("os.name");
    +            current = new OS(name);
    +        }
    +        return current;
    +    }
    +
    +    private OS(String name) {
    +        if (name.startsWith("Linux")) {
    +            family = "linux";
    +        } else if (name.startsWith("Mac") || name.startsWith("Darwin")) {
    +            family = "mac";
    +        } else if (name.startsWith("SunOS") || name.startsWith("Solaris")) {
    +            family = "solaris";
    +        } else if (name.startsWith("Windows")) {
    +            family = "windows";
    +        } else {
    +            // use first word of name
    +            family = name.replaceFirst("^([^ ]+).*", "$1");
    +        }
    +    }
    +}
    +
    +
    diff -r 8ced0dd94a6e -r 552748e3d506 test/lib/jdk/test/lib/Platform.java
    --- a/test/lib/jdk/test/lib/Platform.java	Thu Sep 22 16:41:14 2016 +0000
    +++ b/test/lib/jdk/test/lib/Platform.java	Wed Jul 05 22:16:00 2017 +0200
    @@ -116,6 +116,14 @@
             return (jdkDebug.toLowerCase().contains("debug"));
         }
     
    +    public static boolean isSlowDebugBuild() {
    +        return (jdkDebug.toLowerCase().equals("slowdebug"));
    +    }
    +
    +    public static boolean isFastDebugBuild() {
    +        return (jdkDebug.toLowerCase().equals("fastdebug"));
    +    }
    +
         public static String getVMVersion() {
             return vmVersion;
         }
    diff -r 8ced0dd94a6e -r 552748e3d506 test/lib/jdk/test/lib/unsafe/UnsafeHelper.java
    --- a/test/lib/jdk/test/lib/unsafe/UnsafeHelper.java	Thu Sep 22 16:41:14 2016 +0000
    +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    @@ -1,52 +0,0 @@
    -/*
    - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code is distributed in the hope that it will be useful, but WITHOUT
    - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - */
    -
    -package jdk.test.lib.unsafe;
    -
    -import jdk.internal.misc.Unsafe;
    -import java.lang.reflect.Field;
    -
    -
    -/**
    - * Helper class for accessing the jdk.internal.misc.Unsafe functionality
    - */
    -public final class UnsafeHelper {
    -    private static Unsafe unsafe = null;
    -
    -    /**
    -     * @return Unsafe instance.
    -     */
    -    public static synchronized Unsafe getUnsafe() {
    -        if (unsafe == null) {
    -            try {
    -                Field f = Unsafe.class.getDeclaredField("theUnsafe");
    -                f.setAccessible(true);
    -                unsafe = (Unsafe) f.get(null);
    -            } catch (NoSuchFieldException | IllegalAccessException e) {
    -                throw new RuntimeException("Unable to get Unsafe instance.", e);
    -            }
    -        }
    -        return unsafe;
    -    }
    -}
    -